Commit a4fd427d authored by Mrunal Kapade's avatar Mrunal Kapade Committed by Commit Bot

Wake Lock API: Implement Screen WakeLock based on Promises.

This patch implements navigator.getWakeLock(WakeLockType) and other
necessary interfaces such as WakeLock and WakeLockRequest to provide
acesss to Screen wakelock for now. Latest WakeLock API spec can be
seen here, https://www.w3.org/TR/wake-lock.

Intent to Implement,
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/KMNZmMF1_H4

Bug: 257511
Change-Id: I7fa4d0f7f287d7497b48f583e18e0ca5ca39e662
Reviewed-on: https://chromium-review.googlesource.com/918062
Commit-Queue: Mrunal Kapade <mrunal.kapade@intel.com>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584239}
parent e6a59a6b
...@@ -4994,4 +4994,9 @@ crbug.com/869726 [ Mac ] virtual/scroll_customization/fast/events/touch/touch-la ...@@ -4994,4 +4994,9 @@ crbug.com/869726 [ Mac ] virtual/scroll_customization/fast/events/touch/touch-la
crbug.com/874703 [ Mac ] http/tests/devtools/extensions/extensions-panel.js [ Timeout Pass ] crbug.com/874703 [ Mac ] http/tests/devtools/extensions/extensions-panel.js [ Timeout Pass ]
# This won't pass until the bug fixed. # This won't pass until the bug fixed.
crbug.com/875287 fast/frames/crash-frameset-CSS-content-property.html [ Crash ] crbug.com/875287 fast/frames/crash-frameset-CSS-content-property.html [ Crash ]
\ No newline at end of file
# Wake Lock api test timeouts
crbug.com/872530 external/wpt/wake-lock/wakelock-applicability-manual.https.html [ Pass Timeout ]
crbug.com/872530 external/wpt/wake-lock/wakelock-document-hidden.https.html [ Pass Timeout ]
crbug.com/872535 external/wpt/wake-lock/wakelock-state-is-global.https.html [ Pass Timeout ]
\ No newline at end of file
This is a testharness.js-based test.
PASS Test IDL implementation of WakeLock API
PASS Partial interface Navigator: original interface defined
FAIL WakeLock interface: existence and properties of interface object assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface object length assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface object name assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: attribute type assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: attribute active assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: attribute onactivechange assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock interface: operation createRequest() assert_own_property: self does not have own property "WakeLock" expected property "WakeLock" missing
FAIL WakeLock must be primary interface of wakelock assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL Stringification of wakelock assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL WakeLock interface: wakelock must inherit property "type" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL WakeLock interface: wakelock must inherit property "active" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL WakeLock interface: wakelock must inherit property "onactivechange" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL WakeLock interface: wakelock must inherit property "createRequest()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: wakelock is not defined"
FAIL WakeLockRequest interface: existence and properties of interface object assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface object length assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface object name assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest interface: operation cancel() assert_own_property: self does not have own property "WakeLockRequest" expected property "WakeLockRequest" missing
FAIL WakeLockRequest must be primary interface of request assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: request is not defined"
FAIL Stringification of request assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: request is not defined"
FAIL WakeLockRequest interface: request must inherit property "cancel()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: request is not defined"
FAIL Navigator interface: operation getWakeLock(WakeLockType) assert_own_property: interface prototype object missing non-static operation expected property "getWakeLock" missing
FAIL Navigator interface: navigator must inherit property "getWakeLock(WakeLockType)" with the proper type assert_inherits: property "getWakeLock" not found in prototype chain
FAIL Navigator interface: calling getWakeLock(WakeLockType) on navigator with too few arguments must throw TypeError assert_inherits: property "getWakeLock" not found in prototype chain
PASS WorkerNavigator interface: existence and properties of interface object
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Test IDL implementation of WakeLock API promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Test that the Wake Lock API is correct assert_true: Wake Lock API is present expected true got false
Harness: the test ran to completion.
...@@ -12,7 +12,7 @@ promise_test(async t => { ...@@ -12,7 +12,7 @@ promise_test(async t => {
const wakeLock = await navigator.getWakeLock("screen"); const wakeLock = await navigator.getWakeLock("screen");
const request = wakeLock.createRequest(); const request = wakeLock.createRequest();
assert_true(wakeLock instanceof WakeLock, "wakeLock is a WakeLock"); assert_true(wakeLock instanceof WakeLock, "wakeLock is a WakeLock");
assert_true(wakeLock.type instanceof WakeLockType, "wakeLock.type is a WakeLockType"); assert_equals(typeof wakeLock.type, "string", "the type of wakeLock.type is string");
assert_equals(typeof wakeLock.active, "boolean", "the type of wakeLock.active is boolean"); assert_equals(typeof wakeLock.active, "boolean", "the type of wakeLock.active is boolean");
assert_true(request instanceof WakeLockRequest, "request is a WakeLockRequest"); assert_true(request instanceof WakeLockRequest, "request is a WakeLockRequest");
}, "Test that the Wake Lock API is correct"); }, "Test that the Wake Lock API is correct");
......
This is a testharness.js-based test.
FAIL The screen wake lock isn't applicable after the screen is manually swiched off by the user until it is switched on again. promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
FAIL Manually switching off the screen will not affect the applicability of the system wake lock. promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL no exception is thrown when invoking cancel() twice promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL Feature-Policy header {"wake-lock" : []} disallows the top-level document. navigator.getWakeLock is not a function FAIL Feature-Policy header {"wake-lock" : []} disallows the top-level document. assert_unreached: Should have rejected: undefined Reached unreachable code
PASS Feature-Policy header {"wake-lock" : []} disallows same-origin iframes. FAIL Feature-Policy header {"wake-lock" : []} disallows same-origin iframes. assert_false: navigator.getWakeLock("screen") expected false got true
PASS Feature-Policy header {"wake-lock" : []} disallows cross-origin iframes. FAIL Feature-Policy header {"wake-lock" : []} disallows cross-origin iframes. assert_false: navigator.getWakeLock("screen") expected false got true
Harness: the test ran to completion. Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Test that screen wake lock will not be actived in hidden document promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL Feature-Policy allow="wake-lock" allows same-origin relocation assert_true: navigator.getWakeLock("screen") expected true got false PASS Feature-Policy allow="wake-lock" allows same-origin relocation
PASS Feature-Policy allow="wake-lock" disallows cross-origin relocation FAIL Feature-Policy allow="wake-lock" disallows cross-origin relocation assert_false: navigator.getWakeLock("screen") expected false got true
Harness: the test ran to completion. Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Feature policy "wake-lock" can be enabled in same-origin iframe using allow="wake-lock" attribute assert_true: navigator.getWakeLock("screen") expected true got false
FAIL Feature policy "wake-lock" can be enabled in cross-origin iframe using allow="wake-lock" attribute assert_true: navigator.getWakeLock("screen") expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Feature-Policy header {"wake-lock" : ["*"]} allows the top-level document. navigator.getWakeLock is not a function
FAIL Feature-Policy header {"wake-lock" : ["*"]} allows same-origin iframes. assert_true: navigator.getWakeLock("screen") expected true got false
FAIL Feature-Policy header {"wake-lock" : ["*"]} allows cross-origin iframes. assert_true: navigator.getWakeLock("screen") expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL Feature-Policy header wake-lock "self" allows the top-level document. navigator.getWakeLock is not a function FAIL Feature-Policy header wake-lock "self" allows the top-level document. assert_not_equals: got disallowed value undefined
FAIL Feature-Policy header wake-lock "self" allows same-origin iframes. assert_true: navigator.getWakeLock("screen") expected true got false PASS Feature-Policy header wake-lock "self" allows same-origin iframes.
PASS Feature-Policy header wake-lock "self" disallows cross-origin iframes. FAIL Feature-Policy header wake-lock "self" disallows cross-origin iframes. assert_false: navigator.getWakeLock("screen") expected false got true
Harness: the test ran to completion. Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Test that 'activechange' event is fire and wakeLock.active is valid promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL navigator.getWakeLock() for the same Document always return same WakeLock promise promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Test that wake lock state should be global promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL Test that wakeLock.type is 'screen' when screen wake lock is invoked promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function" PASS Test that wakeLock.type is 'screen' when screen wake lock is invoked
FAIL Test that wakeLock.type is 'system' when system wake lock is invoked promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function" FAIL Test that wakeLock.type is 'system' when system wake lock is invoked promise_test: Unhandled rejection with value: object "NotSupportedError: WakeLockType Not Supported"
FAIL 'NotSupportedError' is thrown when set an empty wake lock type navigator.getWakeLock is not a function PASS 'TypeError' is thrown when set an empty wake lock type
FAIL 'NotSupportedError' is thrown when set an unsupported wake lock type navigator.getWakeLock is not a function PASS 'TypeError' is thrown when set an unsupported wake lock type
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -18,11 +18,11 @@ promise_test(async t => { ...@@ -18,11 +18,11 @@ promise_test(async t => {
}, "Test that wakeLock.type is 'system' when system wake lock is invoked"); }, "Test that wakeLock.type is 'system' when system wake lock is invoked");
promise_test(t => { promise_test(t => {
return promise_rejects(t, new DOMException("", "NotSupportedError"), navigator.getWakeLock()); return promise_rejects(t, new TypeError(), navigator.getWakeLock());
}, "'NotSupportedError' is thrown when set an empty wake lock type"); }, "'TypeError' is thrown when set an empty wake lock type");
promise_test(t => { promise_test(t => {
return promise_rejects(t, new DOMException("", "NotSupportedError"), navigator.getWakeLock("unsupported")); return promise_rejects(t, new TypeError(), navigator.getWakeLock("unsupported"));
}, "'NotSupportedError' is thrown when set an unsupported wake lock type"); }, "'TypeError' is thrown when set an unsupported wake lock type");
</script> </script>
This is a testharness.js-based test.
FAIL Test that the WakeLockRequest object is independent. promise_test: Unhandled rejection with value: object "TypeError: navigator.getWakeLock is not a function"
Harness: the test ran to completion.
...@@ -4687,6 +4687,7 @@ interface Navigator ...@@ -4687,6 +4687,7 @@ interface Navigator
method getInstalledRelatedApps method getInstalledRelatedApps
method getUserMedia method getUserMedia
method getVRDisplays method getVRDisplays
method getWakeLock
method javaEnabled method javaEnabled
method registerProtocolHandler method registerProtocolHandler
method requestMIDIAccess method requestMIDIAccess
...@@ -7643,6 +7644,18 @@ interface VisualViewport : EventTarget ...@@ -7643,6 +7644,18 @@ interface VisualViewport : EventTarget
method constructor method constructor
setter onresize setter onresize
setter onscroll setter onscroll
interface WakeLock : EventTarget
attribute @@toStringTag
getter active
getter onactivechange
getter type
method constructor
method createRequest
setter onactivechange
interface WakeLockRequest
attribute @@toStringTag
method cancel
method constructor
interface WaveShaperNode : AudioNode interface WaveShaperNode : AudioNode
attribute @@toStringTag attribute @@toStringTag
getter curve getter curve
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"activate", "activate",
"activateinvisible", "activateinvisible",
"active", "active",
"activechange",
"addsourcebuffer", "addsourcebuffer",
"addstream", "addstream",
"addtrack", "addtrack",
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
"modules/speech/SpeechSynthesis", "modules/speech/SpeechSynthesis",
"modules/speech/SpeechSynthesisUtterance", "modules/speech/SpeechSynthesisUtterance",
"modules/vr/VRDisplay", "modules/vr/VRDisplay",
"modules/wake_lock/WakeLock",
"modules/wake_lock/WakeLockRequest",
"modules/webaudio/AudioContext", "modules/webaudio/AudioContext",
"modules/webaudio/AudioNode", "modules/webaudio/AudioNode",
"modules/webmidi/MIDIAccess", "modules/webmidi/MIDIAccess",
......
...@@ -305,6 +305,8 @@ modules_idl_files = ...@@ -305,6 +305,8 @@ modules_idl_files =
"vr/vr_frame_data.idl", "vr/vr_frame_data.idl",
"vr/vr_pose.idl", "vr/vr_pose.idl",
"vr/vr_stage_parameters.idl", "vr/vr_stage_parameters.idl",
"wake_lock/wake_lock.idl",
"wake_lock/wake_lock_request.idl",
"webaudio/analyser_node.idl", "webaudio/analyser_node.idl",
"webaudio/audio_buffer.idl", "webaudio/audio_buffer.idl",
"webaudio/audio_buffer_source_node.idl", "webaudio/audio_buffer_source_node.idl",
...@@ -772,6 +774,7 @@ modules_dependency_idl_files = ...@@ -772,6 +774,7 @@ modules_dependency_idl_files =
"storage/window_storage.idl", "storage/window_storage.idl",
"vibration/navigator_vibration.idl", "vibration/navigator_vibration.idl",
"vr/navigator_vr.idl", "vr/navigator_vr.idl",
"wake_lock/navigator_wake_lock.idl",
"wake_lock/screen_wake_lock.idl", "wake_lock/screen_wake_lock.idl",
"webdatabase/window_web_database.idl", "webdatabase/window_web_database.idl",
"webgl/webgl2_rendering_context_base.idl", "webgl/webgl2_rendering_context_base.idl",
......
...@@ -6,7 +6,18 @@ import("//third_party/blink/renderer/modules/modules.gni") ...@@ -6,7 +6,18 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("wake_lock") { blink_modules_sources("wake_lock") {
sources = [ sources = [
"navigator_wake_lock.cc",
"navigator_wake_lock.h",
"screen_wake_lock.cc", "screen_wake_lock.cc",
"screen_wake_lock.h", "screen_wake_lock.h",
"wake_lock.cc",
"wake_lock.h",
"wake_lock_request.cc",
"wake_lock_request.h",
]
deps = [
"//mojo/public/cpp/bindings",
"//services/service_manager/public/cpp",
"//third_party/blink/renderer/platform",
] ]
} }
include_rules = [ include_rules = [
"+mojo/public/cpp/bindings", "+mojo/public/cpp/bindings",
"+services/device/public/mojom", "+services/device/public/mojom",
"+services/device/public/interfaces/constants.mojom-blink.h",
"+services/device/public/mojom/wake_lock.mojom-blink.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
] ]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
namespace blink {
// static
const char NavigatorWakeLock::kSupplementName[] = "NavigatorWakeLock";
NavigatorWakeLock::NavigatorWakeLock(Navigator& navigator)
: Supplement<Navigator>(navigator) {}
// static
ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
Navigator& navigator,
String lock_type) {
return NavigatorWakeLock::From(navigator).getWakeLock(script_state,
lock_type);
}
ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
String lock_type) {
// TODO(crbug.com/873030): Handle 'system' Wake Lock
if (lock_type == "screen") {
if (!wake_lock_screen_)
wake_lock_screen_ = WakeLock::CreateScreenWakeLock(script_state);
return wake_lock_screen_->GetPromise(script_state);
}
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError,
"WakeLockType Not Supported"));
}
NavigatorWakeLock& NavigatorWakeLock::From(Navigator& navigator) {
NavigatorWakeLock* supplement =
Supplement<Navigator>::From<NavigatorWakeLock>(navigator);
if (!supplement) {
supplement = new NavigatorWakeLock(navigator);
ProvideTo(navigator, supplement);
}
return *supplement;
}
void NavigatorWakeLock::Trace(blink::Visitor* visitor) {
visitor->Trace(wake_lock_screen_);
Supplement<Navigator>::Trace(visitor);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
class Navigator;
class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>,
public Supplement<Navigator> {
USING_GARBAGE_COLLECTED_MIXIN(NavigatorWakeLock);
public:
static const char kSupplementName[];
static NavigatorWakeLock& From(Navigator&);
static ScriptPromise getWakeLock(ScriptState*, Navigator&, String);
void Trace(blink::Visitor*) override;
private:
ScriptPromise getWakeLock(ScriptState*, String);
explicit NavigatorWakeLock(Navigator&);
Member<WakeLock> wake_lock_screen_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://www.w3.org/TR/wake-lock
[
SecureContext,
Exposed=Window,
ImplementedAs=NavigatorWakeLock,
RuntimeEnabled=WakeLockNavigator
] partial interface Navigator {
[CallWith=ScriptState] Promise getWakeLock(WakeLockType type);
};
\ No newline at end of file
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
#include "services/device/public/mojom/constants.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
WakeLock* WakeLock::CreateScreenWakeLock(ScriptState* script_state) {
return new WakeLock(script_state, LockType::kScreen);
}
WakeLock::~WakeLock() = default;
WakeLock::WakeLock(ScriptState* script_state, LockType type)
: ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
PageVisibilityObserver(
ToDocument(blink::ExecutionContext::From(script_state))->GetPage()),
type_(type) {
DCHECK(type == LockType::kScreen);
}
ScriptPromise WakeLock::GetPromise(ScriptState* script_state) {
if (!wake_lock_property_) {
wake_lock_property_ = new WakeLockProperty(
ExecutionContext::From(script_state), this, WakeLockProperty::kReady);
wake_lock_property_->Resolve(this);
}
return wake_lock_property_->Promise(script_state->World());
}
AtomicString WakeLock::type() const {
switch (type_) {
case LockType::kSystem:
return "system";
case LockType::kScreen:
return "screen";
}
NOTREACHED();
return AtomicString();
}
bool WakeLock::active() const {
return active_;
}
void WakeLock::OnConnectionError() {
wake_lock_service_.reset();
}
void WakeLock::ChangeActiveStatus(bool active) {
if (active_ == active)
return;
BindToServiceIfNeeded();
if (active)
wake_lock_service_->RequestWakeLock();
else
wake_lock_service_->CancelWakeLock();
active_ = active;
EnqueueEvent(*Event::Create(EventTypeNames::activechange),
TaskType::kMiscPlatformAPI);
}
void WakeLock::BindToServiceIfNeeded() {
if (wake_lock_service_)
return;
LocalFrame* frame = ToDocument(GetExecutionContext())->GetFrame();
frame->GetInterfaceProvider().GetInterface(
mojo::MakeRequest(&wake_lock_service_));
wake_lock_service_.set_connection_error_handler(
WTF::Bind(&WakeLock::OnConnectionError, WrapWeakPersistent(this)));
}
WakeLockRequest* WakeLock::createRequest() {
if (!active_ && request_counter_ == 0)
ChangeActiveStatus(true);
request_counter_++;
return new WakeLockRequest(this);
}
void WakeLock::CancelRequest() {
DCHECK_GT(request_counter_, 0);
if (active_ && request_counter_ == 1)
ChangeActiveStatus(false);
request_counter_--;
}
const WTF::AtomicString& WakeLock::InterfaceName() const {
return EventTargetNames::WakeLock;
}
ExecutionContext* WakeLock::GetExecutionContext() const {
return ContextLifecycleObserver::GetExecutionContext();
}
bool WakeLock::HasPendingActivity() const {
// Prevent V8 from garbage collecting the wrapper object if there are
// event listeners attached to it.
return GetExecutionContext() && HasEventListeners();
}
void WakeLock::ContextDestroyed(ExecutionContext*) {
ChangeActiveStatus(false);
}
void WakeLock::PageVisibilityChanged() {
ChangeActiveStatus(GetPage() && GetPage()->IsPageVisible());
}
void WakeLock::Trace(blink::Visitor* visitor) {
visitor->Trace(wake_lock_property_);
EventTargetWithInlineData::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_
#include "services/device/public/mojom/wake_lock.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class WakeLockRequest;
class WakeLock final : public EventTargetWithInlineData,
public ActiveScriptWrappable<WakeLock>,
public ContextLifecycleObserver,
public PageVisibilityObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(WakeLock);
public:
~WakeLock() override;
// wake_lock.idl implementation
AtomicString type() const;
bool active() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(activechange);
WakeLockRequest* createRequest();
// Called by NavigatorWakeLock to create Screen Wake Lock
static WakeLock* CreateScreenWakeLock(ScriptState*);
// Resolves and returns same promise of that particular WakeLockType each time
ScriptPromise GetPromise(ScriptState*);
// EventTarget overrides.
const WTF::AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const final;
// ContextLifecycleObserver overrides.
void ContextDestroyed(ExecutionContext*) override;
// PageVisibilityObserver overrides.
void PageVisibilityChanged() override;
void Trace(blink::Visitor*) override;
// Called by WakeLockRequest to decrease the request counter by one
void CancelRequest();
private:
enum class LockType { kSystem, kScreen };
WakeLock(ScriptState*, LockType);
// Error handler in case of failure to connect to Wake Lock mojo service
void OnConnectionError();
// Depending on active_ status change, requests or cancels Wake Lock
void ChangeActiveStatus(bool);
// Binds to the Wake Lock mojo service
void BindToServiceIfNeeded();
device::mojom::blink::WakeLockPtr wake_lock_service_;
int request_counter_ = 0;
LockType type_;
bool active_ = false;
// We use ScriptPromiseProperty instead of ScriptPromiseResolver or other
// mechanism because we need to return same promise of that WakeLockType for
// any subsequent calls to navigator.getWakeLock(WakeLockType).
using WakeLockProperty = ScriptPromiseProperty<Member<WakeLock>,
Member<WakeLock>,
Member<DOMException>>;
Member<WakeLockProperty> wake_lock_property_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
enum WakeLockType {
"screen",
"system"
};
// https://www.w3.org/TR/wake-lock
[
ActiveScriptWrappable,
SecureContext,
Exposed=Window,
RuntimeEnabled=WakeLockNavigator
] interface WakeLock : EventTarget {
readonly attribute WakeLockType type;
readonly attribute boolean active;
attribute EventHandler onactivechange;
WakeLockRequest createRequest();
};
\ No newline at end of file
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request.h"
namespace blink {
WakeLockRequest::WakeLockRequest(WakeLock* wake_lock)
: owner_wake_lock_(wake_lock) {}
WakeLockRequest::~WakeLockRequest() = default;
void WakeLockRequest::cancel() {
if (cancelled_)
return;
cancelled_ = true;
owner_wake_lock_->CancelRequest();
}
void WakeLockRequest::Trace(blink::Visitor* visitor) {
visitor->Trace(owner_wake_lock_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
class WakeLockRequest final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
explicit WakeLockRequest(WakeLock*);
~WakeLockRequest() override;
void Trace(blink::Visitor*) override;
void cancel();
private:
Member<WakeLock> owner_wake_lock_;
bool cancelled_ = false;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://www.w3.org/TR/wake-lock
[
SecureContext,
Exposed=Window,
RuntimeEnabled=WakeLockNavigator
] interface WakeLockRequest {
void cancel();
};
\ No newline at end of file
...@@ -1235,6 +1235,10 @@ ...@@ -1235,6 +1235,10 @@
name: "WakeLock", name: "WakeLock",
status: "experimental", status: "experimental",
}, },
{
name: "WakeLockNavigator",
status: "experimental",
},
{ {
name: "WebAnimationsAPI", name: "WebAnimationsAPI",
status: "experimental", status: "experimental",
......
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