-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WIP] wake lock: Adapt to the version of the spec in PR #201
This CL includes an implementation of the Wake Lock spec after https://github.com/w3c/wake-lock/pull/201 [this will be updated once pending clean-up PRs are merged too]. The spec has undergone significant changes since the latest update to the implementation, and multiple features were added and removed to the spec in the meantime. From a Web API user perspective, the Wake Lock API surface is now pretty small: * While the Wake Lock interface still exists, it only contains two static methods, requestPermission() and request(). requestPermission() needs pending work on the permissions side in //content and //chrome, so this CL only implements request(). * navigator.getWakeLock() and WakeLock.createRequest() have been removed and replaced by a single call to WakeLock.request(). * A consequence of the two items above is that it is no longer possible to actually hold a WakeLock object (and all attributes and event listeners are gone). * WakeLock.request() returns a promise that never resolves when it works, and rejects with either NotAllowedError or AbortError in case something did not work or the lock was cancelled. * We now use the AbortSignal mechanism from the DOM spec (just like other specs such as Fetch) for cancelling a Wake Lock. From a Blink perspective: * wake_lock.cc just performs the validation steps in WakeLock.request(), and delegates the act of acquiring or releasing a wake lock to WakeLockController. * WakeLockController is similar to other controllers (like the ones in device_orientation/) and tracks per-Document wake lock state. It also does not acquire or release wake locks itself, but rather delegates it to its per-wake-lock-type instances of WakeLockStateRecord. It also handles per-document visibility and activity changes. * WakeLockStateRecord implements the spec's concept of "state record" and actually requests and cancels wake locks (by talking to //content and //services). Major pending Wake Lock features present in the spec: * Workers support * Permission handling Bug: 257511 Change-Id: I3dced3a16711b720a96b1a0d5c008d49e3b38c6d
- Loading branch information
1 parent
e426a69
commit bd24c30
Showing
15 changed files
with
195 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,25 @@ | ||
<script> | ||
"use strict"; | ||
|
||
Promise.resolve().then(() => { | ||
try { | ||
const wakeLock = new WakeLock("screen"); | ||
window.parent.postMessage({ enabled: true }, "*"); | ||
} catch (e) { | ||
window.parent.postMessage({ enabled: false }, "*"); | ||
} | ||
Promise.resolve().then(async () => { | ||
// On success, WakeLock.request() returns a promise that never resolves. To | ||
// prevent a timeout, abort it with an AbortController and use the different | ||
// DOMExceptions we get to determine if this worked or not. | ||
const controller = new AbortController(); | ||
const wakeLock = WakeLock.request("screen", { signal: controller.signal }); | ||
wakeLock.catch(e => { | ||
if (e.name == "AbortError") { | ||
// We stopped due to the call to AbortController.abort(), so we did manage | ||
// to get the lock. | ||
window.parent.postMessage({ enabled: true }, "*"); | ||
} else if (e.name == "NotAllowedError") { | ||
// This means requesting the lock failed. | ||
window.parent.postMessage({ enabled: false }, "*"); | ||
} else { | ||
// We should not really hit this branch. | ||
window.parent.postMessage({ enabled: false }, "*"); | ||
} | ||
}); | ||
controller.abort(); | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<meta charset="utf-8"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<meta charset="utf-8"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>WakeLock: passing an AbortSignal already set aborts</title> | ||
<link rel="help" href="https://w3c.github.io/wake-lock/"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
promise_test(t => { | ||
const abortController = new AbortController(); | ||
const abortSignal = abortController.signal; | ||
abortController.abort(); | ||
assert_true(abortSignal.aborted); | ||
|
||
return promise_rejects(t, "AbortError", WakeLock.request('screen', { signal: abortSignal })); | ||
}, "A WakeLock request with an AbortSignal whose abort flag is set always aborts"); | ||
|
||
promise_test(async t => { | ||
const abortController = new AbortController(); | ||
const abortSignal = abortController.signal; | ||
abortController.abort(); | ||
assert_true(abortSignal.aborted); | ||
|
||
const lock1 = WakeLock.request('screen', { signal: abortSignal }); | ||
const lock2 = WakeLock.request('screen', { signal: abortSignal }); | ||
const lock3 = WakeLock.request('system', { signal: abortSignal }); | ||
|
||
await promise_rejects(t, "AbortError", lock1); | ||
await promise_rejects(t, "AbortError", lock2); | ||
await promise_rejects(t, "AbortError", lock3); | ||
}, "The same AbortSignal can be used to cause multiple wake locks to abort"); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
function getWakeLockObject(iframe, url) { | ||
return new Promise(resolve => { | ||
iframe.addEventListener( | ||
"load", | ||
() => { | ||
const { WakeLock } = iframe.contentWindow; | ||
resolve(WakeLock); | ||
}, | ||
{ once: true } | ||
); | ||
iframe.src = url; | ||
}); | ||
} | ||
|
||
promise_test(async t => { | ||
const iframe = document.createElement("iframe"); | ||
document.body.appendChild(iframe); | ||
// We first got to page1.html, grab a WakeLock object. | ||
const wakeLock1 = await getWakeLockObject( | ||
iframe, | ||
"/wake-lock/resources/page1.html" | ||
); | ||
// We navigate the iframe again, putting wakeLock1's document into an inactive state. | ||
const wakeLock2 = await getWakeLockObject( | ||
iframe, | ||
"/wake-lock/resources/page2.html" | ||
); | ||
// Now, wakeLock1's relevant global object's document is no longer active. | ||
// So, call .request(), and make sure it rejects appropriately. | ||
await promise_rejects( | ||
t, | ||
"NotAllowedError", | ||
wakeLock1.request('screen'), | ||
"Inactive document, so must throw NotAllowedError" | ||
); | ||
// We are done, so clean up. | ||
iframe.remove(); | ||
}, "WakeLock.request() aborts if the document is not active."); | ||
|
||
promise_test(async t => { | ||
// We nest two iframes and wait for them to load. | ||
const outerIframe = document.createElement("iframe"); | ||
document.body.appendChild(outerIframe); | ||
// Load the outer iframe (we don't care about the awaited request) | ||
await getWakeLockObject( | ||
outerIframe, | ||
"/wake-lock/resources/page1.html" | ||
); | ||
|
||
// Now we create the inner iframe | ||
const innerIframe = outerIframe.contentDocument.createElement("iframe"); | ||
|
||
// nest them | ||
outerIframe.contentDocument.body.appendChild(innerIframe); | ||
|
||
// load innerIframe, and get the WakeLock instance | ||
const wakeLock = await getWakeLockObject( | ||
innerIframe, | ||
"/wake-lock/resources/page2.html" | ||
); | ||
|
||
// Navigate the outer iframe to a new location. | ||
// Wait for the load event to fire. | ||
await new Promise(resolve => { | ||
outerIframe.addEventListener("load", resolve); | ||
outerIframe.src = "/wake-lock/resources/page2.html"; | ||
}); | ||
|
||
// Now, request's relevant global object's document is still active | ||
// (it is the active document of the inner iframe), but is not fully active | ||
// (since the parent of the inner iframe is itself no longer active). | ||
// So, call request.show() and make sure it rejects appropriately. | ||
await promise_rejects( | ||
t, | ||
"NotAllowedError", | ||
wakeLock.request('screen'), | ||
"Active, but not fully active, so must throw NotAllowedError" | ||
); | ||
// We are done, so clean up. | ||
outerIframe.remove(); | ||
}, "WakeLock.request() aborts if the document is active, but not fully active."); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<meta name="timeout" content="long"> | ||
<title>Screen wake locks respect page visibility changes</title> | ||
<link rel="help" href="https://w3c.github.io/wake-lock/#dfn-requesting-the-wake-lock"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
|
||
promise_test(async t => { | ||
const controller = new AbortController(); | ||
const screenWakeLock = WakeLock.request('screen', { signal: controller.signal }); | ||
const systemWakeLock = WakeLock.request('system', { signal: controller.signal }); | ||
const systemWakeLockPromise = new Promise((resolve, reject) => { | ||
systemWakeLock.catch(error => { | ||
assert_equals("AbortError", error.name, "systemWakeLock must have been aborted"); | ||
assert_false(document.hidden, "systemWakeLock must have been aborted after the page is visible again"); | ||
resolve(); | ||
}); | ||
}); | ||
|
||
const eventWatcher = new EventWatcher(t, document, "visibilitychange"); | ||
await eventWatcher.wait_for("visibilitychange"); | ||
assert_true(document.hidden, "document is hidden after the visibilitychange event"); | ||
await promise_rejects(t, "AbortError", screenWakeLock, "existing screen locks are aborted"); | ||
await promise_rejects(t, "NotAllowedError", WakeLock.request('screen'), | ||
"new screen locks are not allowed when the page is not visible"); | ||
|
||
await eventWatcher.wait_for("visibilitychange"); | ||
assert_false(document.hidden, "document is no longer hidden after the visibilitychange event"); | ||
controller.abort(); | ||
|
||
return systemWakeLockPromise; | ||
}, "Test screen locks respect page visibility changes and system locks are unchanged"); | ||
|
||
</script> | ||
|
||
<p>Switch the page to the background, then switch back to it.</p> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.