blob: f9db59d60569087384d00613a518d9c18ae9cc89 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
namespace policy {
namespace {
const char kAutoplayTestPageURL[] = "/media/autoplay_iframe.html";
const char kUnifiedAutoplayTestPageURL[] = "/media/unified_autoplay.html";
} // namespace
class AutoplayPolicyTest : public PolicyTest {
public:
AutoplayPolicyTest() {
// Start two embedded test servers on different ports. This will ensure
// the test works correctly with cross origin iframes and site-per-process.
embedded_test_server2()->AddDefaultHandlers(GetChromeTestDataDir());
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(embedded_test_server2()->Start());
}
void NavigateToTestPage(const std::string& main_origin = std::string(),
const std::string& subframe_origin = std::string()) {
GURL origin =
main_origin.empty()
? embedded_test_server()->GetURL(kAutoplayTestPageURL)
: embedded_test_server()->GetURL(main_origin, kAutoplayTestPageURL);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), origin));
// Navigate the subframe to the test page but on the second origin.
GURL origin2 = subframe_origin.empty()
? embedded_test_server2()->GetURL(kAutoplayTestPageURL)
: embedded_test_server()->GetURL(subframe_origin,
kAutoplayTestPageURL);
std::string script = base::StringPrintf(
"setTimeout(\""
"document.getElementById('subframe').src='%s';"
"\",0)",
origin2.spec().c_str());
content::TestNavigationObserver load_observer(GetWebContents());
EXPECT_TRUE(ExecJs(GetWebContents(), script,
content::EXECUTE_SCRIPT_NO_USER_GESTURE));
load_observer.Wait();
}
net::EmbeddedTestServer* embedded_test_server2() {
return &embedded_test_server2_;
}
bool TryAutoplay(content::RenderFrameHost* rfh) {
return content::EvalJs(rfh, "tryPlayback();",
content::EXECUTE_SCRIPT_NO_USER_GESTURE)
.ExtractBool();
}
content::WebContents* GetWebContents() {
return browser()->tab_strip_model()->GetActiveWebContents();
}
content::RenderFrameHost* GetPrimaryMainFrame() {
return GetWebContents()->GetPrimaryMainFrame();
}
content::RenderFrameHost* GetChildFrame() {
return ChildFrameAt(GetPrimaryMainFrame(), 0);
}
private:
// Second instance of embedded test server to provide a second test origin.
net::EmbeddedTestServer embedded_test_server2_;
};
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, AutoplayAllowedByPolicy) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Update policy to allow autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(true));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage();
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, CrossOriginIframe) {
NavigateToTestPage("foo.com", "bar.com");
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Update policy to allow autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(true));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage("foo.com", "bar.com");
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
// Flaky on Linux. See: crbug.com/1189597.
#if BUILDFLAG(IS_LINUX)
#define MAYBE_AutoplayAllowlist_Allowed DISABLED_AutoplayAllowlist_Allowed
#else
#define MAYBE_AutoplayAllowlist_Allowed AutoplayAllowlist_Allowed
#endif
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, MAYBE_AutoplayAllowlist_Allowed) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with our origin.
base::Value::List allowlist;
allowlist.Append(embedded_test_server()->GetURL("/").spec());
// Update policy to allow autoplay for our test origin.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage();
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, AutoplayAllowlist_PatternAllowed) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with our origin.
base::Value::List allowlist;
allowlist.Append("127.0.0.1:*");
// Update policy to allow autoplay for our test origin.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage();
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, AutoplayAllowlist_Missing) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with a random origin.
base::Value::List allowlist;
allowlist.Append("https://www.example.com");
// Update policy to allow autoplay for a random origin.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was not allowed.
NavigateToTestPage();
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
}
// Flaky on Linux and ChromeOS. See: crbug.com/1172978.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_AutoplayDeniedByPolicy DISABLED_AutoplayDeniedByPolicy
#else
#define MAYBE_AutoplayDeniedByPolicy AutoplayDeniedByPolicy
#endif
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, MAYBE_AutoplayDeniedByPolicy) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Update policy to forbid autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(false));
UpdateProviderPolicy(policies);
// Check that autoplay was not allowed by policy.
NavigateToTestPage();
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with a random origin.
base::Value::List allowlist;
allowlist.Append("https://www.example.com");
// Update policy to allow autoplay for a random origin.
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was not allowed.
NavigateToTestPage();
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
}
// Flaky on Linux. See: crbug.com/1172978.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_AutoplayDeniedAllowedWithURL DISABLED_AutoplayDeniedAllowedWithURL
#else
#define MAYBE_AutoplayDeniedAllowedWithURL AutoplayDeniedAllowedWithURL
#endif
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest, MAYBE_AutoplayDeniedAllowedWithURL) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Update policy to forbid autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(false));
UpdateProviderPolicy(policies);
// Check that autoplay was not allowed by policy.
NavigateToTestPage();
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with our test origin.
base::Value::List allowlist;
allowlist.Append(embedded_test_server()->GetURL("/").spec());
// Update policy to allow autoplay for our test origin.
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage();
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
// TODO(crbug.com/40742600): Flaky test.
IN_PROC_BROWSER_TEST_F(AutoplayPolicyTest,
DISABLED_AutoplayAllowedGlobalAndURL) {
NavigateToTestPage();
// Check that autoplay was not allowed.
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Update policy to forbid autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(false));
UpdateProviderPolicy(policies);
// Check that autoplay was not allowed by policy.
NavigateToTestPage();
EXPECT_FALSE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_FALSE(TryAutoplay(GetChildFrame()));
// Create a test allowlist with our test origin.
base::Value::List allowlist;
allowlist.Append(embedded_test_server()->GetURL("/").spec());
// Update policy to allow autoplay for our test origin.
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateToTestPage();
EXPECT_TRUE(TryAutoplay(GetPrimaryMainFrame()));
EXPECT_TRUE(TryAutoplay(GetChildFrame()));
}
class AutoplayPolicyFencedFrameTest : public AutoplayPolicyTest {
public:
AutoplayPolicyFencedFrameTest() = default;
~AutoplayPolicyFencedFrameTest() override = default;
// Prevent additional feature/field trial enablement.
void SetUpCommandLine(base::CommandLine* command_line) override {}
void NavigateAndCheckAutoplayAllowed(bool expected_result) {
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(),
embedded_test_server()->GetURL(kUnifiedAutoplayTestPageURL)));
// Append a cross origin fenced frame into the primary main frame.
content::RenderFrameHost* fenced_frame_host =
fenced_frame_helper_.CreateFencedFrame(
GetPrimaryMainFrame(),
embedded_test_server2()->GetURL(kUnifiedAutoplayTestPageURL));
ASSERT_NE(nullptr, fenced_frame_host);
// Check that autoplay works as |expected_result|.
EXPECT_EQ(TryAutoplay(GetPrimaryMainFrame()), expected_result);
EXPECT_EQ(TryAutoplay(fenced_frame_host), expected_result);
}
bool TryAutoplay(content::RenderFrameHost* rfh) {
return content::EvalJs(rfh, "attemptPlay();",
content::EXECUTE_SCRIPT_NO_USER_GESTURE)
.ExtractBool();
}
protected:
content::test::FencedFrameTestHelper fenced_frame_helper_;
};
IN_PROC_BROWSER_TEST_F(AutoplayPolicyFencedFrameTest, AutoplayAllowedByPolicy) {
// Check that autoplay was not allowed.
NavigateAndCheckAutoplayAllowed(false);
// Update policy to allow autoplay.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowed, base::Value(true));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateAndCheckAutoplayAllowed(true);
}
IN_PROC_BROWSER_TEST_F(AutoplayPolicyFencedFrameTest,
AutoplayAllowlist_Allowed) {
// Check that autoplay was not allowed.
NavigateAndCheckAutoplayAllowed(false);
// Create a test allowlist with our origin.
base::Value::List allowlist;
allowlist.Append(embedded_test_server()->GetURL("/").spec());
// Update policy to allow autoplay for our test origin.
PolicyMap policies;
SetPolicy(&policies, key::kAutoplayAllowlist,
base::Value(std::move(allowlist)));
UpdateProviderPolicy(policies);
// Check that autoplay was allowed by policy.
NavigateAndCheckAutoplayAllowed(true);
}
} // namespace policy