Bug 786331 - WebGL tests that use a video can loop indefinitely. r=bjacob
[gecko.git] / dom / power / PowerManagerService.cpp
blobcd40e72f5601945da79004909446126ff488f970
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"
15 #include "WakeLock.h"
17 // For _exit().
18 #ifdef XP_WIN
19 #include <process.h>
20 #else
21 #include <unistd.h>
22 #endif
24 namespace mozilla {
25 namespace dom {
26 namespace power {
28 using namespace hal;
30 NS_IMPL_ISUPPORTS1(PowerManagerService, nsIPowerManagerService)
32 /* static */ StaticRefPtr<PowerManagerService> PowerManagerService::sSingleton;
34 /* static */ already_AddRefed<PowerManagerService>
35 PowerManagerService::GetInstance()
37 if (!sSingleton) {
38 sSingleton = new PowerManagerService();
39 sSingleton->Init();
40 ClearOnShutdown(&sSingleton);
43 nsRefPtr<PowerManagerService> service = sSingleton.get();
44 return service.forget();
47 void
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);
64 void
65 PowerManagerService::ComputeWakeLockState(const WakeLockInformation& aWakeLockInfo,
66 nsAString &aState)
68 WakeLockState state = hal::ComputeWakeLockState(aWakeLockInfo.numLocks(),
69 aWakeLockInfo.numHidden());
70 switch (state) {
71 case WAKE_LOCK_STATE_UNLOCKED:
72 aState.AssignLiteral("unlocked");
73 break;
74 case WAKE_LOCK_STATE_HIDDEN:
75 aState.AssignLiteral("locked-background");
76 break;
77 case WAKE_LOCK_STATE_VISIBLE:
78 aState.AssignLiteral("locked-foreground");
79 break;
83 void
84 PowerManagerService::Notify(const WakeLockInformation& aWakeLockInfo)
86 nsAutoString state;
87 ComputeWakeLockState(aWakeLockInfo, state);
89 /**
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);
101 void
102 PowerManagerService::SyncProfile()
104 nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
105 if (obsServ) {
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());
113 NS_IMETHODIMP
114 PowerManagerService::Reboot()
116 StartForceQuitWatchdog(eHalShutdownMode_Reboot, mWatchdogTimeoutSecs);
117 // To synchronize any unsaved user data before rebooting.
118 SyncProfile();
119 hal::Reboot();
120 MOZ_NOT_REACHED();
121 return NS_OK;
124 NS_IMETHODIMP
125 PowerManagerService::PowerOff()
127 StartForceQuitWatchdog(eHalShutdownMode_PowerOff, mWatchdogTimeoutSecs);
128 // To synchronize any unsaved user data before powering off.
129 SyncProfile();
130 hal::PowerOff();
131 MOZ_NOT_REACHED();
132 return NS_OK;
135 NS_IMETHODIMP
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.
143 SyncProfile();
144 _exit(0);
145 MOZ_NOT_REACHED();
146 return NS_OK;
149 NS_IMETHODIMP
150 PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
152 if (mWakeLockListeners.Contains(aListener))
153 return NS_OK;
155 mWakeLockListeners.AppendElement(aListener);
156 return NS_OK;
159 NS_IMETHODIMP
160 PowerManagerService::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
162 mWakeLockListeners.RemoveElement(aListener);
163 return NS_OK;
166 NS_IMETHODIMP
167 PowerManagerService::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
169 WakeLockInformation info;
170 GetWakeLockInfo(aTopic, &info);
172 ComputeWakeLockState(info, aState);
174 return NS_OK;
177 NS_IMETHODIMP
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);
189 return NS_OK;
192 } // power
193 } // dom
194 } // mozilla