| 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..b0c6a426787f6978a0e34bcd0c4e1be116633bcc
|
| --- /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_service_context.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 WakeLockServiceContext::Observer {
|
| + public:
|
| + explicit WakeLockWatcher(WakeLockServiceContext* host)
|
| + : host_(host) {
|
| + host_->AddObserver(this);
|
| + }
|
| +
|
| + virtual ~WakeLockWatcher() {
|
| + host_->RemoveObserver(this);
|
| + }
|
| +
|
| + void Wait() {
|
| + loop_.Run();
|
| + }
|
| +
|
| + protected:
|
| + void OnUpdate() override {
|
| + loop_.Quit();
|
| + }
|
| +
|
| + WakeLockServiceContext* host_;
|
| + base::RunLoop loop_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WakeLockWatcher);
|
| +};
|
| +
|
| +class ChangeWakeLockWatcher : public WakeLockWatcher {
|
| + public:
|
| + explicit ChangeWakeLockWatcher(WakeLockServiceContext* 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 WakeLockServiceContext* context = GetWLSCForWebContents();
|
| + CHECK(context);
|
| + return context->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()->
|
| + ExecuteJavaScriptForTests(base::UTF8ToUTF16(js));
|
| + }
|
| +
|
| + void ExecuteJavaScriptAndWait(const char* js) const {
|
| + WakeLockWatcher watcher(GetWLSCForWebContents());
|
| + ExecuteJavaScript(js);
|
| + watcher.Wait();
|
| + }
|
| +
|
| + void ExecuteJavaScriptAndWaitChangeStatus(const char* js) const {
|
| + ChangeWakeLockWatcher watcher(GetWLSCForWebContents());
|
| + 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");
|
| + }
|
| +
|
| + WakeLockServiceContext* GetWLSCForWebContents() const {
|
| + WebContentsImpl* web_contents_impl =
|
| + static_cast<WebContentsImpl*>(shell()->web_contents());
|
| + return web_contents_impl->wake_lock_service_context();
|
| + }
|
| +};
|
| +
|
| +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(GetWLSCForWebContents());
|
| + 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(GetWLSCForWebContents());
|
| + 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(GetWLSCForWebContents());
|
| + FrameTreeNode* child = root->child_at(0);
|
| + child->current_frame_host()->ExecuteJavaScriptForTests(
|
| + 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(GetWLSCForWebContents());
|
| + child->current_frame_host()->ExecuteJavaScriptForTests(
|
| + 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(GetWLSCForWebContents());
|
| + rph->Shutdown(0, true);
|
| + watcher_shutdown.Wait();
|
| +
|
| + // Screen should not be locked now
|
| + EXPECT_FALSE(IsScreenBlocked());
|
| +}
|
| +
|
| +} // namespace content
|
|
|