summaryrefslogtreecommitdiffstats
path: root/dom/power
diff options
context:
space:
mode:
Diffstat (limited to 'dom/power')
-rw-r--r--dom/power/WakeLockJS.cpp64
-rw-r--r--dom/power/WakeLockJS.h11
-rw-r--r--dom/power/tests/file_empty.html1
-rw-r--r--dom/power/tests/mochitest.toml5
-rw-r--r--dom/power/tests/test_wakelock_on_initial_about_blank.html49
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>