100 lines
3.2 KiB
C++
100 lines
3.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "mozilla/Assertions.h"
|
|
#include "mozilla/glean/DomPowerMetrics.h"
|
|
#include "mozilla/TelemetryHistogramEnums.h"
|
|
#include "mozilla/dom/Document.h"
|
|
#include "mozilla/dom/Event.h"
|
|
#include "mozilla/dom/EventBinding.h"
|
|
#include "mozilla/dom/Promise.h"
|
|
#include "mozilla/dom/WakeLockSentinelBinding.h"
|
|
#include "mozilla/Hal.h"
|
|
#include "WakeLockJS.h"
|
|
#include "WakeLockSentinel.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
JSObject* WakeLockSentinel::WrapObject(JSContext* cx,
|
|
JS::Handle<JSObject*> aGivenProto) {
|
|
return WakeLockSentinel_Binding::Wrap(cx, this, aGivenProto);
|
|
}
|
|
|
|
bool WakeLockSentinel::Released() const { return mReleased; }
|
|
|
|
void WakeLockSentinel::NotifyLockReleased() {
|
|
MOZ_ASSERT(!mReleased);
|
|
mReleased = true;
|
|
|
|
glean::screenwakelock::held_duration.AccumulateRawDuration(TimeStamp::Now() -
|
|
mCreationTime);
|
|
|
|
hal::BatteryInformation batteryInfo;
|
|
hal::GetCurrentBatteryInformation(&batteryInfo);
|
|
if (!batteryInfo.charging()) {
|
|
uint32_t level = static_cast<uint32_t>(100 * batteryInfo.level());
|
|
glean::screenwakelock::release_battery_level_discharging
|
|
.AccumulateSingleSample(level);
|
|
}
|
|
|
|
if (mHoldsActualLock) {
|
|
MOZ_ASSERT(mType == WakeLockType::Screen);
|
|
NS_DispatchToMainThread(NS_NewRunnableFunction("ReleaseWakeLock", []() {
|
|
hal::ModifyWakeLock(u"screen"_ns, hal::WAKE_LOCK_REMOVE_ONE,
|
|
hal::WAKE_LOCK_NO_CHANGE);
|
|
}));
|
|
mHoldsActualLock = false;
|
|
}
|
|
|
|
EventInit init;
|
|
init.mBubbles = false;
|
|
init.mCancelable = false;
|
|
RefPtr<Event> event = Event::Constructor(this, u"release"_ns, init);
|
|
DispatchTrustedEvent(event);
|
|
}
|
|
|
|
void WakeLockSentinel::AcquireActualLock() {
|
|
MOZ_ASSERT(mType == WakeLockType::Screen);
|
|
MOZ_ASSERT(!mHoldsActualLock);
|
|
mHoldsActualLock = true;
|
|
NS_DispatchToMainThread(NS_NewRunnableFunction("AcquireWakeLock", []() {
|
|
hal::ModifyWakeLock(u"screen"_ns, hal::WAKE_LOCK_ADD_ONE,
|
|
hal::WAKE_LOCK_NO_CHANGE);
|
|
}));
|
|
}
|
|
|
|
// https://w3c.github.io/screen-wake-lock/#the-release-method
|
|
already_AddRefed<Promise> WakeLockSentinel::ReleaseLock(ErrorResult& aRv) {
|
|
// ReleaseWakeLock will remove this from document.[[ActiveLocks]]
|
|
RefPtr<WakeLockSentinel> kungFuDeathGrip(this);
|
|
|
|
if (!mReleased) {
|
|
nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal();
|
|
if (!global) {
|
|
aRv.Throw(NS_ERROR_NULL_POINTER);
|
|
return nullptr;
|
|
}
|
|
nsCOMPtr<nsPIDOMWindowInner> window = global->GetAsInnerWindow();
|
|
if (!window) {
|
|
aRv.Throw(NS_ERROR_NULL_POINTER);
|
|
return nullptr;
|
|
}
|
|
nsCOMPtr<Document> doc = window->GetExtantDoc();
|
|
if (!doc) {
|
|
aRv.Throw(NS_ERROR_NULL_POINTER);
|
|
return nullptr;
|
|
}
|
|
ReleaseWakeLock(doc, this, mType);
|
|
}
|
|
|
|
if (RefPtr<Promise> p =
|
|
Promise::CreateResolvedWithUndefined(GetOwnerGlobal(), aRv)) {
|
|
return p.forget();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
} // namespace mozilla::dom
|