1 : /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "mozilla/Hal.h"
7 : #include "mozilla/HalWakeLock.h"
8 : #include "mozilla/ClearOnShutdown.h"
9 : #include "nsDataHashtable.h"
10 : #include "nsHashKeys.h"
11 :
12 : using namespace mozilla::hal;
13 :
14 : namespace mozilla {
15 : namespace hal {
16 :
17 : WakeLockState
18 0 : ComputeWakeLockState(int aNumLocks, int aNumHidden)
19 : {
20 0 : if (aNumLocks == 0) {
21 0 : return WAKE_LOCK_STATE_UNLOCKED;
22 0 : } else if (aNumLocks == aNumHidden) {
23 0 : return WAKE_LOCK_STATE_HIDDEN;
24 : } else {
25 0 : return WAKE_LOCK_STATE_VISIBLE;
26 : }
27 : }
28 :
29 : } // hal
30 : } // mozilla
31 :
32 : namespace mozilla {
33 : namespace hal_impl {
34 :
35 : namespace {
36 : struct LockCount {
37 : PRUint32 numLocks;
38 : PRUint32 numHidden;
39 : };
40 : }
41 :
42 : static int sActiveChildren = 0;
43 1464 : static nsAutoPtr<nsDataHashtable<nsStringHashKey, LockCount> > sLockTable;
44 : static bool sInitialized = false;
45 :
46 : static void
47 0 : Init()
48 : {
49 0 : sLockTable = new nsDataHashtable<nsStringHashKey, LockCount>();
50 0 : sLockTable->Init();
51 0 : ClearOnShutdown(&sLockTable);
52 0 : sInitialized = true;
53 0 : }
54 :
55 : void
56 0 : EnableWakeLockNotifications()
57 : {
58 0 : sActiveChildren++;
59 0 : }
60 :
61 : void
62 0 : DisableWakeLockNotifications()
63 : {
64 0 : sActiveChildren--;
65 0 : }
66 :
67 : void
68 0 : ModifyWakeLock(const nsAString &aTopic,
69 : hal::WakeLockControl aLockAdjust,
70 : hal::WakeLockControl aHiddenAdjust)
71 : {
72 0 : if (!sInitialized) {
73 0 : Init();
74 : }
75 :
76 : LockCount count;
77 0 : count.numLocks = 0;
78 0 : count.numHidden = 0;
79 0 : sLockTable->Get(aTopic, &count);
80 0 : MOZ_ASSERT(count.numLocks >= count.numHidden);
81 0 : MOZ_ASSERT(aLockAdjust >= 0 || count.numLocks > 0);
82 0 : MOZ_ASSERT(aHiddenAdjust >= 0 || count.numHidden > 0);
83 :
84 0 : WakeLockState oldState = ComputeWakeLockState(count.numLocks, count.numHidden);
85 :
86 0 : count.numLocks += aLockAdjust;
87 0 : count.numHidden += aHiddenAdjust;
88 0 : MOZ_ASSERT(count.numLocks >= count.numHidden);
89 :
90 0 : if (count.numLocks) {
91 0 : sLockTable->Put(aTopic, count);
92 : } else {
93 0 : sLockTable->Remove(aTopic);
94 : }
95 :
96 0 : WakeLockState newState = ComputeWakeLockState(count.numLocks, count.numHidden);
97 :
98 0 : if (sActiveChildren && oldState != newState) {
99 0 : WakeLockInformation info;
100 0 : info.numLocks() = count.numLocks;
101 0 : info.numHidden() = count.numHidden;
102 0 : info.topic() = aTopic;
103 0 : NotifyWakeLockChange(info);
104 : }
105 0 : }
106 :
107 : void
108 0 : GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
109 : {
110 0 : if (!sInitialized) {
111 0 : Init();
112 : }
113 :
114 : LockCount count;
115 0 : count.numLocks = 0;
116 0 : count.numHidden = 0;
117 0 : sLockTable->Get(aTopic, &count);
118 :
119 0 : aWakeLockInfo->numLocks() = count.numLocks;
120 0 : aWakeLockInfo->numHidden() = count.numHidden;
121 0 : aWakeLockInfo->topic() = aTopic;
122 0 : }
123 :
124 : } // hal_impl
125 4392 : } // mozilla
|