1 /* -*- Mode: C++; tab-width: 2; 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
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/Hal.h"
7 #include "mozilla/HalWakeLock.h"
8 #include "mozilla/ClearOnShutdown.h"
9 #include "mozilla/Preferences.h"
10 #include "mozilla/Services.h"
11 #include "nsIDOMWakeLockListener.h"
12 #include "nsIDOMWindow.h"
13 #include "nsIObserverService.h"
14 #include "PowerManagerService.h"
30 NS_IMPL_ISUPPORTS1(PowerManagerService
, nsIPowerManagerService
)
32 /* static */ StaticRefPtr
<PowerManagerService
> PowerManagerService::sSingleton
;
34 /* static */ already_AddRefed
<PowerManagerService
>
35 PowerManagerService::GetInstance()
38 sSingleton
= new PowerManagerService();
40 ClearOnShutdown(&sSingleton
);
43 nsRefPtr
<PowerManagerService
> service
= sSingleton
.get();
44 return service
.forget();
48 PowerManagerService::Init()
50 RegisterWakeLockObserver(this);
52 // NB: default to *enabling* the watchdog even when the pref is
53 // absent, in case the profile might be damaged and we need to
54 // restart to repair it.
55 mWatchdogTimeoutSecs
=
56 Preferences::GetInt("shutdown.watchdog.timeoutSecs", 5);
59 PowerManagerService::~PowerManagerService()
61 UnregisterWakeLockObserver(this);
65 PowerManagerService::ComputeWakeLockState(const WakeLockInformation
& aWakeLockInfo
,
68 WakeLockState state
= hal::ComputeWakeLockState(aWakeLockInfo
.numLocks(),
69 aWakeLockInfo
.numHidden());
71 case WAKE_LOCK_STATE_UNLOCKED
:
72 aState
.AssignLiteral("unlocked");
74 case WAKE_LOCK_STATE_HIDDEN
:
75 aState
.AssignLiteral("locked-background");
77 case WAKE_LOCK_STATE_VISIBLE
:
78 aState
.AssignLiteral("locked-foreground");
84 PowerManagerService::Notify(const WakeLockInformation
& aWakeLockInfo
)
87 ComputeWakeLockState(aWakeLockInfo
, state
);
90 * Copy the listeners list before we walk through the callbacks
91 * because the callbacks may install new listeners. We expect no
92 * more than one listener per window, so it shouldn't be too long.
94 nsAutoTArray
<nsCOMPtr
<nsIDOMMozWakeLockListener
>, 2> listeners(mWakeLockListeners
);
96 for (uint32_t i
= 0; i
< listeners
.Length(); ++i
) {
97 listeners
[i
]->Callback(aWakeLockInfo
.topic(), state
);
102 PowerManagerService::SyncProfile()
104 nsCOMPtr
<nsIObserverService
> obsServ
= services::GetObserverService();
106 NS_NAMED_LITERAL_STRING(context
, "shutdown-persist");
107 obsServ
->NotifyObservers(nullptr, "profile-change-net-teardown", context
.get());
108 obsServ
->NotifyObservers(nullptr, "profile-change-teardown", context
.get());
109 obsServ
->NotifyObservers(nullptr, "profile-before-change", context
.get());
114 PowerManagerService::Reboot()
116 StartForceQuitWatchdog(eHalShutdownMode_Reboot
, mWatchdogTimeoutSecs
);
117 // To synchronize any unsaved user data before rebooting.
125 PowerManagerService::PowerOff()
127 StartForceQuitWatchdog(eHalShutdownMode_PowerOff
, mWatchdogTimeoutSecs
);
128 // To synchronize any unsaved user data before powering off.
136 PowerManagerService::Restart()
138 // FIXME/bug 796826 this implementation is currently gonk-specific,
139 // because it relies on the Gonk to initialize the Gecko processes to
140 // restart B2G. It's better to do it here to have a real "restart".
141 StartForceQuitWatchdog(eHalShutdownMode_Restart
, mWatchdogTimeoutSecs
);
142 // To synchronize any unsaved user data before restarting.
150 PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener
*aListener
)
152 if (mWakeLockListeners
.Contains(aListener
))
155 mWakeLockListeners
.AppendElement(aListener
);
160 PowerManagerService::RemoveWakeLockListener(nsIDOMMozWakeLockListener
*aListener
)
162 mWakeLockListeners
.RemoveElement(aListener
);
167 PowerManagerService::GetWakeLockState(const nsAString
&aTopic
, nsAString
&aState
)
169 WakeLockInformation info
;
170 GetWakeLockInfo(aTopic
, &info
);
172 ComputeWakeLockState(info
, aState
);
178 PowerManagerService::NewWakeLock(const nsAString
&aTopic
,
179 nsIDOMWindow
*aWindow
,
180 nsIDOMMozWakeLock
**aWakeLock
)
182 nsRefPtr
<WakeLock
> wakelock
= new WakeLock();
183 nsresult rv
= wakelock
->Init(aTopic
, aWindow
);
184 NS_ENSURE_SUCCESS(rv
, rv
);
186 nsCOMPtr
<nsIDOMMozWakeLock
> wl(wakelock
);
187 wl
.forget(aWakeLock
);