Commit 9e71d67d authored by Raphael Kubo da Costa's avatar Raphael Kubo da Costa Committed by Commit Bot

wake lock: Add WakeLockSentinel.released.

This new attribute indicates whether a sentinel object has been released or
not. While here, move the dispatching of the "release" event to a separate
method so that we can really change |release|'s value and dispatch the event
in a separate, queued task.

Additional web tests have been sent directly to WPT in
https://github.com/web-platform-tests/wpt/pull/25271.

Spec PR: https://github.com/w3c/screen-wake-lock/pull/279
ChromeStatus entry: https://chromestatus.com/feature/5632527123349504
Intent to Prototype and Ship: https://groups.google.com/a/chromium.org/g/blink-dev/c/1V6Ss1VABko/m/Y3Nl0vHIAQAJ

Fixed: 1122518
Change-Id: Iff39ec3db630fa959e6c3c82b9c5ee8df93b681c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2379740
Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
Reviewed-by: default avatarYoav Weiss <yoavweiss@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Auto-Submit: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
Cr-Commit-Position: refs/heads/master@{#804729}
parent 6aba9c76
...@@ -34,6 +34,10 @@ ScriptPromise WakeLockSentinel::release(ScriptState* script_state) { ...@@ -34,6 +34,10 @@ ScriptPromise WakeLockSentinel::release(ScriptState* script_state) {
return ScriptPromise::CastUndefined(script_state); return ScriptPromise::CastUndefined(script_state);
} }
bool WakeLockSentinel::released() const {
return released_;
}
String WakeLockSentinel::type() const { String WakeLockSentinel::type() const {
// https://w3c.github.io/wake-lock/#dom-wakelocksentinel-type // https://w3c.github.io/wake-lock/#dom-wakelocksentinel-type
// The type attribute corresponds to the WakeLockSentinel's wake lock type. // The type attribute corresponds to the WakeLockSentinel's wake lock type.
...@@ -90,7 +94,19 @@ void WakeLockSentinel::DoRelease() { ...@@ -90,7 +94,19 @@ void WakeLockSentinel::DoRelease() {
if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
return; return;
// 6. Queue a task to fire an event named "release" at lock. // 6. Queue a task to run the following steps:
GetExecutionContext()
->GetTaskRunner(TaskType::kMiscPlatformAPI)
->PostTask(FROM_HERE, WTF::Bind(&WakeLockSentinel::DispatchReleaseEvent,
WrapWeakPersistent(this)));
}
void WakeLockSentinel::DispatchReleaseEvent() {
// https://w3c.github.io/wake-lock/#release-wake-lock-algorithm
// 6.1. Set lock.released to true.
DCHECK(!released_);
released_ = true;
// 6.2. Fire an event named "release" at lock.
DispatchEvent(*Event::Create(event_type_names::kRelease)); DispatchEvent(*Event::Create(event_type_names::kRelease));
} }
......
...@@ -36,6 +36,7 @@ class MODULES_EXPORT WakeLockSentinel final ...@@ -36,6 +36,7 @@ class MODULES_EXPORT WakeLockSentinel final
// Web-exposed interfaces // Web-exposed interfaces
DEFINE_ATTRIBUTE_EVENT_LISTENER(release, kRelease) DEFINE_ATTRIBUTE_EVENT_LISTENER(release, kRelease)
ScriptPromise release(ScriptState*); ScriptPromise release(ScriptState*);
bool released() const;
String type() const; String type() const;
// EventTarget overrides. // EventTarget overrides.
...@@ -60,7 +61,10 @@ class MODULES_EXPORT WakeLockSentinel final ...@@ -60,7 +61,10 @@ class MODULES_EXPORT WakeLockSentinel final
// where |script_state_|'s context is no longer valid. // where |script_state_|'s context is no longer valid.
void DoRelease(); void DoRelease();
void DispatchReleaseEvent();
Member<WakeLockManager> manager_; Member<WakeLockManager> manager_;
bool released_ = false;
const WakeLockType type_; const WakeLockType type_;
FRIEND_TEST_ALL_PREFIXES(WakeLockSentinelTest, MultipleReleaseCalls); FRIEND_TEST_ALL_PREFIXES(WakeLockSentinelTest, MultipleReleaseCalls);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
] interface WakeLockSentinel : EventTarget { ] interface WakeLockSentinel : EventTarget {
attribute EventHandler onrelease; attribute EventHandler onrelease;
readonly attribute boolean released;
readonly attribute WakeLockType type; readonly attribute WakeLockType type;
[CallWith=ScriptState] Promise<void> release(); [CallWith=ScriptState] Promise<void> release();
......
...@@ -51,6 +51,23 @@ TEST(WakeLockSentinelTest, SentinelType) { ...@@ -51,6 +51,23 @@ TEST(WakeLockSentinelTest, SentinelType) {
EXPECT_EQ("system", sentinel->type()); EXPECT_EQ("system", sentinel->type());
} }
TEST(WakeLockSentinelTest, SentinelReleased) {
MockWakeLockService wake_lock_service;
WakeLockTestingContext context(&wake_lock_service);
auto* manager = MakeGarbageCollected<WakeLockManager>(context.DomWindow(),
WakeLockType::kScreen);
auto* sentinel = MakeGarbageCollected<WakeLockSentinel>(
context.GetScriptState(), WakeLockType::kScreen, manager);
EXPECT_FALSE(sentinel->released());
manager = MakeGarbageCollected<WakeLockManager>(context.DomWindow(),
WakeLockType::kSystem);
sentinel = MakeGarbageCollected<WakeLockSentinel>(
context.GetScriptState(), WakeLockType::kSystem, manager);
EXPECT_FALSE(sentinel->released());
}
TEST(WakeLockSentinelTest, MultipleReleaseCalls) { TEST(WakeLockSentinelTest, MultipleReleaseCalls) {
MockWakeLockService wake_lock_service; MockWakeLockService wake_lock_service;
WakeLockTestingContext context(&wake_lock_service); WakeLockTestingContext context(&wake_lock_service);
...@@ -65,6 +82,7 @@ TEST(WakeLockSentinelTest, MultipleReleaseCalls) { ...@@ -65,6 +82,7 @@ TEST(WakeLockSentinelTest, MultipleReleaseCalls) {
auto* sentinel = auto* sentinel =
ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise); ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise);
ASSERT_NE(nullptr, sentinel); ASSERT_NE(nullptr, sentinel);
EXPECT_FALSE(sentinel->released());
base::RunLoop run_loop; base::RunLoop run_loop;
auto* event_listener = auto* event_listener =
...@@ -75,12 +93,14 @@ TEST(WakeLockSentinelTest, MultipleReleaseCalls) { ...@@ -75,12 +93,14 @@ TEST(WakeLockSentinelTest, MultipleReleaseCalls) {
sentinel->removeEventListener(event_type_names::kRelease, event_listener); sentinel->removeEventListener(event_type_names::kRelease, event_listener);
EXPECT_EQ(nullptr, sentinel->manager_); EXPECT_EQ(nullptr, sentinel->manager_);
EXPECT_TRUE(sentinel->released());
event_listener = MakeGarbageCollected<SyncEventListener>(WTF::Bind([]() { event_listener = MakeGarbageCollected<SyncEventListener>(WTF::Bind([]() {
EXPECT_TRUE(false) << "This event handler should not be reached."; EXPECT_TRUE(false) << "This event handler should not be reached.";
})); }));
sentinel->addEventListener(event_type_names::kRelease, event_listener); sentinel->addEventListener(event_type_names::kRelease, event_listener);
sentinel->release(context.GetScriptState()); sentinel->release(context.GetScriptState());
EXPECT_TRUE(sentinel->released());
} }
TEST(WakeLockSentinelTest, ContextDestruction) { TEST(WakeLockSentinelTest, ContextDestruction) {
......
This is a testharness.js-based test.
PASS idl_test setup
PASS idl_test validation
PASS Partial interface Navigator: original interface defined
PASS Partial interface Navigator: member names are unique
PASS Partial interface mixin NavigatorID: member names are unique
PASS Navigator includes NavigatorID: member names are unique
PASS Navigator includes NavigatorLanguage: member names are unique
PASS Navigator includes NavigatorOnLine: member names are unique
PASS Navigator includes NavigatorContentUtils: member names are unique
PASS Navigator includes NavigatorCookies: member names are unique
PASS Navigator includes NavigatorPlugins: member names are unique
PASS Navigator includes NavigatorConcurrentHardware: member names are unique
PASS WakeLock interface: existence and properties of interface object
PASS WakeLock interface object length
PASS WakeLock interface object name
PASS WakeLock interface: existence and properties of interface prototype object
PASS WakeLock interface: existence and properties of interface prototype object's "constructor" property
PASS WakeLock interface: existence and properties of interface prototype object's @@unscopables property
PASS WakeLock interface: operation request(WakeLockType)
PASS WakeLock must be primary interface of navigator.wakeLock
PASS Stringification of navigator.wakeLock
PASS WakeLock interface: navigator.wakeLock must inherit property "request(WakeLockType)" with the proper type
PASS WakeLock interface: calling request(WakeLockType) on navigator.wakeLock with too few arguments must throw TypeError
PASS WakeLockSentinel interface: existence and properties of interface object
PASS WakeLockSentinel interface object length
PASS WakeLockSentinel interface object name
PASS WakeLockSentinel interface: existence and properties of interface prototype object
PASS WakeLockSentinel interface: existence and properties of interface prototype object's "constructor" property
PASS WakeLockSentinel interface: existence and properties of interface prototype object's @@unscopables property
FAIL WakeLockSentinel interface: attribute released assert_true: The prototype object must have a property "released" expected true got false
PASS WakeLockSentinel interface: attribute type
PASS WakeLockSentinel interface: operation release()
PASS WakeLockSentinel interface: attribute onrelease
PASS WakeLockSentinel must be primary interface of sentinel
PASS Stringification of sentinel
FAIL WakeLockSentinel interface: sentinel must inherit property "released" with the proper type assert_inherits: property "released" not found in prototype chain
PASS WakeLockSentinel interface: sentinel must inherit property "type" with the proper type
PASS WakeLockSentinel interface: sentinel must inherit property "release()" with the proper type
PASS WakeLockSentinel interface: sentinel must inherit property "onrelease" with the proper type
PASS Navigator interface: attribute wakeLock
PASS Navigator interface: navigator must inherit property "wakeLock" with the proper type
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Basic WakeLockSentinel.released functionality assert_false: lock.release must be false on creation expected false got undefined
FAIL The release attribute inside an event handler assert_false: lock.release must be false on creation expected false got undefined
Harness: the test ran to completion.
...@@ -7624,6 +7624,7 @@ interface WakeLock ...@@ -7624,6 +7624,7 @@ interface WakeLock
interface WakeLockSentinel : EventTarget interface WakeLockSentinel : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter onrelease getter onrelease
getter released
getter type getter type
method constructor method constructor
method release method release
......
...@@ -26,12 +26,18 @@ promise_test(async t => { ...@@ -26,12 +26,18 @@ promise_test(async t => {
const screenLock1 = await navigator.wakeLock.request('screen'); const screenLock1 = await navigator.wakeLock.request('screen');
const screenLock2 = await navigator.wakeLock.request('screen'); const screenLock2 = await navigator.wakeLock.request('screen');
assert_false(screenLock1.released);
assert_false(screenLock2.released);
const wait1 = new EventWatcher(t, screenLock1, 'release').wait_for('release'); const wait1 = new EventWatcher(t, screenLock1, 'release').wait_for('release');
const wait2 = new EventWatcher(t, screenLock2, 'release').wait_for('release'); const wait2 = new EventWatcher(t, screenLock2, 'release').wait_for('release');
await setMainWindowHidden(true); await setMainWindowHidden(true);
return Promise.all([wait1, wait2]); await Promise.all([wait1, wait2]);
assert_true(screenLock1.released);
assert_true(screenLock2.released);
}, "Screen wake locks are released when the document the page is hidden"); }, "Screen wake locks are released when the document the page is hidden");
</script> </script>
</body> </body>
......
...@@ -1687,6 +1687,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -1687,6 +1687,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] interface WakeLockSentinel : EventTarget [Worker] interface WakeLockSentinel : EventTarget
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] getter onrelease [Worker] getter onrelease
[Worker] getter released
[Worker] getter type [Worker] getter type
[Worker] method constructor [Worker] method constructor
[Worker] method release [Worker] method release
......
...@@ -8919,6 +8919,7 @@ interface WakeLock ...@@ -8919,6 +8919,7 @@ interface WakeLock
interface WakeLockSentinel : EventTarget interface WakeLockSentinel : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter onrelease getter onrelease
getter released
getter type getter type
method constructor method constructor
method release method release
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment