forked from mirrors/gecko-dev
Backed out 7 changesets (bug 1589554) for causing non-unified bustages on WakeLockJS.cpp.
Backed out changeset a0db8be67659 (bug 1589554) Backed out changeset 76a3c248813f (bug 1589554) Backed out changeset f1500173aa53 (bug 1589554) Backed out changeset e02e11c3d977 (bug 1589554) Backed out changeset 202c4f5c642b (bug 1589554) Backed out changeset 82e03a404c2f (bug 1589554) Backed out changeset b55991835aec (bug 1589554)
This commit is contained in:
parent
5c95548994
commit
0917a1636c
54 changed files with 191 additions and 860 deletions
|
|
@ -233,8 +233,6 @@
|
|||
#include "mozilla/dom/URL.h"
|
||||
#include "mozilla/dom/UseCounterMetrics.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/WakeLockJS.h"
|
||||
#include "mozilla/dom/WakeLockSentinel.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
|
|
@ -2594,11 +2592,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(
|
||||
mPendingFrameStaticClones[i].mStaticCloneOf);
|
||||
}
|
||||
|
||||
for (auto& tableEntry : tmp->mActiveLocks) {
|
||||
ImplCycleCollectionTraverse(cb, *tableEntry.GetModifiableData(),
|
||||
"mActiveLocks entry", 0);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Document)
|
||||
|
|
@ -2744,8 +2737,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
|||
|
||||
tmp->mPendingFrameStaticClones.Clear();
|
||||
|
||||
tmp->mActiveLocks.Clear();
|
||||
|
||||
tmp->mInUnlinkOrDeletion = false;
|
||||
|
||||
tmp->UnregisterFromMemoryReportingForDataDocument();
|
||||
|
|
@ -18256,49 +18247,6 @@ already_AddRefed<Promise> Document::CompleteStorageAccessRequestFromSite(
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
nsTHashSet<RefPtr<WakeLockSentinel>>& Document::ActiveWakeLocks(
|
||||
WakeLockType aType) {
|
||||
return mActiveLocks.LookupOrInsert(aType);
|
||||
}
|
||||
|
||||
class UnlockAllWakeLockRunnable final : public Runnable {
|
||||
public:
|
||||
UnlockAllWakeLockRunnable(WakeLockType aType, Document* aDoc)
|
||||
: Runnable("UnlockAllWakeLocks"), mType(aType), mDoc(aDoc) {}
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD Run() override {
|
||||
// Move, as ReleaseWakeLock will try to remove from and possibly allow
|
||||
// scripts via onrelease to add to document.[[ActiveLocks]]["screen"]
|
||||
nsCOMPtr<Document> doc = mDoc;
|
||||
nsTHashSet<RefPtr<WakeLockSentinel>> locks =
|
||||
std::move(doc->ActiveWakeLocks(mType));
|
||||
for (const auto& lock : locks) {
|
||||
// ReleaseWakeLock runs script, which could release other locks
|
||||
if (!lock->Released()) {
|
||||
ReleaseWakeLock(doc, MOZ_KnownLive(lock), mType);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
~UnlockAllWakeLockRunnable() = default;
|
||||
|
||||
private:
|
||||
WakeLockType mType;
|
||||
nsCOMPtr<Document> mDoc;
|
||||
};
|
||||
|
||||
void Document::UnlockAllWakeLocks(WakeLockType aType) {
|
||||
// Perform unlock in a runnable to prevent UnlockAll being MOZ_CAN_RUN_SCRIPT
|
||||
RefPtr<UnlockAllWakeLockRunnable> runnable =
|
||||
MakeRefPtr<UnlockAllWakeLockRunnable>(aType, this);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
RefPtr<Document::AutomaticStorageAccessPermissionGrantPromise>
|
||||
Document::AutomaticStorageAccessPermissionCanBeGranted(bool hasUserActivation) {
|
||||
// requestStorageAccessForOrigin may not require user activation. If we don't
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#include "mozilla/dom/TreeOrderedArray.h"
|
||||
#include "mozilla/dom/ViewportMetaData.h"
|
||||
#include "mozilla/dom/LargestContentfulPaint.h"
|
||||
#include "mozilla/dom/WakeLockBinding.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
|
@ -277,7 +276,6 @@ class Touch;
|
|||
class TouchList;
|
||||
class TreeWalker;
|
||||
enum class ViewportFitType : uint8_t;
|
||||
class WakeLockSentinel;
|
||||
class WindowContext;
|
||||
class WindowGlobalChild;
|
||||
class WindowProxyHolder;
|
||||
|
|
@ -3538,10 +3536,6 @@ class Document : public nsINode,
|
|||
// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes
|
||||
void EvaluateMediaQueriesAndReportChanges(bool aRecurse);
|
||||
|
||||
nsTHashSet<RefPtr<WakeLockSentinel>>& ActiveWakeLocks(WakeLockType aType);
|
||||
|
||||
void UnlockAllWakeLocks(WakeLockType aType);
|
||||
|
||||
// ParentNode
|
||||
nsIHTMLCollection* Children();
|
||||
uint32_t ChildElementCount();
|
||||
|
|
@ -5171,10 +5165,6 @@ class Document : public nsINode,
|
|||
// 2) We haven't had Destroy() called on us yet.
|
||||
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
|
||||
|
||||
// Mapping of wake lock types to sets of wake locks sentinels
|
||||
// https://w3c.github.io/screen-wake-lock/#internal-slots
|
||||
nsTHashMap<WakeLockType, nsTHashSet<RefPtr<WakeLockSentinel>>> mActiveLocks;
|
||||
|
||||
// The parsed viewport metadata of the last modified <meta name=viewport>
|
||||
// element.
|
||||
UniquePtr<ViewportMetaData> mLastModifiedViewportMetaData;
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@
|
|||
#include "mozilla/dom/VRServiceTest.h"
|
||||
#include "mozilla/dom/XRSystem.h"
|
||||
#include "mozilla/dom/workerinternals/RuntimeService.h"
|
||||
#include "mozilla/dom/WakeLockJS.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
|
|
@ -162,7 +161,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebGpu)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocks)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUserActivation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWakeLock)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager)
|
||||
|
|
@ -252,8 +250,6 @@ void Navigator::Invalidate() {
|
|||
mUserActivation = nullptr;
|
||||
|
||||
mSharePromise = nullptr;
|
||||
|
||||
mWakeLock = nullptr;
|
||||
}
|
||||
|
||||
void Navigator::GetUserAgent(nsAString& aUserAgent, CallerType aCallerType,
|
||||
|
|
@ -2309,11 +2305,4 @@ already_AddRefed<dom::UserActivation> Navigator::UserActivation() {
|
|||
return do_AddRef(mUserActivation);
|
||||
}
|
||||
|
||||
dom::WakeLockJS* Navigator::WakeLock() {
|
||||
if (!mWakeLock) {
|
||||
mWakeLock = new WakeLockJS(mWindow);
|
||||
}
|
||||
return mWakeLock;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class Clipboard;
|
|||
class LockManager;
|
||||
class HTMLMediaElement;
|
||||
class AudioContext;
|
||||
class WakeLockJS;
|
||||
} // namespace dom
|
||||
namespace webgpu {
|
||||
class Instance;
|
||||
|
|
@ -130,7 +129,6 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|||
bool GlobalPrivacyControl();
|
||||
Geolocation* GetGeolocation(ErrorResult& aRv);
|
||||
Promise* GetBattery(ErrorResult& aRv);
|
||||
dom::WakeLockJS* WakeLock();
|
||||
|
||||
bool CanShare(const ShareData& aData);
|
||||
already_AddRefed<Promise> Share(const ShareData& aData, ErrorResult& aRv);
|
||||
|
|
@ -302,7 +300,6 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|||
RefPtr<Promise> mSharePromise; // Web Share API related
|
||||
RefPtr<dom::LockManager> mLocks;
|
||||
RefPtr<dom::UserActivation> mUserActivation;
|
||||
RefPtr<dom::WakeLockJS> mWakeLock;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
|||
|
|
@ -1028,10 +1028,6 @@ DOMInterfaces = {
|
|||
'nativeType': 'mozilla::dom::TextTrackRegion',
|
||||
},
|
||||
|
||||
'WakeLock': {
|
||||
'nativeType': 'mozilla::dom::WakeLockJS'
|
||||
},
|
||||
|
||||
'WebExtensionContentScript': {
|
||||
'nativeType': 'mozilla::extensions::WebExtensionContentScript',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ static const nsLiteralCString kPermissionTypes[] = {
|
|||
// "midi" is the only public permission but internally we have both "midi"
|
||||
// and "midi-sysex" (and yes, this is confusing).
|
||||
"midi"_ns,
|
||||
"storage-access"_ns,
|
||||
"screen-wake-lock"_ns
|
||||
"storage-access"_ns
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ CreatePermissionStatus(JSContext* aCx, JS::Handle<JSObject*> aPermission,
|
|||
case PermissionName::Notifications:
|
||||
case PermissionName::Push:
|
||||
case PermissionName::Persistent_storage:
|
||||
case PermissionName::Screen_wake_lock:
|
||||
return PermissionStatus::Create(aWindow, permission.mName);
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,277 +0,0 @@
|
|||
/* -*- 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 "ErrorList.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/FeaturePolicyUtils.h"
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WakeLockBinding.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nscore.h"
|
||||
#include "WakeLock.h"
|
||||
#include "WakeLockJS.h"
|
||||
#include "WakeLockSentinel.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
static mozilla::LazyLogModule sLogger("ScreenWakeLock");
|
||||
|
||||
#define MIN_BATTERY_LEVEL 0.05
|
||||
|
||||
nsLiteralCString WakeLockJS::GetRequestErrorMessage(RequestError aRv) {
|
||||
switch (aRv) {
|
||||
case RequestError::DocInactive:
|
||||
return "The requesting document is inactive."_ns;
|
||||
case RequestError::DocHidden:
|
||||
return "The requesting document is hidden."_ns;
|
||||
case RequestError::PolicyDisallowed:
|
||||
return "A permissions policy does not allow screen-wake-lock for the requesting document."_ns;
|
||||
case RequestError::PrefDisabled:
|
||||
return "The pref dom.screenwakelock.enabled is disabled."_ns;
|
||||
case RequestError::InternalFailure:
|
||||
return "A browser-internal error occured."_ns;
|
||||
case RequestError::PermissionDenied:
|
||||
return "Permission to request screen-wake-lock was denied."_ns;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown error reason");
|
||||
return "Unknown error"_ns;
|
||||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#the-request-method steps 2-5
|
||||
WakeLockJS::RequestError WakeLockJS::WakeLockAllowedForDocument(
|
||||
Document* aDoc) {
|
||||
if (!aDoc) {
|
||||
return RequestError::InternalFailure;
|
||||
}
|
||||
|
||||
// Step 2. check policy-controlled feature screen-wake-lock
|
||||
if (!FeaturePolicyUtils::IsFeatureAllowed(aDoc, u"screen-wake-lock"_ns)) {
|
||||
return RequestError::PolicyDisallowed;
|
||||
}
|
||||
|
||||
// Step 3. Deny wake lock for user agent specific reasons
|
||||
if (!StaticPrefs::dom_screenwakelock_enabled()) {
|
||||
return RequestError::PrefDisabled;
|
||||
}
|
||||
|
||||
// Step 4 check doc active
|
||||
if (!aDoc->IsActive()) {
|
||||
return RequestError::DocInactive;
|
||||
}
|
||||
|
||||
// Step 5. check doc visible
|
||||
if (aDoc->Hidden()) {
|
||||
return RequestError::DocHidden;
|
||||
}
|
||||
|
||||
return RequestError::Success;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#dfn-applicable-wake-lock
|
||||
static bool IsWakeLockApplicable(WakeLockType aType) {
|
||||
hal::BatteryInformation batteryInfo;
|
||||
hal::GetCurrentBatteryInformation(&batteryInfo);
|
||||
if (batteryInfo.level() <= MIN_BATTERY_LEVEL && !batteryInfo.charging()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only currently supported wake lock type
|
||||
return aType == WakeLockType::Screen;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#dfn-release-a-wake-lock
|
||||
void ReleaseWakeLock(Document* aDoc, WakeLockSentinel* aLock,
|
||||
WakeLockType aType) {
|
||||
MOZ_ASSERT(aLock);
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
RefPtr<WakeLockSentinel> kungFuDeathGrip = aLock;
|
||||
aDoc->ActiveWakeLocks(aType).Remove(aLock);
|
||||
aLock->NotifyLockReleased();
|
||||
MOZ_LOG(sLogger, LogLevel::Debug, ("Released wake lock sentinel"));
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WakeLockJS, mWindow)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(WakeLockJS)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(WakeLockJS)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WakeLockJS)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentActivity)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
WakeLockJS::WakeLockJS(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) {
|
||||
AttachListeners();
|
||||
}
|
||||
|
||||
WakeLockJS::~WakeLockJS() { DetachListeners(); }
|
||||
|
||||
nsISupports* WakeLockJS::GetParentObject() const { return mWindow; }
|
||||
|
||||
JSObject* WakeLockJS::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return WakeLock_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#the-request-method Step 7.3
|
||||
Result<already_AddRefed<WakeLockSentinel>, WakeLockJS::RequestError>
|
||||
WakeLockJS::Obtain(WakeLockType aType) {
|
||||
// Step 7.3.1. check visibility again
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
if (!doc) {
|
||||
return Err(RequestError::InternalFailure);
|
||||
}
|
||||
if (doc->Hidden()) {
|
||||
return Err(RequestError::DocHidden);
|
||||
}
|
||||
// Step 7.3.3. let lock be a new WakeLockSentinel
|
||||
RefPtr<WakeLockSentinel> lock =
|
||||
MakeRefPtr<WakeLockSentinel>(mWindow->AsGlobal(), aType);
|
||||
// Step 7.3.2. acquire a wake lock
|
||||
if (IsWakeLockApplicable(aType)) {
|
||||
lock->AcquireActualLock();
|
||||
}
|
||||
|
||||
// Steps 7.3.4. append lock to locks
|
||||
doc->ActiveWakeLocks(aType).Insert(lock);
|
||||
|
||||
return lock.forget();
|
||||
}
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#the-request-method
|
||||
already_AddRefed<Promise> WakeLockJS::Request(WakeLockType aType,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_LOG(sLogger, LogLevel::Debug, ("Received request for wake lock"));
|
||||
nsCOMPtr<nsIGlobalObject> global = mWindow->AsGlobal();
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_FALSE(aRv.Failed(), nullptr);
|
||||
|
||||
// Steps 1-5
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
RequestError rv = WakeLockAllowedForDocument(doc);
|
||||
if (rv != RequestError::Success) {
|
||||
promise->MaybeRejectWithNotAllowedError(GetRequestErrorMessage(rv));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// For now, we don't check the permission as we always grant the lock
|
||||
// Step 7.3. Queue a task
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"ObtainWakeLock", [aType, promise, self = RefPtr<WakeLockJS>(this)]() {
|
||||
auto lockOrErr = self->Obtain(aType);
|
||||
if (lockOrErr.isOk()) {
|
||||
RefPtr<WakeLockSentinel> lock = lockOrErr.unwrap();
|
||||
promise->MaybeResolve(lock);
|
||||
MOZ_LOG(sLogger, LogLevel::Debug,
|
||||
("Resolved promise with wake lock sentinel"));
|
||||
} else {
|
||||
promise->MaybeRejectWithNotAllowedError(
|
||||
GetRequestErrorMessage(lockOrErr.unwrapErr()));
|
||||
}
|
||||
}));
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void WakeLockJS::AttachListeners() {
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
DebugOnly<nsresult> rv =
|
||||
doc->AddSystemEventListener(u"visibilitychange"_ns, this, true, false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
doc->RegisterActivityObserver(ToSupports(this));
|
||||
|
||||
hal::RegisterBatteryObserver(this);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(prefBranch);
|
||||
rv = prefBranch->AddObserver("dom.screenwakelock.enabled", this, true);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void WakeLockJS::DetachListeners() {
|
||||
if (mWindow) {
|
||||
if (nsCOMPtr<Document> doc = mWindow->GetExtantDoc()) {
|
||||
doc->RemoveSystemEventListener(u"visibilitychange"_ns, this, true);
|
||||
|
||||
doc->UnregisterActivityObserver(ToSupports(this));
|
||||
}
|
||||
}
|
||||
|
||||
hal::UnregisterBatteryObserver(this);
|
||||
|
||||
if (nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID)) {
|
||||
prefBranch->RemoveObserver("dom.screenwakelock.enabled", this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WakeLockJS::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
|
||||
if (!StaticPrefs::dom_screenwakelock_enabled()) {
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
doc->UnlockAllWakeLocks(WakeLockType::Screen);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void WakeLockJS::NotifyOwnerDocumentActivityChanged() {
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
if (!doc->IsActive()) {
|
||||
doc->UnlockAllWakeLocks(WakeLockType::Screen);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WakeLockJS::HandleEvent(Event* aEvent) {
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
|
||||
if (type.EqualsLiteral("visibilitychange")) {
|
||||
nsCOMPtr<Document> doc = do_QueryInterface(aEvent->GetTarget());
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
if (doc->Hidden()) {
|
||||
doc->UnlockAllWakeLocks(WakeLockType::Screen);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void WakeLockJS::Notify(const hal::BatteryInformation& aBatteryInfo) {
|
||||
if (aBatteryInfo.level() > MIN_BATTERY_LEVEL || aBatteryInfo.charging()) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<Document> doc = mWindow->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
doc->UnlockAllWakeLocks(WakeLockType::Screen);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef DOM_WAKELOCKJS_H_
|
||||
#define DOM_WAKELOCKJS_H_
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/HalBatteryInformation.h"
|
||||
#include "mozilla/dom/WakeLockBinding.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDocumentActivity.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class Promise;
|
||||
class Document;
|
||||
class WakeLockSentinel;
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
/**
|
||||
* Management class for wake locks held from client scripts.
|
||||
* Instances of this class have two purposes:
|
||||
* - Implement navigator.wakeLock.request which creates a WakeLockSentinel
|
||||
* - Listen for state changes that require all WakeLockSentinel to be released
|
||||
* The WakeLockSentinel objects are held in document.mActiveLocks.
|
||||
*
|
||||
* https://www.w3.org/TR/screen-wake-lock/#the-wakelock-interface
|
||||
*/
|
||||
class WakeLockJS final : public nsIDOMEventListener,
|
||||
public nsWrapperCache,
|
||||
public hal::BatteryObserver,
|
||||
public nsIDocumentActivity,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference {
|
||||
public:
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
NS_DECL_NSIDOCUMENTACTIVITY
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(WakeLockJS,
|
||||
nsIDOMEventListener)
|
||||
|
||||
public:
|
||||
explicit WakeLockJS(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
protected:
|
||||
~WakeLockJS();
|
||||
|
||||
public:
|
||||
nsISupports* GetParentObject() const;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void Notify(const hal::BatteryInformation& aBatteryInfo) override;
|
||||
|
||||
already_AddRefed<Promise> Request(WakeLockType aType, ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
enum class RequestError {
|
||||
Success,
|
||||
DocInactive,
|
||||
DocHidden,
|
||||
PolicyDisallowed,
|
||||
PrefDisabled,
|
||||
InternalFailure,
|
||||
PermissionDenied
|
||||
};
|
||||
|
||||
static nsLiteralCString GetRequestErrorMessage(RequestError aRv);
|
||||
|
||||
static RequestError WakeLockAllowedForDocument(Document* aDoc);
|
||||
|
||||
void AttachListeners();
|
||||
void DetachListeners();
|
||||
|
||||
Result<already_AddRefed<WakeLockSentinel>, RequestError> Obtain(
|
||||
WakeLockType aType);
|
||||
|
||||
RefPtr<nsPIDOMWindowInner> mWindow;
|
||||
};
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ReleaseWakeLock(Document* aDoc, WakeLockSentinel* aLock,
|
||||
WakeLockType aType);
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // DOM_WAKELOCKJS_H_
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/* -*- 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/Telemetry.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;
|
||||
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::SCREENWAKELOCK_HELD_DURATION_MS,
|
||||
mCreationTime);
|
||||
|
||||
hal::BatteryInformation batteryInfo;
|
||||
hal::GetCurrentBatteryInformation(&batteryInfo);
|
||||
if (!batteryInfo.charging()) {
|
||||
uint32_t level = static_cast<uint32_t>(100 * batteryInfo.level());
|
||||
Telemetry::Accumulate(
|
||||
Telemetry::SCREENWAKELOCK_RELEASE_BATTERY_LEVEL_DISCHARGING, 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
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef DOM_WAKELOCKSENTINEL_H_
|
||||
#define DOM_WAKELOCKSENTINEL_H_
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/WakeLockBinding.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class Promise;
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class WakeLockSentinel final : public DOMEventTargetHelper {
|
||||
public:
|
||||
WakeLockSentinel(nsIGlobalObject* aOwnerWindow, WakeLockType aType)
|
||||
: DOMEventTargetHelper(aOwnerWindow),
|
||||
mType(aType),
|
||||
mCreationTime(TimeStamp::Now()) {}
|
||||
|
||||
protected:
|
||||
~WakeLockSentinel() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mReleased);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mHoldsActualLock);
|
||||
}
|
||||
|
||||
public:
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool Released() const;
|
||||
|
||||
WakeLockType Type() const { return mType; }
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<Promise> ReleaseLock(ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void NotifyLockReleased();
|
||||
|
||||
IMPL_EVENT_HANDLER(release);
|
||||
|
||||
// Acquire underlying system wake lock by modifying the HAL wake lock counter
|
||||
void AcquireActualLock();
|
||||
|
||||
private:
|
||||
WakeLockType mType;
|
||||
|
||||
bool mReleased = false;
|
||||
|
||||
/**
|
||||
* To avoid user fingerprinting, WakeLockJS::Request will provide a
|
||||
* WakeLockSentinel even if the lock type is not applicable or cannot be
|
||||
* obtained.
|
||||
* But when releasing this sentinel, we have to know whether
|
||||
* AcquireActualLock was called.
|
||||
*
|
||||
* https://w3c.github.io/screen-wake-lock/#dfn-applicable-wake-lock
|
||||
* https://w3c.github.io/screen-wake-lock/#the-request-method
|
||||
*/
|
||||
bool mHoldsActualLock = false;
|
||||
|
||||
// Time when this object was created
|
||||
TimeStamp mCreationTime;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // DOM_WAKELOCKSENTINEL_H_
|
||||
|
|
@ -19,7 +19,9 @@ XPCOM_MANIFESTS += [
|
|||
"components.conf",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += ["WakeLock.h", "WakeLockJS.h", "WakeLockSentinel.h"]
|
||||
EXPORTS.mozilla.dom += [
|
||||
"WakeLock.h",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom.power += [
|
||||
"PowerManagerService.h",
|
||||
|
|
@ -28,12 +30,8 @@ EXPORTS.mozilla.dom.power += [
|
|||
UNIFIED_SOURCES += [
|
||||
"PowerManagerService.cpp",
|
||||
"WakeLock.cpp",
|
||||
"WakeLockJS.cpp",
|
||||
"WakeLockSentinel.cpp",
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ["tests/mochitest.toml"]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
[DEFAULT]
|
||||
prefs = ["dom.screenwakelock.enabled=true"]
|
||||
scheme = "https"
|
||||
|
||||
["test_wakelock_default_permission.html"]
|
||||
fail-if = ["xorigin"] # cross-origin use requires permissions policy
|
||||
|
||||
["test_dynamic_pref_change.html"]
|
||||
fail-if = ["xorigin"] # cross-origin use requires permissions policy
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Screen Wake Lock responds to dynamic pref changes</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
/* globals SpecialPowers */
|
||||
'use strict';
|
||||
|
||||
function spinEventLoop() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, 0);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function my_test() {
|
||||
const lock = await navigator.wakeLock.request("screen");
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.screenwakelock.enabled", false]],
|
||||
});
|
||||
await spinEventLoop();
|
||||
ok(lock.released, "Lock was released once pref was deactivated");
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Screen Wake Lock Permission Granted by Default</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
add_task(async function my_test() {
|
||||
const status = await navigator.permissions.query({name:'screen-wake-lock'});
|
||||
is(status.state, "granted", "Permission is granted by default");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -40,7 +40,6 @@ static FeatureMap sSupportedFeatures[] = {
|
|||
FeaturePolicyUtils::FeaturePolicyValue::eSelf},
|
||||
{"speaker-selection", FeaturePolicyUtils::FeaturePolicyValue::eSelf},
|
||||
{"storage-access", FeaturePolicyUtils::FeaturePolicyValue::eAll},
|
||||
{"screen-wake-lock", FeaturePolicyUtils::FeaturePolicyValue::eSelf},
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ let supportedFeatures = [
|
|||
"speaker-selection",
|
||||
"vr",
|
||||
"web-share",
|
||||
"screen-wake-lock",
|
||||
];
|
||||
|
||||
function checkFeatures(features) {
|
||||
|
|
|
|||
|
|
@ -1967,10 +1967,6 @@ let interfaceNamesInGlobalScope = [
|
|||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "visualViewport", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "WakeLock", nightly: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "WakeLockSentinel", nightly: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "webkitURL", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "window", insecureContext: true },
|
||||
|
|
|
|||
|
|
@ -378,10 +378,3 @@ partial interface Navigator {
|
|||
partial interface Navigator {
|
||||
[SameObject] readonly attribute UserActivation userActivation;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/screen-wake-lock/#extensions-to-the-navigator-interface
|
||||
[SecureContext]
|
||||
partial interface Navigator {
|
||||
[SameObject, Pref="dom.screenwakelock.enabled"]
|
||||
readonly attribute WakeLock wakeLock;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ enum PermissionName {
|
|||
"push",
|
||||
"persistent-storage",
|
||||
"midi",
|
||||
"storage-access", // Defined in https://privacycg.github.io/storage-access/#permissions-integration
|
||||
"screen-wake-lock" // Defined in https://w3c.github.io/screen-wake-lock/
|
||||
"storage-access" // Defined in https://privacycg.github.io/storage-access/#permissions-integration
|
||||
};
|
||||
|
||||
[GenerateInit]
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://w3c.github.io/screen-wake-lock/
|
||||
*/
|
||||
|
||||
[SecureContext, Exposed=(Window)]
|
||||
interface WakeLock {
|
||||
[Throws]
|
||||
Promise<WakeLockSentinel> request(optional WakeLockType type = "screen");
|
||||
};
|
||||
|
||||
enum WakeLockType { "screen" };
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://w3c.github.io/screen-wake-lock/
|
||||
*/
|
||||
|
||||
[SecureContext, Exposed=(Window)]
|
||||
interface WakeLockSentinel : EventTarget {
|
||||
readonly attribute boolean released;
|
||||
readonly attribute WakeLockType type;
|
||||
[BinaryName="releaseLock", Throws]
|
||||
Promise<undefined> release();
|
||||
attribute EventHandler onrelease;
|
||||
};
|
||||
|
|
@ -999,8 +999,6 @@ WEBIDL_FILES = [
|
|||
"VRServiceTest.webidl",
|
||||
"VTTCue.webidl",
|
||||
"VTTRegion.webidl",
|
||||
"WakeLock.webidl",
|
||||
"WakeLockSentinel.webidl",
|
||||
"WaveShaperNode.webidl",
|
||||
"WebAuthentication.webidl",
|
||||
"WebGL2RenderingContext.webidl",
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ static const DelegateInfo sPermissionsMap[] = {
|
|||
{"microphone", u"microphone", DelegatePolicy::eDelegateUseFeaturePolicy},
|
||||
{"screen", u"display-capture", DelegatePolicy::eDelegateUseFeaturePolicy},
|
||||
{"xr", u"xr-spatial-tracking", DelegatePolicy::eDelegateUseFeaturePolicy},
|
||||
{"screen-wake-lock", u"screen-wake-lock",
|
||||
DelegatePolicy::eDelegateUseFeaturePolicy}};
|
||||
};
|
||||
|
||||
static_assert(PermissionDelegateHandler::DELEGATED_PERMISSION_COUNT ==
|
||||
(sizeof(sPermissionsMap) / sizeof(DelegateInfo)),
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class PermissionDelegateHandler final : public nsIPermissionDelegateHandler {
|
|||
explicit PermissionDelegateHandler() = default;
|
||||
explicit PermissionDelegateHandler(mozilla::dom::Document* aDocument);
|
||||
|
||||
static constexpr size_t DELEGATED_PERMISSION_COUNT = 13;
|
||||
static constexpr size_t DELEGATED_PERMISSION_COUNT = 12;
|
||||
|
||||
typedef struct DelegatedPermissionList {
|
||||
Array<uint32_t, DELEGATED_PERMISSION_COUNT> mPermissions;
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ bool HasDefaultPref(const nsACString& aType) {
|
|||
// set under the permissions.default.* pref.
|
||||
static const nsLiteralCString kPermissionsWithDefaults[] = {
|
||||
"camera"_ns, "microphone"_ns, "geo"_ns, "desktop-notification"_ns,
|
||||
"shortcuts"_ns, "screen-wake-lock"_ns};
|
||||
"shortcuts"_ns};
|
||||
|
||||
if (!aType.IsEmpty()) {
|
||||
for (const auto& perm : kPermissionsWithDefaults) {
|
||||
|
|
|
|||
|
|
@ -48,11 +48,9 @@
|
|||
#include "js/WasmFeatures.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ScriptLoader.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "mozilla/dom/WakeLockBinding.h"
|
||||
#include "mozilla/extensions/WebExtensionPolicy.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
|
@ -749,9 +747,6 @@ bool XPCJSContext::InterruptCallback(JSContext* cx) {
|
|||
if (Preferences::GetBool("dom.global_stop_script", true)) {
|
||||
xpc::Scriptability::Get(global).Block();
|
||||
}
|
||||
if (nsCOMPtr<Document> doc = win->GetExtantDoc()) {
|
||||
doc->UnlockAllWakeLocks(WakeLockType::Screen);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3461,18 +3461,6 @@
|
|||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# Enable Screen Wake Lock API
|
||||
- name: dom.screenwakelock.enabled
|
||||
type: bool
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# Prevent errors when using set_permission from permissions.sys.mjs
|
||||
- name: dom.screenwakelock.testing
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Whether to enable the JavaScript start-up cache. This causes one of the first
|
||||
# execution to record the bytecode of the JavaScript function used, and save it
|
||||
# in the existing cache entry. On the following loads of the same script, the
|
||||
|
|
@ -12825,11 +12813,6 @@
|
|||
value: 1
|
||||
mirror: always
|
||||
|
||||
- name: permissions.default.screen-wake-lock
|
||||
type: RelaxedAtomicUint32
|
||||
value: 1
|
||||
mirror: always
|
||||
|
||||
- name: permissions.isolateBy.userContext
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
|
|
|
|||
|
|
@ -114,13 +114,6 @@ permissions.set = function (
|
|||
`'Set Permission' did not work for storage-access'`
|
||||
);
|
||||
}
|
||||
} else if (name === "screen-wake-lock") {
|
||||
if (Services.prefs.getBoolPref("dom.screenwakelock.testing", false)) {
|
||||
return;
|
||||
}
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
"'Set Permission' expected dom.screenwakelock.testing to be set"
|
||||
);
|
||||
}
|
||||
|
||||
throw new lazy.error.UnsupportedOperationError(
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
[Query "nfc" permission]
|
||||
expected: FAIL
|
||||
|
||||
[Query "screen-wake-lock" permission]
|
||||
expected: FAIL
|
||||
|
||||
[Query "camera" permission]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
prefs: [marionette.setpermission.enabled:true, dom.screenwakelock.enabled:true, dom.screenwakelock.testing:true]
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
[chrome-bug-1348019.https.html]
|
||||
expected:
|
||||
if (os == "android"): ERROR # cannot minimize window
|
||||
[Appending iframe in release event listener does not cause a crash when page visibility changes]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
[idlharness.https.window.html]
|
||||
[WakeLockSentinel interface: operation release()]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[idl_test setup]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel must be primary interface of sentinel]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: sentinel must inherit property "onrelease" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: sentinel must inherit property "release()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of sentinel]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: attribute type]
|
||||
expected: FAIL
|
||||
|
||||
[Navigator interface: attribute wakeLock]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of navigator.wakeLock]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: sentinel must inherit property "type" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: attribute onrelease]
|
||||
expected: FAIL
|
||||
|
||||
[Navigator interface: navigator must inherit property "wakeLock" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock must be primary interface of navigator.wakeLock]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: sentinel must inherit property "released" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLockSentinel interface: attribute released]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: calling request(optional WakeLockType) on navigator.wakeLock with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: navigator.wakeLock must inherit property "request(optional WakeLockType)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[WakeLock interface: operation request(optional WakeLockType)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[wakelock-active-document.https.window.html]
|
||||
[navigator.wakeLock.request() aborts if the document is not active.]
|
||||
expected: FAIL
|
||||
|
||||
[navigator.wakeLock.request() aborts if the document is active, but not fully active.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
@ -3,6 +3,3 @@
|
|||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Permissions-Policy header "screen-wake-lock=()" disallows the top-level document.]
|
||||
expected: FAIL
|
||||
|
||||
[Permissions-Policy header "screen-wake-lock=()" disallows same-origin iframes.]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
[wakelock-document-hidden.https.html]
|
||||
expected:
|
||||
if (os == "android"): ERROR # cannot minimize window
|
||||
[navigator.wakeLock.request('screen') fails when the document is hidden]
|
||||
expected: FAIL
|
||||
|
||||
[Screen wake locks are released when the document the page is hidden]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
[wakelock-enabled-by-permissions-policy-attribute-redirect-on-load.https.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Permissions-Policy allow="screen-wake-lock" allows same-origin relocation]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[wakelock-enabled-by-permissions-policy-attribute.https.html]
|
||||
[Permissions policy "screen-wake-lock" can be enabled in same-origin iframe using allow="screen-wake-lock" attribute]
|
||||
expected: FAIL
|
||||
|
||||
[Permissions policy "screen-wake-lock" can be enabled in cross-origin iframe using allow="screen-wake-lock" attribute]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[wakelock-enabled-by-permissions-policy.https.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Permissions-Policy header "screen-wake-lock=*" allows the top-level document.]
|
||||
expected: FAIL
|
||||
|
||||
[Permissions-Policy header "screen-wake-lock=*" allows same-origin iframes.]
|
||||
expected: FAIL
|
||||
|
||||
[Permissions-Policy header "screen-wake-lock=*" allows cross-origin iframes.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
[wakelock-enabled-on-self-origin-by-permissions-policy.https.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Permissions-Policy header "screen-wake-lock=self" allows the top-level document.]
|
||||
expected: FAIL
|
||||
|
||||
[Permissions-Policy header "screen-wake-lock=self" allows same-origin iframes.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[wakelock-insecure-context.any.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
|
||||
[wakelock-insecure-context.any.worker.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
[wakelock-onrelease.https.html]
|
||||
expected:
|
||||
if swgl and (os == "win"): [OK, ERROR]
|
||||
[Test onreleased event's basic properties]
|
||||
expected: FAIL
|
||||
|
||||
[Ensure onreleased is called before WakeLockSentinel.release() resolves]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[wakelock-released.https.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[The released attribute inside an event handler]
|
||||
expected: FAIL
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
[wakelock-request-denied.https.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Denied requests should abort with NotAllowedError]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -1,2 +1,5 @@
|
|||
[wakelock-supported-by-permissions-policy.html]
|
||||
prefs: [dom.security.featurePolicy.webidl.enabled:true]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[document.featurePolicy.features should advertise screen-wake-lock.]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
[wakelock-type.https.window.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
['type' parameter in WakeLock.request() defaults to 'screen']
|
||||
expected: FAIL
|
||||
|
||||
['TypeError' is thrown when set an invalid wake lock type]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +1,5 @@
|
|||
[wakelockpermissiondescriptor.https.html]
|
||||
prefs: [permissions.default.screen-wake-lock:2]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[PermissionDescriptor with name='screen-wake-lock' works]
|
||||
expected: FAIL
|
||||
|
|
|
|||
|
|
@ -4,19 +4,15 @@
|
|||
"use strict";
|
||||
|
||||
Promise.resolve().then(async () => {
|
||||
test_driver.set_test_context(window.parent);
|
||||
await test_driver.set_permission({ name: 'screen-wake-lock' }, 'granted');
|
||||
|
||||
try {
|
||||
await test_driver.set_permission(
|
||||
{ name: 'screen-wake-lock' }, 'granted');
|
||||
|
||||
const wakeLock = await navigator.wakeLock.request("screen");
|
||||
window.parent.postMessage({ type: 'availability-result', enabled: true }, "*");
|
||||
await wakeLock.release();
|
||||
window.parent.postMessage({ type: 'availability-result', enabled: true }, "*");
|
||||
} catch (e) {
|
||||
if (e instanceof DOMException && e.name === "NotAllowedError") {
|
||||
window.parent.postMessage({ type: 'availability-result', enabled: false }, "*");
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/permissions-policy/resources/permissions-policy.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/permissions-policy/resources/permissions-policy.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/permissions-policy/resources/permissions-policy.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -35,20 +35,5 @@ promise_test(async t => {
|
|||
assert_true(releaseFired, "The 'release' event fires immediately after release() is called");
|
||||
|
||||
return releasePromise;
|
||||
}, "Ensure onrelease is called before WakeLockSentinel.release() resolves");
|
||||
|
||||
promise_test(async t => {
|
||||
await test_driver.set_permission({ name: 'screen-wake-lock' }, 'granted');
|
||||
|
||||
const lock = await navigator.wakeLock.request("screen");
|
||||
|
||||
let eventCount = 0;
|
||||
lock.onrelease = t.step_func(() => {
|
||||
eventCount++;
|
||||
});
|
||||
|
||||
await lock.release();
|
||||
await lock.release();
|
||||
assert_equals(eventCount, 1, "The 'release' event was fired once");
|
||||
}, "Ensure onrelease is fired exactly once");
|
||||
}, "Ensure onreleased is called before WakeLockSentinel.release() resolves");
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -18173,29 +18173,5 @@
|
|||
"record_in_processes": ["all"],
|
||||
"labels": ["inits"],
|
||||
"releaseChannelCollection": "opt-out"
|
||||
},
|
||||
"SCREENWAKELOCK_HELD_DURATION_MS": {
|
||||
"record_in_processes": ["content"],
|
||||
"products": ["firefox"],
|
||||
"alert_emails": ["vhilla@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"low": 240000,
|
||||
"high": 28800000,
|
||||
"n_buckets": 50,
|
||||
"bug_numbers": [1589554],
|
||||
"description": "How long a screen wake lock was held in ms"
|
||||
},
|
||||
"SCREENWAKELOCK_RELEASE_BATTERY_LEVEL_DISCHARGING": {
|
||||
"record_in_processes": ["content"],
|
||||
"products": ["firefox"],
|
||||
"alert_emails": ["vhilla@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "linear",
|
||||
"low": 1,
|
||||
"high": 100,
|
||||
"n_buckets": 50,
|
||||
"bug_numbers": [1589554],
|
||||
"description": "Battery level when discharging and the wake lock was released"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1627,7 +1627,6 @@ STATIC_ATOMS = [
|
|||
Atom("onbeginEvent", "onbeginEvent"),
|
||||
Atom("onend", "onend"),
|
||||
Atom("onendEvent", "onendEvent"),
|
||||
Atom("onrelease", "onrelease"),
|
||||
Atom("onrepeat", "onrepeat"),
|
||||
Atom("onrepeatEvent", "onrepeatEvent"),
|
||||
Atom("repeatCount", "repeatCount"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue