1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
9 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
10 #include "third_party/blink/renderer/core/dom/dom_exception.h"
11 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
12 #include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h"
13 #include "third_party/blink/renderer/platform/heap/handle.h"
14 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
15 #include "v8/include/v8.h"
16
17 namespace blink {
18
19 namespace {
20
MakeManager(WakeLockTestingContext & context,WakeLockType type)21 WakeLockManager* MakeManager(WakeLockTestingContext& context,
22 WakeLockType type) {
23 return MakeGarbageCollected<WakeLockManager>(context.DomWindow(), type);
24 }
25
26 } // namespace
27
TEST(WakeLockManagerTest,AcquireWakeLock)28 TEST(WakeLockManagerTest, AcquireWakeLock) {
29 MockWakeLockService wake_lock_service;
30 WakeLockTestingContext context(&wake_lock_service);
31 auto* manager = MakeManager(context, WakeLockType::kScreen);
32
33 MockWakeLock& screen_lock =
34 wake_lock_service.get_wake_lock(WakeLockType::kScreen);
35 EXPECT_FALSE(screen_lock.is_acquired());
36 EXPECT_FALSE(manager->wake_lock_.is_bound());
37
38 auto* resolver1 =
39 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
40 ScriptPromise promise1 = resolver1->Promise();
41 auto* resolver2 =
42 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
43 ScriptPromise promise2 = resolver2->Promise();
44
45 manager->AcquireWakeLock(resolver1);
46 manager->AcquireWakeLock(resolver2);
47 screen_lock.WaitForRequest();
48
49 context.WaitForPromiseFulfillment(promise1);
50 context.WaitForPromiseFulfillment(promise2);
51
52 auto* sentinel1 =
53 ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise1);
54 auto* sentinel2 =
55 ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise2);
56
57 EXPECT_TRUE(manager->wake_lock_sentinels_.Contains(sentinel1));
58 EXPECT_TRUE(manager->wake_lock_sentinels_.Contains(sentinel2));
59 EXPECT_EQ(2U, manager->wake_lock_sentinels_.size());
60 EXPECT_TRUE(screen_lock.is_acquired());
61 EXPECT_TRUE(manager->wake_lock_.is_bound());
62 }
63
TEST(WakeLockManagerTest,ReleaseAllWakeLocks)64 TEST(WakeLockManagerTest, ReleaseAllWakeLocks) {
65 MockWakeLockService wake_lock_service;
66 WakeLockTestingContext context(&wake_lock_service);
67 auto* manager = MakeManager(context, WakeLockType::kScreen);
68
69 MockWakeLock& screen_lock =
70 wake_lock_service.get_wake_lock(WakeLockType::kScreen);
71
72 auto* resolver =
73 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
74 ScriptPromise promise = resolver->Promise();
75
76 manager->AcquireWakeLock(resolver);
77 screen_lock.WaitForRequest();
78 context.WaitForPromiseFulfillment(promise);
79
80 EXPECT_EQ(1U, manager->wake_lock_sentinels_.size());
81 EXPECT_TRUE(screen_lock.is_acquired());
82
83 auto* sentinel =
84 ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise);
85
86 manager->UnregisterSentinel(sentinel);
87 screen_lock.WaitForCancelation();
88
89 EXPECT_EQ(0U, manager->wake_lock_sentinels_.size());
90 EXPECT_FALSE(screen_lock.is_acquired());
91 EXPECT_FALSE(manager->wake_lock_.is_bound());
92 }
93
TEST(WakeLockManagerTest,ReleaseOneWakeLock)94 TEST(WakeLockManagerTest, ReleaseOneWakeLock) {
95 MockWakeLockService wake_lock_service;
96 WakeLockTestingContext context(&wake_lock_service);
97 auto* manager = MakeManager(context, WakeLockType::kScreen);
98
99 MockWakeLock& screen_lock =
100 wake_lock_service.get_wake_lock(WakeLockType::kScreen);
101
102 auto* resolver1 =
103 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
104 ScriptPromise promise1 = resolver1->Promise();
105 auto* resolver2 =
106 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
107 ScriptPromise promise2 = resolver2->Promise();
108
109 manager->AcquireWakeLock(resolver1);
110 manager->AcquireWakeLock(resolver2);
111 screen_lock.WaitForRequest();
112
113 context.WaitForPromiseFulfillment(promise1);
114 context.WaitForPromiseFulfillment(promise2);
115
116 EXPECT_TRUE(screen_lock.is_acquired());
117 EXPECT_EQ(2U, manager->wake_lock_sentinels_.size());
118
119 auto* sentinel1 =
120 ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise1);
121 EXPECT_TRUE(manager->wake_lock_sentinels_.Contains(sentinel1));
122
123 manager->UnregisterSentinel(sentinel1);
124 EXPECT_FALSE(manager->wake_lock_sentinels_.Contains(sentinel1));
125 EXPECT_TRUE(manager->wake_lock_.is_bound());
126 EXPECT_EQ(1U, manager->wake_lock_sentinels_.size());
127 EXPECT_TRUE(screen_lock.is_acquired());
128 }
129
TEST(WakeLockManagerTest,ClearEmptyWakeLockSentinelList)130 TEST(WakeLockManagerTest, ClearEmptyWakeLockSentinelList) {
131 MockWakeLockService wake_lock_service;
132 WakeLockTestingContext context(&wake_lock_service);
133 auto* manager = MakeManager(context, WakeLockType::kSystem);
134
135 MockWakeLock& system_lock =
136 wake_lock_service.get_wake_lock(WakeLockType::kSystem);
137 EXPECT_FALSE(system_lock.is_acquired());
138
139 manager->ClearWakeLocks();
140 test::RunPendingTasks();
141
142 EXPECT_FALSE(system_lock.is_acquired());
143 }
144
TEST(WakeLockManagerTest,ClearWakeLocks)145 TEST(WakeLockManagerTest, ClearWakeLocks) {
146 MockWakeLockService wake_lock_service;
147 WakeLockTestingContext context(&wake_lock_service);
148 auto* manager = MakeManager(context, WakeLockType::kSystem);
149
150 auto* resolver1 =
151 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
152 ScriptPromise promise1 = resolver1->Promise();
153 auto* resolver2 =
154 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
155 ScriptPromise promise2 = resolver2->Promise();
156
157 MockWakeLock& system_lock =
158 wake_lock_service.get_wake_lock(WakeLockType::kSystem);
159
160 manager->AcquireWakeLock(resolver1);
161 manager->AcquireWakeLock(resolver2);
162 system_lock.WaitForRequest();
163 context.WaitForPromiseFulfillment(promise1);
164 context.WaitForPromiseFulfillment(promise2);
165
166 EXPECT_EQ(2U, manager->wake_lock_sentinels_.size());
167
168 manager->ClearWakeLocks();
169 system_lock.WaitForCancelation();
170
171 EXPECT_EQ(0U, manager->wake_lock_sentinels_.size());
172 EXPECT_FALSE(system_lock.is_acquired());
173 }
174
TEST(WakeLockManagerTest,WakeLockConnectionError)175 TEST(WakeLockManagerTest, WakeLockConnectionError) {
176 MockWakeLockService wake_lock_service;
177 WakeLockTestingContext context(&wake_lock_service);
178 auto* manager = MakeManager(context, WakeLockType::kSystem);
179
180 auto* resolver1 =
181 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
182 ScriptPromise promise1 = resolver1->Promise();
183 auto* resolver2 =
184 MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
185 ScriptPromise promise2 = resolver2->Promise();
186
187 MockWakeLock& system_lock =
188 wake_lock_service.get_wake_lock(WakeLockType::kSystem);
189
190 manager->AcquireWakeLock(resolver1);
191 manager->AcquireWakeLock(resolver2);
192 system_lock.WaitForRequest();
193 context.WaitForPromiseFulfillment(promise1);
194 context.WaitForPromiseFulfillment(promise2);
195
196 EXPECT_TRUE(manager->wake_lock_.is_bound());
197 EXPECT_EQ(2U, manager->wake_lock_sentinels_.size());
198
199 // Unbind and wait for the disconnection to reach |wake_lock_|'s
200 // disconnection handler.
201 system_lock.Unbind();
202 manager->wake_lock_.FlushForTesting();
203
204 EXPECT_EQ(0U, manager->wake_lock_sentinels_.size());
205 EXPECT_FALSE(manager->wake_lock_.is_bound());
206 EXPECT_FALSE(system_lock.is_acquired());
207 }
208
209 } // namespace blink
210