Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(896)

Unified Diff: content/browser/wake_lock/wake_lock_browsertest.cc

Issue 1107333002: Wake Lock API implementation (Chromium part) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/wake_lock/wake_lock_browsertest.cc
diff --git a/content/browser/wake_lock/wake_lock_browsertest.cc b/content/browser/wake_lock/wake_lock_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..be4409a3f752ef6cf7da5abfce5593ab26c39c89
--- /dev/null
+++ b/content/browser/wake_lock/wake_lock_browsertest.cc
@@ -0,0 +1,362 @@
+// Copyright 2015 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 "base/command_line.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/wake_lock/wake_lock_dispatcher_host.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace content {
+
+class WakeLockWatcher : public WakeLockDispatcherHost::Observer {
+ public:
+ explicit WakeLockWatcher(WakeLockDispatcherHost* host)
+ : host_(host) {
+ host_->AddObserver(this);
+ }
+
+ virtual ~WakeLockWatcher() {
+ host_->RemoveObserver(this);
+ }
+
+ void Wait() {
+ loop_.Run();
+ }
+
+ protected:
+ void OnUpdate() override {
+ loop_.Quit();
+ }
+
+ WakeLockDispatcherHost* host_;
+ base::RunLoop loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLockWatcher);
+};
+
+class ChangeWakeLockWatcher : public WakeLockWatcher {
+ public:
+ explicit ChangeWakeLockWatcher(WakeLockDispatcherHost* host)
+ : WakeLockWatcher(host) {
+ has_blocker_ = host_->has_blocker_for_testing();
+ }
+
+ private:
+ void OnUpdate() override {
+ if (host_->has_blocker_for_testing() != has_blocker_)
+ loop_.Quit();
+ }
+
+ bool has_blocker_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChangeWakeLockWatcher);
+};
+
+class WakeLockTest : public ContentBrowserTest {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures);
+ command_line->AppendSwitch(switches::kSitePerProcess);
+ }
+
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ SetupCrossSiteRedirector(embedded_test_server());
+ }
+
+ protected:
+ bool IsScreenBlocked() const {
+ const WakeLockDispatcherHost* dispatcher = GetWLDHForWebContents();
+ CHECK(dispatcher);
+ return dispatcher->has_blocker_for_testing();
+ }
+
+ void LoadTestURL(const char* url_name) const {
+ GURL test_url = GetTestUrl("wake_lock", url_name);
+ ASSERT_TRUE(NavigateToURL(shell(), test_url));
+ }
+
+ void LoadTestURLAndLockScreen(const char* url_name) const {
+ LoadTestURL(url_name);
+ EXPECT_FALSE(IsScreenBlocked());
+
+ // Lock screen
+ ExecuteJavaScriptAndWaitChangeStatus("screen.keepAwake = true;");
+ EXPECT_TRUE(IsScreenBlocked());
+ }
+
+ void ExecuteJavaScript(const char* js) const {
+ shell()->web_contents()->GetMainFrame()->
+ ExecuteJavaScript(base::UTF8ToUTF16(js));
+ }
+
+ void ExecuteJavaScriptAndWait(const char* js) const {
+ WakeLockWatcher watcher(GetWLDHForWebContents());
+ ExecuteJavaScript(js);
+ watcher.Wait();
+ }
+
+ void ExecuteJavaScriptAndWaitChangeStatus(const char* js) const {
+ ChangeWakeLockWatcher watcher(GetWLDHForWebContents());
+ ExecuteJavaScript(js);
+ watcher.Wait();
+ }
+
+ bool ExecuteJavaScriptAndGetBool(const char* js) const {
+ bool bool_value = false;
+ scoped_ptr<base::Value> value = ExecuteScriptAndGetValue(
+ shell()->web_contents()->GetMainFrame(), js);
+ EXPECT_TRUE(value->GetAsBoolean(&bool_value));
+ return bool_value;
+ }
+
+ bool GetScreenKeepAwakeInJS() const {
+ return ExecuteJavaScriptAndGetBool("screen.keepAwake");
+ }
+
+ WakeLockDispatcherHost* GetWLDHForWebContents() const {
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ return web_contents_impl->wake_lock_dispatcher_host();
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, WakeLockApiIsPresent) {
+ LoadTestURL("../title1.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+ EXPECT_TRUE(ExecuteJavaScriptAndGetBool(
+ "typeof screen.keepAwake !== undefined"));
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockAndUnlockScreenInMainFrame) {
+ LoadTestURL("../title1.html");
+
+ // Screen is not locked on start
+ EXPECT_FALSE(IsScreenBlocked());
+
+ // Check attribute 'screen.keepAwake' in JavaScript
+ EXPECT_FALSE(GetScreenKeepAwakeInJS());
+
+ // Intention to lock screen
+ ExecuteJavaScriptAndWaitChangeStatus("screen.keepAwake = true;");
+
+ // Check attribute
+ EXPECT_TRUE(GetScreenKeepAwakeInJS());
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Set attribute to false, no longer keep screen awake
+ ExecuteJavaScriptAndWaitChangeStatus("screen.keepAwake = false;");
+
+ // Check attribute in JS
+ EXPECT_FALSE(GetScreenKeepAwakeInJS());
+
+ // Screen should not be locked now.
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, ManyLockOneUnlock) {
+ LoadTestURLAndLockScreen("../title1.html");
+
+ // Intention to lock screen in main frame when screen is locked
+ ExecuteJavaScriptAndWait("screen.keepAwake = true;");
+ EXPECT_TRUE(IsScreenBlocked());
+
+ ExecuteJavaScriptAndWaitChangeStatus("screen.keepAwake = false;");
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, LockScreenInMainFrameAndNestedFrame) {
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+
+ // Lock screen in nested frame
+ ExecuteJavaScriptAndWaitChangeStatus(
+ "document.getElementById('nested_frame')."
+ "contentWindow.screen.keepAwake = true;");
+
+ // Screen is locked now
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // But in main frame screen.keepAwake is false
+ EXPECT_FALSE(GetScreenKeepAwakeInJS());
+
+ // Lock screen in main frame
+ ExecuteJavaScriptAndWait("screen.keepAwake = true;");
+
+ EXPECT_TRUE(GetScreenKeepAwakeInJS());
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Unlock screen in nested frame
+ ExecuteJavaScriptAndWait("document.getElementById('nested_frame')."
+ "contentWindow.screen.keepAwake = false;");
+
+ // screen.keepAwake in nested frame is false, but screen is locked now
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Unlock screen in main frame
+ ExecuteJavaScriptAndWaitChangeStatus("screen.keepAwake = false;");
+
+ // Screen is unlock now
+ EXPECT_FALSE(GetScreenKeepAwakeInJS());
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, RemoveFrame) {
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+
+ // Lock screen in nested frame
+ ExecuteJavaScriptAndWaitChangeStatus(
+ "document.getElementById('nested_frame')."
+ "contentWindow.screen.keepAwake = true;");
+
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Remove nested frame
+ ExecuteJavaScriptAndWaitChangeStatus(
+ "var iframe = document.getElementById('nested_frame');"
+ "iframe.parentNode.removeChild(iframe);");
+
+ // Screen is unlocked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashTab) {
+ LoadTestURLAndLockScreen("../title1.html");
+
+ // Tab is crashed
+ ChangeWakeLockWatcher watcher(GetWLDHForWebContents());
+ CrashTab(shell()->web_contents());
+ watcher.Wait();
+
+ // Screen is unlocked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, Navigation) {
+ LoadTestURLAndLockScreen("../title1.html");
+
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, NavigationToSelf) {
+ LoadTestURLAndLockScreen("../title1.html");
+
+ LoadTestURL("../title1.html");
+
+ // Screen is unlocked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, Reload) {
+ LoadTestURLAndLockScreen("../title1.html");
+
+ ChangeWakeLockWatcher watcher(GetWLDHForWebContents());
+ shell()->Reload();
+ watcher.Wait();
+
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, FrameNavigation) {
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+
+ // Lock screen in nested frame
+ ExecuteJavaScriptAndWaitChangeStatus(
+ "document.getElementById('nested_frame')."
+ "contentWindow.screen.keepAwake = true;");
+ // Screen is locked now
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Navigate frame
+ ExecuteJavaScriptAndWaitChangeStatus(
+ "document.getElementById('nested_frame')."
+ "src = 'data:text/html,';");
+
+ // Screen is unlocked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, OutOfProcessFrame) {
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+
+ // Lock screen in same-site iframe
+ ChangeWakeLockWatcher watcher(GetWLDHForWebContents());
+ FrameTreeNode* child = root->child_at(0);
+ child->current_frame_host()->
+ ExecuteJavaScript(base::UTF8ToUTF16("screen.keepAwake = true;"));
+ watcher.Wait();
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Load cross-site page into iframe.
+ GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
+ NavigateFrameToURL(root->child_at(0), url);
+
+ // Ensure that we have created a new process for the subframe.
+ RenderProcessHost* rph = child->current_frame_host()->GetProcess();
+ EXPECT_NE(shell()->web_contents()->GetRenderProcessHost(), rph);
+
+ // Screen should not be locked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+IN_PROC_BROWSER_TEST_F(WakeLockTest, UnlockAfterCrashOutOfProcessFrame) {
+ LoadTestURL("page_with_iframe.html");
+
+ EXPECT_FALSE(IsScreenBlocked());
+
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->
+ GetFrameTree()->root();
+ FrameTreeNode* child = root->child_at(0);
+
+ // Load cross-site page into iframe.
+ GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
+ NavigateFrameToURL(child, url);
+
+ // Ensure that we have created a new process for the subframe.
+ EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());
+
+ // Lock screen in cross-site iframe
+ ChangeWakeLockWatcher watcher(GetWLDHForWebContents());
+ child->current_frame_host()->
+ ExecuteJavaScript(base::UTF8ToUTF16("screen.keepAwake = true;"));
+ watcher.Wait();
+ EXPECT_TRUE(IsScreenBlocked());
+
+ // Crash process that owns the out-of-process frame
+ RenderProcessHost* rph = child->current_frame_host()->GetProcess();
+ ChangeWakeLockWatcher watcher_shutdown(GetWLDHForWebContents());
+ rph->Shutdown(0, true);
+ watcher_shutdown.Wait();
+
+ // Screen should not be locked now
+ EXPECT_FALSE(IsScreenBlocked());
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698