PowerManagerService.cpp (3946B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "PowerManagerService.h" 8 9 #include "WakeLock.h" 10 #include "mozilla/ClearOnShutdown.h" 11 #include "mozilla/Hal.h" 12 #include "mozilla/HalWakeLock.h" 13 #include "mozilla/ModuleUtils.h" 14 #include "mozilla/Preferences.h" 15 #include "mozilla/dom/ContentParent.h" 16 #include "nsIDOMWakeLockListener.h" 17 18 // For _exit(). 19 #ifdef XP_WIN 20 # include <process.h> 21 #else 22 # include <unistd.h> 23 #endif 24 25 namespace mozilla::dom::power { 26 27 using namespace hal; 28 29 NS_IMPL_ISUPPORTS(PowerManagerService, nsIPowerManagerService) 30 31 /* static */ 32 StaticRefPtr<PowerManagerService> PowerManagerService::sSingleton; 33 34 /* static */ 35 already_AddRefed<PowerManagerService> PowerManagerService::GetInstance() { 36 if (!sSingleton) { 37 sSingleton = new PowerManagerService(); 38 sSingleton->Init(); 39 ClearOnShutdown(&sSingleton); 40 } 41 42 RefPtr<PowerManagerService> service = sSingleton.get(); 43 return service.forget(); 44 } 45 46 void PowerManagerService::Init() { RegisterWakeLockObserver(this); } 47 48 PowerManagerService::~PowerManagerService() { 49 UnregisterWakeLockObserver(this); 50 } 51 52 void PowerManagerService::ComputeWakeLockState( 53 const WakeLockInformation& aWakeLockInfo, nsAString& aState) { 54 WakeLockState state = hal::ComputeWakeLockState(aWakeLockInfo.numLocks(), 55 aWakeLockInfo.numHidden()); 56 switch (state) { 57 case WAKE_LOCK_STATE_UNLOCKED: 58 aState.AssignLiteral("unlocked"); 59 break; 60 case WAKE_LOCK_STATE_HIDDEN: 61 aState.AssignLiteral("locked-background"); 62 break; 63 case WAKE_LOCK_STATE_VISIBLE: 64 aState.AssignLiteral("locked-foreground"); 65 break; 66 } 67 } 68 69 void PowerManagerService::Notify(const WakeLockInformation& aWakeLockInfo) { 70 nsAutoString state; 71 ComputeWakeLockState(aWakeLockInfo, state); 72 73 /** 74 * Copy the listeners list before we walk through the callbacks 75 * because the callbacks may install new listeners. We expect no 76 * more than one listener per window, so it shouldn't be too long. 77 */ 78 const CopyableAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners = 79 mWakeLockListeners; 80 81 for (uint32_t i = 0; i < listeners.Length(); ++i) { 82 listeners[i]->Callback(aWakeLockInfo.topic(), state); 83 } 84 } 85 86 NS_IMETHODIMP 87 PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener* aListener) { 88 if (mWakeLockListeners.Contains(aListener)) return NS_OK; 89 90 mWakeLockListeners.AppendElement(aListener); 91 return NS_OK; 92 } 93 94 NS_IMETHODIMP 95 PowerManagerService::RemoveWakeLockListener( 96 nsIDOMMozWakeLockListener* aListener) { 97 mWakeLockListeners.RemoveElement(aListener); 98 return NS_OK; 99 } 100 101 NS_IMETHODIMP 102 PowerManagerService::GetWakeLockState(const nsAString& aTopic, 103 nsAString& aState) { 104 WakeLockInformation info; 105 GetWakeLockInfo(aTopic, &info); 106 107 ComputeWakeLockState(info, aState); 108 109 return NS_OK; 110 } 111 112 already_AddRefed<WakeLock> PowerManagerService::NewWakeLock( 113 const nsAString& aTopic, nsPIDOMWindowInner* aWindow, 114 mozilla::ErrorResult& aRv) { 115 RefPtr<WakeLock> wakelock = new WakeLock(); 116 aRv = wakelock->Init(aTopic, aWindow); 117 if (aRv.Failed()) { 118 return nullptr; 119 } 120 121 return wakelock.forget(); 122 } 123 124 NS_IMETHODIMP 125 PowerManagerService::NewWakeLock(const nsAString& aTopic, 126 mozIDOMWindow* aWindow, 127 nsIWakeLock** aWakeLock) { 128 mozilla::ErrorResult rv; 129 RefPtr<WakeLock> wakelock = 130 NewWakeLock(aTopic, nsPIDOMWindowInner::From(aWindow), rv); 131 if (rv.Failed()) { 132 return rv.StealNSResult(); 133 } 134 135 wakelock.forget(aWakeLock); 136 return NS_OK; 137 } 138 139 } // namespace mozilla::dom::power