OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "base/command_line.h" | |
6 #include "base/test/test_timeouts.h" | |
7 #include "content/browser/wake_lock/wake_lock_service_context.h" | |
8 #include "content/browser/web_contents/web_contents_impl.h" | |
9 #include "content/public/common/content_switches.h" | |
10 #include "content/public/test/browser_test_utils.h" | |
11 #include "content/public/test/content_browser_test.h" | |
12 #include "content/public/test/content_browser_test_utils.h" | |
13 #include "content/public/test/test_utils.h" | |
14 #include "content/shell/browser/shell.h" | |
15 #include "content/test/content_browser_test_utils_internal.h" | |
16 #include "net/dns/mock_host_resolver.h" | |
17 #include "net/test/embedded_test_server/embedded_test_server.h" | |
18 | |
19 namespace content { | |
20 | |
21 class WakeLockTest : public ContentBrowserTest { | |
22 public: | |
23 void SetUpCommandLine(base::CommandLine* command_line) override { | |
24 command_line->AppendSwitch( | |
25 switches::kEnableExperimentalWebPlatformFeatures); | |
26 command_line->AppendSwitch(switches::kSitePerProcess); | |
27 } | |
28 | |
29 void SetUpOnMainThread() override { | |
30 host_resolver()->AddRule("*", "127.0.0.1"); | |
31 EXPECT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
32 } | |
33 | |
34 protected: | |
35 WebContents* GetWebContents() { | |
36 return shell()->web_contents(); | |
37 } | |
38 | |
39 WebContentsImpl* GetWebContentsImpl() { | |
40 return static_cast<WebContentsImpl*>(GetWebContents()); | |
41 } | |
42 | |
43 RenderFrameHost* GetMainFrame() { | |
44 return GetWebContents()->GetMainFrame(); | |
45 } | |
46 | |
47 FrameTreeNode* GetNestedFrameNode() { | |
48 FrameTreeNode* root = GetWebContentsImpl()->GetFrameTree()->root(); | |
49 CHECK(root->child_count() == 1); | |
50 return root->child_at(0); | |
51 } | |
52 | |
53 RenderFrameHost* GetNestedFrame() { | |
54 return GetNestedFrameNode()->current_frame_host(); | |
55 } | |
56 | |
57 WakeLockServiceContext* GetWakeLockServiceContext() { | |
58 return GetWebContentsImpl()->GetWakeLockServiceContext(); | |
59 } | |
60 | |
61 bool HasWakeLock() { | |
62 return GetWakeLockServiceContext()->HasWakeLockForTests(); | |
63 } | |
64 | |
65 void WaitForPossibleUpdate() { | |
66 // As Mojo channels have no common FIFO order in respect to each other and | |
67 // to the Chromium IPC, we cannot assume that when screen.keepAwake state | |
68 // is changed from within a script, WakeLockService will receive an update | |
69 // request before ExecuteScript() returns. Therefore, some time slack is | |
70 // needed to make sure that WakeLockService has received any possible update | |
71 // requests before checking the resulting wake lock state. | |
72 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
73 RunAllPendingInMessageLoop(); | |
74 } | |
75 | |
76 void ScreenWakeLockInMainFrame() { | |
77 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;")); | |
78 WaitForPossibleUpdate(); | |
79 EXPECT_TRUE(HasWakeLock()); | |
80 } | |
81 | |
82 bool EvaluateAsBool(const ToRenderFrameHost& adapter, | |
83 const std::string& expr) { | |
84 bool result; | |
85 CHECK(ExecuteScriptAndExtractBool( | |
86 adapter, | |
87 "window.domAutomationController.send(" + expr + ");", | |
88 &result)); | |
89 return result; | |
90 } | |
91 }; | |
92 | |
93 IN_PROC_BROWSER_TEST_F(WakeLockTest, WakeLockApiIsPresent) { | |
94 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
95 EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), | |
96 "typeof screen.keepAwake !== undefined")); | |
97 } | |
98 | |
99 IN_PROC_BROWSER_TEST_F(WakeLockTest, LockAndUnlockScreenInMainFrame) { | |
100 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
101 | |
102 // Should not have screen wake lock initially. | |
103 EXPECT_FALSE(HasWakeLock()); | |
104 | |
105 // Check attribute 'screen.keepAwake' in main frame. | |
106 EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake")); | |
107 | |
108 // Set keep awake flag in main frame. | |
109 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;")); | |
110 WaitForPossibleUpdate(); | |
111 | |
112 // Keep awake flag should be set in main frame. | |
113 EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake")); | |
114 | |
115 // Should create screen wake lock. | |
116 EXPECT_TRUE(HasWakeLock()); | |
117 | |
118 // Reset keep awake flag in main frame. | |
119 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;")); | |
120 WaitForPossibleUpdate(); | |
121 | |
122 // Keep awake flag should not be set in main frame. | |
123 EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake")); | |
124 | |
125 // Should release screen wake lock. | |
126 EXPECT_FALSE(HasWakeLock()); | |
127 } | |
128 | |
129 IN_PROC_BROWSER_TEST_F(WakeLockTest, MultipleLockThenUnlock) { | |
130 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
131 | |
132 // Set keep awake flag | |
133 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;")); | |
134 WaitForPossibleUpdate(); | |
135 | |
136 // Set keep awake flag again. | |
137 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;")); | |
138 WaitForPossibleUpdate(); | |
139 | |
140 // Screen should still be locked. | |
141 EXPECT_TRUE(HasWakeLock()); | |
142 | |
143 // Reset keep awake flag. | |
144 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;")); | |
145 WaitForPossibleUpdate(); | |
146 | |
147 // Should release screen wake lock. | |
148 EXPECT_FALSE(HasWakeLock()); | |
149 } | |
150 | |
151 IN_PROC_BROWSER_TEST_F(WakeLockTest, LockInMainFrameAndNestedFrame) { | |
152 NavigateToURL(shell(), | |
153 embedded_test_server()->GetURL("/frame_tree/2-4.html")); | |
154 EXPECT_FALSE(HasWakeLock()); | |
155 | |
156 // Lock screen in nested frame. | |
157 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
158 WaitForPossibleUpdate(); | |
159 | |
160 // Should create screen wake lock. | |
161 EXPECT_TRUE(HasWakeLock()); | |
162 | |
163 // screen.keepAwake should be false in the main frame. | |
164 EXPECT_FALSE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake")); | |
165 | |
166 // Lock screen in main frame. | |
167 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = true;")); | |
168 WaitForPossibleUpdate(); | |
169 | |
170 // screen.keepAwake should be true in the main frame. | |
171 EXPECT_TRUE(EvaluateAsBool(GetMainFrame(), "screen.keepAwake")); | |
172 | |
173 // Screen wake lock should not change. | |
174 EXPECT_TRUE(HasWakeLock()); | |
175 | |
176 // Unlock screen in nested frame. | |
177 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = false;")); | |
178 WaitForPossibleUpdate(); | |
179 | |
180 // Screen wake lock should be present, as the main frame is still requesting | |
181 // it. | |
182 EXPECT_TRUE(HasWakeLock()); | |
183 | |
184 // Unlock screen in main frame. | |
185 EXPECT_TRUE(ExecuteScript(GetMainFrame(), "screen.keepAwake = false;")); | |
186 WaitForPossibleUpdate(); | |
187 | |
188 // Screen wake lock should be released, as no frames are requesting it. | |
189 EXPECT_FALSE(HasWakeLock()); | |
190 } | |
191 | |
192 IN_PROC_BROWSER_TEST_F(WakeLockTest, FrameRemoved) { | |
193 NavigateToURL(shell(), | |
194 embedded_test_server()->GetURL("/frame_tree/2-4.html")); | |
195 EXPECT_FALSE(HasWakeLock()); | |
196 | |
197 // Lock screen in nested frame. | |
198 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
199 WaitForPossibleUpdate(); | |
200 | |
201 EXPECT_TRUE(HasWakeLock()); | |
202 | |
203 // Remove nested frame. | |
204 EXPECT_TRUE(ExecuteScript( | |
205 GetMainFrame(), | |
206 "var iframe = document.getElementById('3-1-id');" | |
207 "iframe.parentNode.removeChild(iframe);")); | |
208 | |
209 // Screen wake lock should be released. | |
210 EXPECT_FALSE(HasWakeLock()); | |
211 } | |
212 | |
213 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterTabCrashed) { | |
214 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
215 ScreenWakeLockInMainFrame(); | |
216 | |
217 // Crash the tab. | |
218 CrashTab(GetWebContents()); | |
219 | |
220 // Screen wake lock should be released. | |
221 EXPECT_FALSE(HasWakeLock()); | |
222 } | |
223 | |
224 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigation) { | |
225 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
226 ScreenWakeLockInMainFrame(); | |
227 | |
228 // Navigate to a different document. | |
229 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); | |
230 | |
231 // Screen wake lock should be released after navigation. | |
232 EXPECT_FALSE(HasWakeLock()); | |
233 } | |
234 | |
235 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterNavigationToSelf) { | |
236 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
237 ScreenWakeLockInMainFrame(); | |
238 | |
239 // Navigate to the same document. | |
240 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
241 | |
242 // Screen wake lock should be released after navigation to the same URL. | |
243 EXPECT_FALSE(HasWakeLock()); | |
244 } | |
245 | |
246 IN_PROC_BROWSER_TEST_F(WakeLockTest, KeepLockAfterInPageNavigation) { | |
247 GURL test_url( | |
248 embedded_test_server()->GetURL("/session_history/fragment.html")); | |
249 GURL test_in_page_url(test_url.spec() + "#a"); | |
250 | |
251 NavigateToURL(shell(), test_url); | |
252 ScreenWakeLockInMainFrame(); | |
253 | |
254 NavigateToURL(shell(), test_in_page_url); | |
255 EXPECT_TRUE(HasWakeLock()); | |
256 } | |
257 | |
258 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterReload) { | |
259 NavigateToURL(shell(), embedded_test_server()->GetURL("/simple_page.html")); | |
260 ScreenWakeLockInMainFrame(); | |
261 | |
262 shell()->Reload(); | |
263 WaitForLoadStop(GetWebContents()); | |
264 | |
265 // Screen wake lock should be released after reload. | |
266 EXPECT_FALSE(HasWakeLock()); | |
267 } | |
268 | |
269 IN_PROC_BROWSER_TEST_F(WakeLockTest, BrowserInitiatedFrameNavigation) { | |
270 NavigateToURL(shell(), | |
271 embedded_test_server()->GetURL("/frame_tree/2-4.html")); | |
272 | |
273 EXPECT_FALSE(HasWakeLock()); | |
274 | |
275 // Lock screen in nested frame. | |
276 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
277 WaitForPossibleUpdate(); | |
278 | |
279 // Screen wake lock should be present. | |
280 EXPECT_TRUE(HasWakeLock()); | |
281 | |
282 // Navigate the nested frame (browser-initiated). | |
283 NavigateFrameToURL(GetNestedFrameNode(), | |
284 embedded_test_server()->GetURL("/simple_page.html")); | |
285 WaitForPossibleUpdate(); | |
286 | |
287 // Screen wake lock should be released. | |
288 EXPECT_FALSE(HasWakeLock()); | |
289 } | |
290 | |
291 IN_PROC_BROWSER_TEST_F(WakeLockTest, RendererInitiatedFrameNavigation) { | |
292 NavigateToURL(shell(), | |
293 embedded_test_server()->GetURL("/frame_tree/2-4.html")); | |
294 | |
295 EXPECT_FALSE(HasWakeLock()); | |
296 | |
297 // Lock screen in nested frame. | |
298 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
299 WaitForPossibleUpdate(); | |
300 | |
301 // Screen wake lock should be present. | |
302 EXPECT_TRUE(HasWakeLock()); | |
303 | |
304 // Navigate the nested frame (renderer-initiated). | |
305 NavigateIframeToURL(GetWebContents(), | |
306 "3-1-id", | |
307 embedded_test_server()->GetURL("/simple_page.html")); | |
308 WaitForPossibleUpdate(); | |
309 | |
310 // Screen wake lock should be released. | |
311 EXPECT_FALSE(HasWakeLock()); | |
312 } | |
313 | |
314 IN_PROC_BROWSER_TEST_F(WakeLockTest, OutOfProcessFrame) { | |
315 NavigateToURL(shell(), | |
316 embedded_test_server()->GetURL("a.com", | |
317 "/cross_site_iframe_factory.html?a(a)")); | |
318 EXPECT_FALSE(HasWakeLock()); | |
319 | |
320 // Ensure that the nested frame is same-process. | |
321 EXPECT_FALSE(GetNestedFrame()->IsCrossProcessSubframe()); | |
322 | |
323 // Lock screen in same-site nested frame. | |
324 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
325 WaitForPossibleUpdate(); | |
326 EXPECT_TRUE(HasWakeLock()); | |
327 | |
328 // Navigate nested frame to a cross-site document. | |
329 NavigateFrameToURL(GetNestedFrameNode(), | |
330 embedded_test_server()->GetURL("b.com", | |
331 "/simple_page.html")); | |
332 WaitForPossibleUpdate(); | |
333 | |
334 // Ensure that a new process has been created for the nested frame. | |
335 EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe()); | |
336 | |
337 // Screen wake lock should be released. | |
338 EXPECT_FALSE(HasWakeLock()); | |
339 | |
340 // Lock screen in the cross-site nested frame. | |
341 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
342 WaitForPossibleUpdate(); | |
343 | |
344 // Screen wake lock should be created. | |
345 EXPECT_TRUE(HasWakeLock()); | |
346 } | |
347 | |
348 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashOutOfProcessFrame) { | |
349 // Load a page with cross-site iframe. | |
350 NavigateToURL(shell(), | |
351 embedded_test_server()->GetURL("a.com", | |
352 "/cross_site_iframe_factory.html?a(b)")); | |
353 EXPECT_FALSE(HasWakeLock()); | |
354 | |
355 // Ensure that a new process has been created for the nested frame. | |
356 EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe()); | |
357 | |
358 // Lock screen in cross-site nested frame. | |
359 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
360 WaitForPossibleUpdate(); | |
361 EXPECT_TRUE(HasWakeLock()); | |
362 | |
363 // Crash process that owns the out-of-process frame. | |
364 RenderProcessHostWatcher watcher( | |
365 GetNestedFrame()->GetProcess(), | |
366 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | |
367 GetNestedFrame()->GetProcess()->Shutdown(0, false); | |
368 watcher.Wait(); | |
369 | |
370 // Screen wake lock should be released. | |
371 EXPECT_FALSE(HasWakeLock()); | |
372 } | |
373 | |
374 } // namespace content | |
OLD | NEW |