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