1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
// 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 "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/abort_signal.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_controller.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request_options.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
namespace {
Document* GetDocument(ScriptState* script_state) {
ExecutionContext* execution_context = ExecutionContext::From(script_state);
return To<Document>(execution_context);
}
} // namespace
// static
ScriptPromise WakeLock::request(ScriptState* script_state,
const String& type,
WakeLockRequestOptions* options) {
// https://w3c.github.io/wake-lock/#request-static-method
// We only support [Exposed=Window] for now.
DCHECK(ExecutionContext::From(script_state)->IsDocument());
// 2. Let document be the responsible document of the current settings object.
auto* document = GetDocument(script_state);
// 3. If the current global object is the DedicatedWorkerGlobalScope object:
// 3.1. If the current global object's owner set is empty, reject promise with
// a "NotAllowedError" DOMException and return promise.
// 3.2. If type is "screen", reject promise with a "NotAllowedError"
// DOMException, and return promise.
// 4. Otherwise, if the current global object is the Window object:
// 4.1. If the document's browsing context is null, reject promise with a
// "NotAllowedError" DOMException and return promise.
if (!document) {
return ScriptPromise::RejectWithDOMException(
script_state, MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
"The document has no associated browsing context"));
}
// 2.1. If document is not allowed to use the policy-controlled feature named
// "wake-lock", reject promise with a "NotAllowedError" DOMException and
// return promise.
// 2.2. If the user agent denies the wake lock of this type for document,
// reject promise with a "NotAllowedError" DOMException and return
// promise.
if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWakeLock,
ReportOptions::kReportOnFailure)) {
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
"Access to WakeLock features is disallowed by feature policy"));
}
// 4.2. If document is not fully active, reject promise with a
// "NotAllowedError" DOMException, and return promise.
if (!document->IsActive()) {
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError,
"The document is not active"));
}
// 4.3. If type is "screen" and the Document of the top-level browsing context
// is hidden, reject promise with a "NotAllowedError" DOMException, and
// return promise.
if (type == "screen" &&
!(document->GetPage() && document->GetPage()->IsPageVisible())) {
return ScriptPromise::RejectWithDOMException(
script_state, MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
"The requesting page is not visible"));
}
// 5. If options' signal member is present, then run the following steps:
// 5.1. Let signal be options's signal member.
// 5.2. If signal’s aborted flag is set, then reject promise with an
// "AbortError" DOMException and return promise.
if (options->hasSignal() && options->signal()->aborted()) {
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
WakeLockType wake_lock_type = ToWakeLockType(type);
WakeLockController& controller = WakeLockController::From(*document);
// 5.3. Otherwise, add to signal:
// 5.3.1. Run release a wake lock with promise and type.
if (options->hasSignal()) {
options->signal()->AddAlgorithm(WTF::Bind(
&WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller),
wake_lock_type, WrapPersistent(resolver)));
}
// 6. Run the following steps in parallel, but abort when options' signal
// member is present and its aborted flag is set:
// [...]
// 6.2. Let success be the result of awaiting acquire a wake lock with promise
// and type:
// 6.2.1. If success is false then reject promise with a "NotAllowedError"
// DOMException, and abort these steps.
controller.AcquireWakeLock(wake_lock_type, resolver);
// 7. Return promise.
return promise;
}
} // namespace blink
|