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()); | |
nasko
2015/09/02 22:40:14
Is it possible to structure this some other way? W
alogvinov
2015/09/03 16:25:00
I am aware of that, but I cannot think of a way ho
| |
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("/wake_lock/page_with_iframe.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("/wake_lock/page_with_iframe.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('nested_frame');" | |
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("/wake_lock/page_with_iframe.html")); | |
249 GURL test_in_page_url(test_url.spec() + "#anchor"); | |
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("/wake_lock/page_with_iframe.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 | |
286 // Screen wake lock should be released. | |
287 EXPECT_FALSE(HasWakeLock()); | |
288 } | |
289 | |
290 IN_PROC_BROWSER_TEST_F(WakeLockTest, RendererInitiatedFrameNavigation) { | |
291 NavigateToURL(shell(), | |
292 embedded_test_server()->GetURL("/wake_lock/page_with_iframe.html")); | |
293 | |
294 EXPECT_FALSE(HasWakeLock()); | |
295 | |
296 // Lock screen in nested frame. | |
297 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
298 WaitForPossibleUpdate(); | |
299 | |
300 // Screen wake lock should be present. | |
301 EXPECT_TRUE(HasWakeLock()); | |
302 | |
303 // Navigate the nested frame (renderer-initiated). | |
304 NavigateIframeToURL(GetWebContents(), | |
305 "nested_frame", | |
306 embedded_test_server()->GetURL("/simple_page.html")); | |
307 WaitForPossibleUpdate(); | |
308 | |
309 // Screen wake lock should be released. | |
310 EXPECT_FALSE(HasWakeLock()); | |
311 } | |
312 | |
313 IN_PROC_BROWSER_TEST_F(WakeLockTest, OutOfProcessFrame) { | |
nasko
2015/09/02 22:40:14
Thanks for adding this test case!
| |
314 NavigateToURL(shell(), | |
315 embedded_test_server()->GetURL("/wake_lock/page_with_iframe.html")); | |
nasko
2015/09/02 22:40:14
There are already a bunch of test files that have
alogvinov
2015/09/03 16:25:00
Done.
| |
316 EXPECT_FALSE(HasWakeLock()); | |
317 | |
318 // Lock screen in same-site nested frame. | |
319 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
320 WaitForPossibleUpdate(); | |
321 EXPECT_TRUE(HasWakeLock()); | |
322 | |
323 // Navigate nested frame to a cross-site document. | |
324 NavigateFrameToURL(GetNestedFrameNode(), | |
325 embedded_test_server()->GetURL("foo.com", | |
326 "/simple_page.html")); | |
327 | |
328 // Ensure that a new process has been created for the subframe. | |
329 EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe()); | |
330 | |
331 // Screen wake lock should be released. | |
332 EXPECT_FALSE(HasWakeLock()); | |
333 | |
334 // Lock screen in the cross-site nested frame. | |
335 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
336 WaitForPossibleUpdate(); | |
337 | |
338 // Screen wake lock should be created. | |
339 EXPECT_TRUE(HasWakeLock()); | |
340 } | |
341 | |
342 IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashOutOfProcessFrame) { | |
343 NavigateToURL(shell(), | |
344 embedded_test_server()->GetURL("/wake_lock/page_with_iframe.html")); | |
345 EXPECT_FALSE(HasWakeLock()); | |
346 | |
347 // Load cross-site page into the nested frame. | |
348 NavigateFrameToURL(GetNestedFrameNode(), | |
349 embedded_test_server()->GetURL("foo.com", | |
350 "/simple_page.html")); | |
351 | |
352 // Ensure that a new process has been created for the nested frame. | |
353 EXPECT_TRUE(GetNestedFrame()->IsCrossProcessSubframe()); | |
354 | |
355 // Lock screen in cross-site nested frame. | |
356 EXPECT_TRUE(ExecuteScript(GetNestedFrame(), "screen.keepAwake = true;")); | |
357 WaitForPossibleUpdate(); | |
358 EXPECT_TRUE(HasWakeLock()); | |
359 | |
360 // Crash process that owns the out-of-process frame. | |
361 RenderProcessHostWatcher watcher( | |
362 GetNestedFrame()->GetProcess(), | |
363 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | |
364 GetNestedFrame()->GetProcess()->Shutdown(0, false); | |
365 watcher.Wait(); | |
366 | |
367 // Screen wake lock should be released. | |
368 EXPECT_FALSE(HasWakeLock()); | |
369 } | |
370 | |
371 } // namespace content | |
OLD | NEW |