diff options
Diffstat (limited to 'dom/power')
-rw-r--r-- | dom/power/WakeLockJS.cpp | 64 | ||||
-rw-r--r-- | dom/power/WakeLockJS.h | 11 | ||||
-rw-r--r-- | dom/power/tests/file_empty.html | 1 | ||||
-rw-r--r-- | dom/power/tests/mochitest.toml | 5 | ||||
-rw-r--r-- | dom/power/tests/test_wakelock_on_initial_about_blank.html | 49 |
5 files changed, 70 insertions, 60 deletions
diff --git a/dom/power/WakeLockJS.cpp b/dom/power/WakeLockJS.cpp index 50e4a716c0..3aa748fbe6 100644 --- a/dom/power/WakeLockJS.cpp +++ b/dom/power/WakeLockJS.cpp @@ -127,8 +127,7 @@ 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_AMBIGUOUS(nsISupports, nsIObserver) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END @@ -148,14 +147,12 @@ JSObject* WakeLockJS::WrapObject(JSContext* aCx, // https://w3c.github.io/screen-wake-lock/#the-request-method Step 7.3 Result<already_AddRefed<WakeLockSentinel>, WakeLockJS::RequestError> -WakeLockJS::Obtain(WakeLockType aType) { +WakeLockJS::Obtain(WakeLockType aType, Document* aDoc) { // 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); + // Out of spec, but also check everything else + RequestError rv = WakeLockAllowedForDocument(aDoc); + if (rv != RequestError::Success) { + return Err(rv); } // Step 7.3.3. let lock be a new WakeLockSentinel RefPtr<WakeLockSentinel> lock = @@ -166,7 +163,7 @@ WakeLockJS::Obtain(WakeLockType aType) { } // Steps 7.3.4. append lock to locks - doc->ActiveWakeLocks(aType).Insert(lock); + aDoc->ActiveWakeLocks(aType).Insert(lock); return lock.forget(); } @@ -191,8 +188,9 @@ already_AddRefed<Promise> WakeLockJS::Request(WakeLockType aType, // 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); + "ObtainWakeLock", + [aType, promise, doc, self = RefPtr<WakeLockJS>(this)]() { + auto lockOrErr = self->Obtain(aType, doc); if (lockOrErr.isOk()) { RefPtr<WakeLockSentinel> lock = lockOrErr.unwrap(); promise->MaybeResolve(lock); @@ -208,30 +206,16 @@ already_AddRefed<Promise> WakeLockJS::Request(WakeLockType aType, } 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); + DebugOnly<nsresult> 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 = @@ -252,30 +236,6 @@ NS_IMETHODIMP WakeLockJS::Observe(nsISupports* aSubject, const char* aTopic, 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; diff --git a/dom/power/WakeLockJS.h b/dom/power/WakeLockJS.h index c6858fdd22..43b11a6dc9 100644 --- a/dom/power/WakeLockJS.h +++ b/dom/power/WakeLockJS.h @@ -39,20 +39,15 @@ namespace mozilla::dom { * * https://www.w3.org/TR/screen-wake-lock/#the-wakelock-interface */ -class WakeLockJS final : public nsIDOMEventListener, +class WakeLockJS final : public nsIObserver, 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) + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(WakeLockJS, nsIObserver) public: explicit WakeLockJS(nsPIDOMWindowInner* aWindow); @@ -89,7 +84,7 @@ class WakeLockJS final : public nsIDOMEventListener, void DetachListeners(); Result<already_AddRefed<WakeLockSentinel>, RequestError> Obtain( - WakeLockType aType); + WakeLockType aType, Document* aDoc); RefPtr<nsPIDOMWindowInner> mWindow; }; diff --git a/dom/power/tests/file_empty.html b/dom/power/tests/file_empty.html new file mode 100644 index 0000000000..4f54ef40a6 --- /dev/null +++ b/dom/power/tests/file_empty.html @@ -0,0 +1 @@ +<h1>Example page</h1> diff --git a/dom/power/tests/mochitest.toml b/dom/power/tests/mochitest.toml index 0b57119a8a..47e10ee3cd 100644 --- a/dom/power/tests/mochitest.toml +++ b/dom/power/tests/mochitest.toml @@ -1,9 +1,14 @@ [DEFAULT] prefs = ["dom.screenwakelock.enabled=true"] scheme = "https" +support-files = [ + "file_empty.html", +] ["test_dynamic_pref_change.html"] fail-if = ["xorigin"] # cross-origin use requires permissions policy ["test_wakelock_default_permission.html"] fail-if = ["xorigin"] # cross-origin use requires permissions policy + +["test_wakelock_on_initial_about_blank.html"] diff --git a/dom/power/tests/test_wakelock_on_initial_about_blank.html b/dom/power/tests/test_wakelock_on_initial_about_blank.html new file mode 100644 index 0000000000..eefa6c6fb7 --- /dev/null +++ b/dom/power/tests/test_wakelock_on_initial_about_blank.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test requesting lock on the initial about:blank</title> + <link rel="help" href="https://bugzilla.mozilla.org/1882344"/> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + + add_task(async function test() { + const iframe = document.createElement('iframe'); + iframe.src = "file_empty.html"; + document.documentElement.appendChild(iframe); + + // https://html.spec.whatwg.org/multipage/nav-history-apis.html#the-window-object:initialise-the-document-object + is(iframe.contentWindow.location.href, "about:blank", "Initial about:blank is loaded"); + + let lock; + try { + // request lock on initial about:blank + lock = await iframe.contentWindow.navigator.wakeLock.request(); + } catch (err) { + // This could happen if the initial about:blank document is inactive + // once the async code in .request runs. + ok(true, "request was rejected"); + return; + } + + if (iframe.contentWindow.location.href == "about:blank") { + await new Promise((res, _rej) => { iframe.onload = res; }); + } + isnot(iframe.contentWindow.location.href, "about:blank", "Target document is loaded"); + + is(lock.released, true, "lock was released by load of target doc"); + + // window and wakeLock object stayed the same, but document changed + await iframe.contentWindow.navigator.wakeLock.request(); + ok(true, "Was able to request lock on target document"); + }); + + </script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> |