Commit a38a47cb authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Autoplay] Force allow based on content setting

If the sound content setting has been set to ALLOW
by the user then we should set the force allow
autoplay flag.

BUG=865548

Change-Id: I895ce4d1a0f99357f097ee23ee52fa5fa566cc69
Reviewed-on: https://chromium-review.googlesource.com/1159349
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581923}
parent 79be6d92
......@@ -10,12 +10,17 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/content/source_url_recorder.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/url_constants.h"
#include "media/base/media_switches.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/platform/autoplay.mojom.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/ui/tabs/tab_utils.h"
......@@ -44,6 +49,45 @@ SoundContentSettingObserver::SoundContentSettingObserver(
SoundContentSettingObserver::~SoundContentSettingObserver() = default;
void SoundContentSettingObserver::ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->IsSameDocument())
return;
if (!base::FeatureList::IsEnabled(media::kAutoplaySoundSettings))
return;
GURL url = navigation_handle->IsInMainFrame()
? navigation_handle->GetURL()
: navigation_handle->GetWebContents()->GetLastCommittedURL();
content_settings::SettingInfo setting_info;
std::unique_ptr<base::Value> setting =
host_content_settings_map_->GetWebsiteSetting(
url, navigation_handle->GetURL(),
CONTENT_SETTINGS_TYPE_SOUND, std::string(), &setting_info);
if (content_settings::ValueToContentSetting(setting.get()) !=
CONTENT_SETTING_ALLOW) {
return;
}
if (setting_info.source != content_settings::SETTING_SOURCE_USER)
return;
if (setting_info.primary_pattern == ContentSettingsPattern::Wildcard() &&
setting_info.secondary_pattern == ContentSettingsPattern::Wildcard()) {
return;
}
blink::mojom::AutoplayConfigurationClientAssociatedPtr client;
navigation_handle->GetRenderFrameHost()
->GetRemoteAssociatedInterfaces()
->GetInterface(&client);
client->AddAutoplayFlags(url::Origin::Create(navigation_handle->GetURL()),
blink::mojom::kAutoplayFlagUserException);
}
void SoundContentSettingObserver::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame() && navigation_handle->HasCommitted() &&
......
......@@ -31,6 +31,8 @@ class SoundContentSettingObserver
~SoundContentSettingObserver() override;
// content::WebContentsObserver implementation.
void ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void OnAudioStateChanged(bool audible) override;
......
......@@ -3,13 +3,17 @@
// found in the LICENSE file.
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "media/base/media_switches.h"
#include "net/dns/mock_host_resolver.h"
......@@ -18,6 +22,9 @@
namespace {
static constexpr char const kFramedTestPagePath[] =
"/media/autoplay_iframe.html";
static constexpr char const kTestPagePath[] = "/media/unified_autoplay.html";
} // anonymous namespace
......@@ -226,3 +233,159 @@ IN_PROC_BROWSER_TEST_F(UnifiedAutoplayBrowserTest,
EXPECT_TRUE(AttemptPlay(GetWebContents()));
}
// Integration tests for the new unified autoplay sound settings UI.
class UnifiedAutoplaySettingBrowserTest : public UnifiedAutoplayBrowserTest {
public:
~UnifiedAutoplaySettingBrowserTest() override = default;
void SetUpOnMainThread() override {
scoped_feature_list_.InitAndEnableFeature(media::kAutoplaySoundSettings);
UnifiedAutoplayBrowserTest::SetUpOnMainThread();
}
bool AutoplayAllowed(const content::ToRenderFrameHost& adapter) {
bool played = false;
EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool(
adapter, "tryPlayback();", &played));
return played;
}
void NavigateFrameAndWait(content::RenderFrameHost* rfh, const GURL& url) {
content::TestFrameNavigationObserver observer(rfh);
content::NavigationController::LoadURLParams params(url);
params.transition_type = ui::PAGE_TRANSITION_LINK;
params.frame_tree_node_id = rfh->GetFrameTreeNodeId();
content::WebContents::FromRenderFrameHost(rfh)
->GetController()
.LoadURLWithParams(params);
observer.Wait();
}
HostContentSettingsMap* GetSettingsMap() {
return HostContentSettingsMapFactory::GetForProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
}
content::RenderFrameHost* main_frame() const {
return web_contents()->GetAllFrames()[0];
}
content::RenderFrameHost* first_child() const {
return web_contents()->GetAllFrames()[1];
}
private:
content::WebContents* web_contents() const {
return browser()->tab_strip_model()->GetActiveWebContents();
}
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(UnifiedAutoplaySettingBrowserTest, Allow) {
GURL main_url(
embedded_test_server()->GetURL("example.com", kFramedTestPagePath));
GURL foo_url(embedded_test_server()->GetURL("foo.com", kFramedTestPagePath));
GetSettingsMap()->SetContentSettingDefaultScope(
main_url, main_url, CONTENT_SETTINGS_TYPE_SOUND, std::string(),
CONTENT_SETTING_ALLOW);
NavigateFrameAndWait(main_frame(), main_url);
NavigateFrameAndWait(first_child(), foo_url);
EXPECT_TRUE(AutoplayAllowed(main_frame()));
EXPECT_TRUE(AutoplayAllowed(first_child()));
// Simulate a same document navigation by navigating to #test.
GURL::Replacements replace_ref;
replace_ref.SetRefStr("test");
ui_test_utils::NavigateToURL(browser(),
main_url.ReplaceComponents(replace_ref));
EXPECT_TRUE(AutoplayAllowed(main_frame()));
EXPECT_TRUE(AutoplayAllowed(first_child()));
}
IN_PROC_BROWSER_TEST_F(UnifiedAutoplaySettingBrowserTest, Allow_Wildcard) {
GURL main_url(
embedded_test_server()->GetURL("example.com", kFramedTestPagePath));
GURL foo_url(embedded_test_server()->GetURL("foo.org", kFramedTestPagePath));
GURL bar_url(embedded_test_server()->GetURL("bar.com", kFramedTestPagePath));
// Set a wildcard allow sound setting for *.com.
ContentSettingsPattern pattern(ContentSettingsPattern::FromString("[*.]com"));
GetSettingsMap()->SetWebsiteSettingCustomScope(
pattern, pattern, CONTENT_SETTINGS_TYPE_SOUND, std::string(),
std::make_unique<base::Value>(CONTENT_SETTING_ALLOW));
NavigateFrameAndWait(main_frame(), main_url);
EXPECT_TRUE(AutoplayAllowed(main_frame()));
NavigateFrameAndWait(main_frame(), foo_url);
EXPECT_FALSE(AutoplayAllowed(main_frame()));
NavigateFrameAndWait(main_frame(), bar_url);
EXPECT_TRUE(AutoplayAllowed(main_frame()));
}
IN_PROC_BROWSER_TEST_F(UnifiedAutoplaySettingBrowserTest, Block) {
GURL main_url(
embedded_test_server()->GetURL("example.com", kFramedTestPagePath));
GURL foo_url(embedded_test_server()->GetURL("foo.com", kFramedTestPagePath));
GetSettingsMap()->SetContentSettingDefaultScope(
main_url, main_url, CONTENT_SETTINGS_TYPE_SOUND, std::string(),
CONTENT_SETTING_BLOCK);
NavigateFrameAndWait(main_frame(), main_url);
NavigateFrameAndWait(first_child(), foo_url);
EXPECT_FALSE(AutoplayAllowed(main_frame()));
EXPECT_FALSE(AutoplayAllowed(first_child()));
}
IN_PROC_BROWSER_TEST_F(UnifiedAutoplaySettingBrowserTest, Block_Wildcard) {
GURL main_url(
embedded_test_server()->GetURL("example.com", kFramedTestPagePath));
GURL foo_url(embedded_test_server()->GetURL("foo.org", kFramedTestPagePath));
GURL bar_url(embedded_test_server()->GetURL("bar.com", kFramedTestPagePath));
// Set a wildcard block sound setting for *.com.
ContentSettingsPattern pattern(ContentSettingsPattern::FromString("[*.]com"));
GetSettingsMap()->SetWebsiteSettingCustomScope(
pattern, pattern, CONTENT_SETTINGS_TYPE_SOUND, std::string(),
std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
GetSettingsMap()->SetContentSettingDefaultScope(
foo_url, foo_url, CONTENT_SETTINGS_TYPE_SOUND, std::string(),
CONTENT_SETTING_ALLOW);
NavigateFrameAndWait(main_frame(), main_url);
EXPECT_FALSE(AutoplayAllowed(main_frame()));
NavigateFrameAndWait(main_frame(), foo_url);
EXPECT_TRUE(AutoplayAllowed(main_frame()));
NavigateFrameAndWait(main_frame(), bar_url);
EXPECT_FALSE(AutoplayAllowed(main_frame()));
}
IN_PROC_BROWSER_TEST_F(UnifiedAutoplaySettingBrowserTest, DefaultAllow) {
GURL main_url(
embedded_test_server()->GetURL("example.com", kFramedTestPagePath));
GURL foo_url(embedded_test_server()->GetURL("foo.com", kFramedTestPagePath));
EXPECT_EQ(
CONTENT_SETTING_ALLOW,
GetSettingsMap()->GetContentSetting(
main_url, main_url, CONTENT_SETTINGS_TYPE_SOUND, std::string()));
NavigateFrameAndWait(main_frame(), main_url);
NavigateFrameAndWait(first_child(), foo_url);
EXPECT_FALSE(AutoplayAllowed(main_frame()));
EXPECT_FALSE(AutoplayAllowed(first_child()));
}
......@@ -14,6 +14,10 @@ const int32 kAutoplayFlagHighMediaEngagement = 0x00001;
// This flag indicates a page should always be allowed to autoplay.
const int32 kAutoplayFlagForceAllow = 0x00002;
// This flag indicates a page should be allowed to autoplay because the
// user has added an exception for it.
const int32 kAutoplayFlagUserException = 0x00004;
interface AutoplayConfigurationClient {
// The browser tells the renderer that an origin has specific autoplay flags.
AddAutoplayFlags(url.mojom.Origin origin, int32 flags);
......
......@@ -86,6 +86,9 @@ AutoplayPolicy::Type AutoplayPolicy::GetAutoplayPolicyForDocument(
if (IsDocumentWhitelisted(document))
return Type::kNoUserGestureRequired;
if (DocumentHasUserExceptionFlag(document))
return Type::kNoUserGestureRequired;
return document.GetSettings()->GetAutoplayPolicy();
}
......@@ -135,6 +138,14 @@ bool AutoplayPolicy::DocumentHasForceAllowFlag(const Document& document) {
mojom::blink::kAutoplayFlagForceAllow;
}
// static
bool AutoplayPolicy::DocumentHasUserExceptionFlag(const Document& document) {
if (!document.GetPage())
return false;
return document.GetPage()->AutoplayFlags() &
mojom::blink::kAutoplayFlagUserException;
}
// static
bool AutoplayPolicy::DocumentShouldAutoplayMutedVideos(
const Document& document) {
......
......@@ -49,6 +49,9 @@ class AutoplayPolicy final : public GarbageCollected<AutoplayPolicy> {
// Returns true if the given |document| should force allow autoplay.
static bool DocumentHasForceAllowFlag(const Document&);
// Returns true if the given |document| has the user exception flag.
static bool DocumentHasUserExceptionFlag(const Document&);
// Returns true if the given |document| should autoplay muted videos.
static bool DocumentShouldAutoplayMutedVideos(const Document&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment