WakeLockSentinel.cpp (3323B)
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 "WakeLockSentinel.h" 8 9 #include "WakeLockJS.h" 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Hal.h" 12 #include "mozilla/TelemetryHistogramEnums.h" 13 #include "mozilla/dom/Document.h" 14 #include "mozilla/dom/Event.h" 15 #include "mozilla/dom/EventBinding.h" 16 #include "mozilla/dom/Promise.h" 17 #include "mozilla/dom/WakeLockSentinelBinding.h" 18 #include "mozilla/glean/DomPowerMetrics.h" 19 20 namespace mozilla::dom { 21 22 JSObject* WakeLockSentinel::WrapObject(JSContext* cx, 23 JS::Handle<JSObject*> aGivenProto) { 24 return WakeLockSentinel_Binding::Wrap(cx, this, aGivenProto); 25 } 26 27 bool WakeLockSentinel::Released() const { return mReleased; } 28 29 void WakeLockSentinel::NotifyLockReleased() { 30 MOZ_ASSERT(!mReleased); 31 mReleased = true; 32 33 glean::screenwakelock::held_duration.AccumulateRawDuration(TimeStamp::Now() - 34 mCreationTime); 35 36 hal::BatteryInformation batteryInfo; 37 hal::GetCurrentBatteryInformation(&batteryInfo); 38 if (!batteryInfo.charging()) { 39 uint32_t level = static_cast<uint32_t>(100 * batteryInfo.level()); 40 glean::screenwakelock::release_battery_level_discharging 41 .AccumulateSingleSample(level); 42 } 43 44 if (mHoldsActualLock) { 45 MOZ_ASSERT(mType == WakeLockType::Screen); 46 NS_DispatchToMainThread(NS_NewRunnableFunction("ReleaseWakeLock", []() { 47 hal::ModifyWakeLock(u"screen"_ns, hal::WAKE_LOCK_REMOVE_ONE, 48 hal::WAKE_LOCK_NO_CHANGE); 49 })); 50 mHoldsActualLock = false; 51 } 52 53 EventInit init; 54 init.mBubbles = false; 55 init.mCancelable = false; 56 RefPtr<Event> event = Event::Constructor(this, u"release"_ns, init); 57 DispatchTrustedEvent(event); 58 } 59 60 void WakeLockSentinel::AcquireActualLock() { 61 MOZ_ASSERT(mType == WakeLockType::Screen); 62 MOZ_ASSERT(!mHoldsActualLock); 63 mHoldsActualLock = true; 64 NS_DispatchToMainThread(NS_NewRunnableFunction("AcquireWakeLock", []() { 65 hal::ModifyWakeLock(u"screen"_ns, hal::WAKE_LOCK_ADD_ONE, 66 hal::WAKE_LOCK_NO_CHANGE); 67 })); 68 } 69 70 // https://w3c.github.io/screen-wake-lock/#the-release-method 71 already_AddRefed<Promise> WakeLockSentinel::ReleaseLock(ErrorResult& aRv) { 72 // ReleaseWakeLock will remove this from document.[[ActiveLocks]] 73 RefPtr<WakeLockSentinel> kungFuDeathGrip(this); 74 75 if (!mReleased) { 76 nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal(); 77 if (!global) { 78 aRv.Throw(NS_ERROR_NULL_POINTER); 79 return nullptr; 80 } 81 nsCOMPtr<nsPIDOMWindowInner> window = global->GetAsInnerWindow(); 82 if (!window) { 83 aRv.Throw(NS_ERROR_NULL_POINTER); 84 return nullptr; 85 } 86 nsCOMPtr<Document> doc = window->GetExtantDoc(); 87 if (!doc) { 88 aRv.Throw(NS_ERROR_NULL_POINTER); 89 return nullptr; 90 } 91 ReleaseWakeLock(doc, this, mType); 92 } 93 94 if (RefPtr<Promise> p = 95 Promise::CreateResolvedWithUndefined(GetOwnerGlobal(), aRv)) { 96 return p.forget(); 97 } 98 return nullptr; 99 } 100 101 } // namespace mozilla::dom