From 19606e8594b79c90ee3631920f74957b5544ea98 Mon Sep 17 00:00:00 2001 From: octocorvus Date: Thu, 13 Oct 2022 13:55:35 +0000 Subject: [PATCH] implement autoplay policy to block media autoplay... ... when not allowed by content settings. This commit adds four patches: 1. Add enable-autoplay-permssion flag to the renderer. 2. Implement experimental Autoplay site setting (behind a flag). 3. Add AllowAutoplay in WebContentSettingsClient (allows accessing the Autoplay setting in the renderer (blink). 4. Implement the below autoplay policy. Current autoplay policy (if autoplay is blocked for site as per content settings): 1. Muted autoplay is always blocked. 2. Autoplay with sound is allowed if and only if the user has interacted with domain (click, tap, etc.). If we block this, then the user won't be able to start a video by tapping on the play button, since those will be blocked too. --- ...ble-autoplay-permssion-flag-in-the-r.patch | 167 ++++++++ ...plement-UI-for-autoplay-site-setting.patch | 380 ++++++++++++++++++ ...owAutoplay-for-WebContentSettingsCli.patch | 182 +++++++++ ...nt-autoplay-policy-to-block-media-au.patch | 68 ++++ 4 files changed, 797 insertions(+) create mode 100644 patches/0089-autoplay-add-enable-autoplay-permssion-flag-in-the-r.patch create mode 100644 patches/0090-autoplay-implement-UI-for-autoplay-site-setting.patch create mode 100644 patches/0091-autoplay-add-AllowAutoplay-for-WebContentSettingsCli.patch create mode 100644 patches/0092-autoplay-implement-autoplay-policy-to-block-media-au.patch diff --git a/patches/0089-autoplay-add-enable-autoplay-permssion-flag-in-the-r.patch b/patches/0089-autoplay-add-enable-autoplay-permssion-flag-in-the-r.patch new file mode 100644 index 000000000..313fc7824 --- /dev/null +++ b/patches/0089-autoplay-add-enable-autoplay-permssion-flag-in-the-r.patch @@ -0,0 +1,167 @@ +From bdc7c2049ee15d2e096e0a0462b43a4d7367dee3 Mon Sep 17 00:00:00 2001 +From: octocorvus +Date: Wed, 26 Oct 2022 13:20:53 +0000 +Subject: [PATCH] [autoplay] add enable-autoplay-permssion flag in the + renderer... + +... and expose it through Java ChromeFeatureList and +SiteSettingsFeatureList API. The permission will only be visible and +effective when this flag is enabled. +--- + chrome/browser/about_flags.cc | 4 ++++ + chrome/browser/flag-metadata.json | 7 +++++++ + chrome/browser/flag_descriptions.cc | 4 ++++ + chrome/browser/flag_descriptions.h | 3 +++ + chrome/browser/flags/android/chrome_feature_list.cc | 1 + + .../chromium/chrome/browser/flags/ChromeFeatureList.java | 1 + + .../browser_ui/site_settings/SiteSettingsFeatureList.java | 1 + + .../site_settings/android/site_settings_feature_list.cc | 2 ++ + third_party/blink/common/features.cc | 3 +++ + third_party/blink/public/common/features.h | 2 ++ + 10 files changed, 28 insertions(+) + +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index 5fe29951b44d4..5bb2f3eb38e49 100644 +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -6285,6 +6285,10 @@ const FeatureEntry kFeatureEntries[] = { + flag_descriptions::kDisableProcessReuseDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kDisableProcessReuse)}, + ++ {"enable-autoplay-permission", flag_descriptions::kEnableAutoplayPermission, ++ flag_descriptions::kEnableAutoplayPermissionDescription, kOsAndroid, ++ FEATURE_VALUE_TYPE(blink::features::kEnableAutoplayPermission)}, ++ + #if !BUILDFLAG(IS_ANDROID) + {"enable-accessibility-live-caption", + flag_descriptions::kEnableAccessibilityLiveCaptionName, +diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json +index c74df3b8e7cab..4560f9a892a8d 100644 +--- a/chrome/browser/flag-metadata.json ++++ b/chrome/browser/flag-metadata.json +@@ -1415,6 +1415,13 @@ + "yangsharon@google.com", "alexmos@google.com", "creis@google.com" ], + "expiry_milestone": 110 + }, ++ { ++ "name": "enable-autoplay-permission", ++ "owners": [ ++ "loryeam@gmail.com" ++ ], ++ "expiry_milestone": -1 ++ }, + { + "name": "disable-quick-answers-v2-translation", + "owners": [ "croissant-eng" ], +diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc +index 66d1a897618f4..c904493b32250 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -821,6 +821,10 @@ const char kDisableProcessReuseDescription[] = + "unrelated tabs. This is an experimental mode that will result in more " + "processes being created."; + ++const char kEnableAutoplayPermission[] = "Enable autoplay permission"; ++const char kEnableAutoplayPermissionDescription[] = ++ "Enable autoplay permission."; ++ + const char kDisallowDocWrittenScriptsUiName[] = + "Block scripts loaded via document.write"; + const char kDisallowDocWrittenScriptsUiDescription[] = +diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h +index 1d94a553737be..832ef6c238ec6 100644 +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -405,6 +405,9 @@ extern const char kChromeWhatsNewInMainMenuNewBadgeDescription[]; + extern const char kDisableProcessReuse[]; + extern const char kDisableProcessReuseDescription[]; + ++extern const char kEnableAutoplayPermission[]; ++extern const char kEnableAutoplayPermissionDescription[]; ++ + extern const char kDiscountConsentV2Name[]; + extern const char kDiscountConsentV2Description[]; + +diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc +index f6791e43511cc..abd0c42c66994 100644 +--- a/chrome/browser/flags/android/chrome_feature_list.cc ++++ b/chrome/browser/flags/android/chrome_feature_list.cc +@@ -99,6 +99,7 @@ const base::Feature* const kFeaturesExposedToJava[] = { + &autofill::features::kAutofillEnableUpdateVirtualCardEnrollment, + &autofill::features::kAutofillEnableVirtualCardMetadata, + &blink::features::kPrerender2, ++ &blink::features::kEnableAutoplayPermission, + &blink::features::kForceWebContentsDarkMode, + &commerce::kCommerceMerchantViewer, + &commerce::kCommercePriceTracking, +diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +index 9500d2d9026d3..b0ea15800a1a8 100644 +--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java ++++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +@@ -347,6 +347,7 @@ public abstract class ChromeFeatureList { + public static final String EARLY_LIBRARY_LOAD = "EarlyLibraryLoad"; + public static final String ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS = + "ElidePrioritizationOfPreNativeBootstrapTasks"; ++ public static final String ENABLE_AUTOPLAY_PERMISSION = "EnableAutoplayPermission"; + public static final String ENABLE_AUTOMATIC_SNOOZE = "EnableAutomaticSnooze"; + public static final String ENABLE_FAMILY_INFO_FEEDBACK = "EnableFamilyInfoFeedback"; + public static final String ELASTIC_OVERSCROLL = "ElasticOverscroll"; +diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsFeatureList.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsFeatureList.java +index 1f72fd6058239..fd80fe51829f9 100644 +--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsFeatureList.java ++++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsFeatureList.java +@@ -16,6 +16,7 @@ import org.chromium.build.annotations.MainDex; + @JNINamespace("browser_ui") + @MainDex + public class SiteSettingsFeatureList { ++ public static final String ENABLE_AUTOPLAY_PERMISSION = "EnableAutoplayPermission"; + public static final String SITE_DATA_IMPROVEMENTS = "SiteDataImprovements"; + public static final String REQUEST_DESKTOP_SITE_EXCEPTIONS_DOWNGRADE = + "RequestDesktopSiteExceptionsDowngrade"; +diff --git a/components/browser_ui/site_settings/android/site_settings_feature_list.cc b/components/browser_ui/site_settings/android/site_settings_feature_list.cc +index 48343f2ed9241..2ac2050950102 100644 +--- a/components/browser_ui/site_settings/android/site_settings_feature_list.cc ++++ b/components/browser_ui/site_settings/android/site_settings_feature_list.cc +@@ -7,6 +7,7 @@ + #include "base/notreached.h" + #include "components/browser_ui/site_settings/android/features.h" + #include "components/browser_ui/site_settings/android/site_settings_jni_headers/SiteSettingsFeatureList_jni.h" ++#include "third_party/blink/public/common/features.h" + + using base::android::ConvertJavaStringToUTF8; + using base::android::JavaParamRef; +@@ -19,6 +20,7 @@ namespace { + // this array may either refer to features defined in the header of this file or + // in other locations in the code base (e.g. content_features.h). + const base::Feature* const kFeaturesExposedToJava[] = { ++ &blink::features::kEnableAutoplayPermission, + &kSiteDataImprovements, + &kRequestDesktopSiteExceptionsDowngrade, + }; +diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc +index b26d392e51c9d..fb34216855940 100644 +--- a/third_party/blink/common/features.cc ++++ b/third_party/blink/common/features.cc +@@ -505,6 +505,9 @@ const base::Feature kLightweightNoStatePrefetch { + const base::Feature kForceWebContentsDarkMode{ + "WebContentsForceDark", base::FEATURE_DISABLED_BY_DEFAULT}; + ++const base::Feature kEnableAutoplayPermission{ ++ "EnableAutoplayPermission", base::FEATURE_DISABLED_BY_DEFAULT}; ++ + // A feature to enable using the smallest image specified within image srcset + // for users with Save Data enabled. + const base::Feature kSaveDataImgSrcset{"SaveDataImgSrcset", +diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h +index ac637219f5808..201b144753da6 100644 +--- a/third_party/blink/public/common/features.h ++++ b/third_party/blink/public/common/features.h +@@ -241,6 +241,8 @@ BLINK_COMMON_EXPORT extern const base::Feature kLightweightNoStatePrefetch; + + BLINK_COMMON_EXPORT extern const base::Feature kSaveDataImgSrcset; + ++BLINK_COMMON_EXPORT extern const base::Feature kEnableAutoplayPermission; ++ + BLINK_COMMON_EXPORT extern const base::Feature kForceWebContentsDarkMode; + BLINK_COMMON_EXPORT extern const base::FeatureParam + kForceDarkInversionMethodParam; diff --git a/patches/0090-autoplay-implement-UI-for-autoplay-site-setting.patch b/patches/0090-autoplay-implement-UI-for-autoplay-site-setting.patch new file mode 100644 index 000000000..858763007 --- /dev/null +++ b/patches/0090-autoplay-implement-UI-for-autoplay-site-setting.patch @@ -0,0 +1,380 @@ +From bd0703991975ba4b4c0075ba17e741a0b93225dc Mon Sep 17 00:00:00 2001 +From: octocorvus +Date: Wed, 26 Oct 2022 13:28:20 +0000 +Subject: [PATCH] [autoplay] implement UI for autoplay site setting + +This setting is experimental and hidden behind the flag. +--- + .../ChromeSiteSettingsDelegate.java | 2 ++ + .../res/xml/site_settings_preferences.xml | 4 +++ + .../ContentSettingsResources.java | 6 +++++ + .../site_settings/SingleCategorySettings.java | 7 +++++ + .../site_settings/SingleWebsiteSettings.java | 26 +++++++++++++++++++ + .../site_settings/SiteSettingsCategory.java | 9 +++++-- + .../site_settings/SiteSettingsUtil.java | 1 + + .../browser_ui/site_settings/Website.java | 6 +++++ + .../WebsitePermissionsFetcher.java | 1 + + .../android/website_preference_bridge.cc | 1 + + .../strings/android/site_settings.grdp | 15 +++++++++++ + .../android/page_info_controller_android.cc | 7 +++++ + components/page_info/page_info.cc | 11 ++++++++ + components/page_info/page_info_ui.cc | 2 ++ + components/site_settings_strings.grdp | 6 +++++ + 15 files changed, 102 insertions(+), 2 deletions(-) + +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java +index 4a84a75126820..593c9264e6d96 100644 +--- a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java +@@ -111,6 +111,8 @@ public class ChromeSiteSettingsDelegate implements SiteSettingsDelegate { + case SiteSettingsCategory.Type.AUTO_DARK_WEB_CONTENT: + return ChromeFeatureList.isEnabled( + ChromeFeatureList.DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING); ++ case SiteSettingsCategory.Type.AUTOPLAY: ++ return ChromeFeatureList.isEnabled(ChromeFeatureList.ENABLE_AUTOPLAY_PERMISSION); + case SiteSettingsCategory.Type.BLUETOOTH: + return ContentFeatureList.isEnabled( + ContentFeatureList.WEB_BLUETOOTH_NEW_PERMISSIONS_BACKEND); +diff --git a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml +index 1d4dc20474739..fd616602883b2 100644 +--- a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml ++++ b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml +@@ -71,6 +71,10 @@ found in the LICENSE file. + ++ ++ + + + + Automatic downloads + ++ ++ Autoplay ++ + + Background sync + +@@ -302,6 +305,18 @@ + Allow a site to download multiple files automatically. + + ++ ++ ++ ++ Allow sites to automatically play muted videos ++ ++ ++ Allow autoplay for a specific site. ++ ++ ++ Block autoplay for a specific site. ++ ++ + + + +diff --git a/components/page_info/android/page_info_controller_android.cc b/components/page_info/android/page_info_controller_android.cc +index 38a378be60069..1e7ab20525fd3 100644 +--- a/components/page_info/android/page_info_controller_android.cc ++++ b/components/page_info/android/page_info_controller_android.cc +@@ -25,6 +25,7 @@ + #include "content/public/browser/web_contents.h" + #include "content/public/common/content_features.h" + #include "content/public/common/content_switches.h" ++#include "third_party/blink/public/common/features.h" + #include "url/origin.h" + + using base::android::ConvertUTF16ToJavaString; +@@ -147,6 +148,10 @@ void PageInfoControllerAndroid::SetPermissionInfo( + permissions_to_display.push_back( + ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER); + permissions_to_display.push_back(ContentSettingsType::SOUND); ++ if (base::FeatureList::IsEnabled( ++ blink::features::kEnableAutoplayPermission)) { ++ permissions_to_display.push_back(ContentSettingsType::AUTOPLAY); ++ } + if (base::FeatureList::IsEnabled(features::kWebNfc)) + permissions_to_display.push_back(ContentSettingsType::NFC); + base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); +@@ -220,6 +225,8 @@ absl::optional PageInfoControllerAndroid::GetSettingToDisplay( + // setting should show up in Page Info is in ShouldShowPermission in + // page_info.cc. + return permission.default_setting; ++ } else if (permission.type == ContentSettingsType::AUTOPLAY) { ++ return permission.default_setting; + } else if (permission.type == ContentSettingsType::JAVASCRIPT) { + // The javascript content setting should show up if it is blocked globally + // to give users an easy way to create exceptions. +diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc +index 11af31a67ef19..d449d60019d07 100644 +--- a/components/page_info/page_info.cc ++++ b/components/page_info/page_info.cc +@@ -67,6 +67,7 @@ + #include "net/ssl/ssl_connection_status_flags.h" + #include "services/metrics/public/cpp/ukm_builders.h" + #include "services/metrics/public/cpp/ukm_recorder.h" ++#include "third_party/blink/public/common/features.h" + #include "third_party/boringssl/src/include/openssl/ssl.h" + #include "ui/base/l10n/l10n_util.h" + #include "url/origin.h" +@@ -100,6 +101,7 @@ ContentSettingsType kPermissionType[] = { + ContentSettingsType::ADS, + ContentSettingsType::BACKGROUND_SYNC, + ContentSettingsType::SOUND, ++ ContentSettingsType::AUTOPLAY, + ContentSettingsType::AUTOMATIC_DOWNLOADS, + #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) + ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, +@@ -150,6 +152,15 @@ bool ShouldShowPermission(const PageInfo::PermissionInfo& info, + return true; + } + ++ // Always show autoplay settings UI when it has a site-specific override. ++ if (info.type == ContentSettingsType::AUTOPLAY) { ++ if (!base::FeatureList::IsEnabled( ++ blink::features::kEnableAutoplayPermission)) { ++ return false; ++ } ++ return true; ++ } ++ + // Always show JIT settings UI when when it has a site-specific override. + if (info.type == ContentSettingsType::JAVASCRIPT_JIT) { + return true; +diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc +index ae48aa9762766..788c37f514b1a 100644 +--- a/components/page_info/page_info_ui.cc ++++ b/components/page_info/page_info_ui.cc +@@ -165,6 +165,8 @@ base::span GetContentSettingsUIInfo() { + IDS_SITE_SETTINGS_TYPE_ADS_MID_SENTENCE}, + {ContentSettingsType::SOUND, IDS_SITE_SETTINGS_TYPE_SOUND, + IDS_SITE_SETTINGS_TYPE_SOUND_MID_SENTENCE}, ++ {ContentSettingsType::AUTOPLAY, IDS_SITE_SETTINGS_TYPE_AUTOPLAY, ++ IDS_SITE_SETTINGS_TYPE_AUTOPLAY_MID_SENTENCE}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, + IDS_SITE_SETTINGS_TYPE_CLIPBOARD, + IDS_SITE_SETTINGS_TYPE_CLIPBOARD_MID_SENTENCE}, +diff --git a/components/site_settings_strings.grdp b/components/site_settings_strings.grdp +index d73b6fa7e483b..6f0894c0442bf 100644 +--- a/components/site_settings_strings.grdp ++++ b/components/site_settings_strings.grdp +@@ -19,6 +19,12 @@ + + automatic downloads + ++ ++ Autoplay ++ ++ ++ autoplay ++ + + Background sync + diff --git a/patches/0091-autoplay-add-AllowAutoplay-for-WebContentSettingsCli.patch b/patches/0091-autoplay-add-AllowAutoplay-for-WebContentSettingsCli.patch new file mode 100644 index 000000000..858bcd756 --- /dev/null +++ b/patches/0091-autoplay-add-AllowAutoplay-for-WebContentSettingsCli.patch @@ -0,0 +1,182 @@ +From 90baf1cb00ec425ec3cb17bea589bb2f73b5edca Mon Sep 17 00:00:00 2001 +From: octocorvus +Date: Wed, 12 Oct 2022 09:04:43 +0000 +Subject: [PATCH] [autoplay] add AllowAutoplay for WebContentSettingsClient + +This allows accessing the Autoplay site setting in blink. +--- + .../core/browser/content_settings_utils.cc | 2 ++ + .../core/common/content_settings.cc | 4 +++- + .../core/common/content_settings.h | 1 + + .../core/common/content_settings.mojom | 1 + + .../common/content_settings_mojom_traits.cc | 3 ++- + .../common/content_settings_mojom_traits.h | 5 ++++ + .../renderer/content_settings_agent_impl.cc | 23 +++++++++++++++++++ + .../renderer/content_settings_agent_impl.h | 3 +++ + .../platform/web_content_settings_client.h | 4 ++++ + 9 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc +index a1af4f30a2b00..56122e9850f50 100644 +--- a/components/content_settings/core/browser/content_settings_utils.cc ++++ b/components/content_settings/core/browser/content_settings_utils.cc +@@ -151,6 +151,8 @@ void GetRendererContentSettingRules(const HostContentSettingsMap* map, + &(rules->script_rules)); + map->GetSettingsForOneType(ContentSettingsType::POPUPS, + &(rules->popup_redirect_rules)); ++ map->GetSettingsForOneType(ContentSettingsType::AUTOPLAY, ++ &(rules->autoplay_rules)); + } + + bool IsMorePermissive(ContentSetting a, ContentSetting b) { +diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc +index b2c74904489e7..ef2b0c7da0d99 100644 +--- a/components/content_settings/core/common/content_settings.cc ++++ b/components/content_settings/core/common/content_settings.cc +@@ -203,7 +203,8 @@ bool RendererContentSettingRules::IsRendererContentSetting( + content_type == ContentSettingsType::JAVASCRIPT || + content_type == ContentSettingsType::POPUPS || + content_type == ContentSettingsType::MIXEDSCRIPT || +- content_type == ContentSettingsType::AUTO_DARK_WEB_CONTENT; ++ content_type == ContentSettingsType::AUTO_DARK_WEB_CONTENT || ++ content_type == ContentSettingsType::AUTOPLAY; + } + + void RendererContentSettingRules::FilterRulesByOutermostMainFrameURL( +@@ -213,6 +214,7 @@ void RendererContentSettingRules::FilterRulesByOutermostMainFrameURL( + FilterRulesForType(popup_redirect_rules, outermost_main_frame_url); + FilterRulesForType(mixed_content_rules, outermost_main_frame_url); + FilterRulesForType(auto_dark_content_rules, outermost_main_frame_url); ++ FilterRulesForType(autoplay_rules, outermost_main_frame_url); + } + + RendererContentSettingRules::RendererContentSettingRules() = default; +diff --git a/components/content_settings/core/common/content_settings.h b/components/content_settings/core/common/content_settings.h +index 8a72a70593212..ba92d75a149db 100644 +--- a/components/content_settings/core/common/content_settings.h ++++ b/components/content_settings/core/common/content_settings.h +@@ -93,6 +93,7 @@ struct RendererContentSettingRules { + ContentSettingsForOneType popup_redirect_rules; + ContentSettingsForOneType mixed_content_rules; + ContentSettingsForOneType auto_dark_content_rules; ++ ContentSettingsForOneType autoplay_rules; + }; + + namespace content_settings { +diff --git a/components/content_settings/core/common/content_settings.mojom b/components/content_settings/core/common/content_settings.mojom +index 136cd84e0c4ea..d0622f5c1875f 100644 +--- a/components/content_settings/core/common/content_settings.mojom ++++ b/components/content_settings/core/common/content_settings.mojom +@@ -78,4 +78,5 @@ struct RendererContentSettingRules { + array popup_redirect_rules; + array mixed_content_rules; + array auto_dark_content_rules; ++ array autoplay_rules; + }; +diff --git a/components/content_settings/core/common/content_settings_mojom_traits.cc b/components/content_settings/core/common/content_settings_mojom_traits.cc +index 7827cbb991f8a..0f384e787a254 100644 +--- a/components/content_settings/core/common/content_settings_mojom_traits.cc ++++ b/components/content_settings/core/common/content_settings_mojom_traits.cc +@@ -102,7 +102,8 @@ bool StructTraitsscript_rules) && + data.ReadPopupRedirectRules(&out->popup_redirect_rules) && + data.ReadMixedContentRules(&out->mixed_content_rules) && +- data.ReadAutoDarkContentRules(&out->auto_dark_content_rules); ++ data.ReadAutoDarkContentRules(&out->auto_dark_content_rules) && ++ data.ReadAutoplayRules(&out->autoplay_rules); + } + + } // namespace mojo +diff --git a/components/content_settings/core/common/content_settings_mojom_traits.h b/components/content_settings/core/common/content_settings_mojom_traits.h +index e3afc3a0a2069..9c5c8ffc4983b 100644 +--- a/components/content_settings/core/common/content_settings_mojom_traits.h ++++ b/components/content_settings/core/common/content_settings_mojom_traits.h +@@ -150,6 +150,11 @@ struct StructTraits< + return r.auto_dark_content_rules; + } + ++ static const std::vector& autoplay_rules( ++ const RendererContentSettingRules& r) { ++ return r.autoplay_rules; ++ } ++ + static bool Read( + content_settings::mojom::RendererContentSettingRulesDataView data, + RendererContentSettingRules* out); +diff --git a/components/content_settings/renderer/content_settings_agent_impl.cc b/components/content_settings/renderer/content_settings_agent_impl.cc +index 9b9f37709511a..17c6e48f61092 100644 +--- a/components/content_settings/renderer/content_settings_agent_impl.cc ++++ b/components/content_settings/renderer/content_settings_agent_impl.cc +@@ -362,6 +362,28 @@ bool ContentSettingsAgentImpl::AllowAutoDarkWebContent( + return allow; + } + ++bool ContentSettingsAgentImpl::AllowAutoplay(bool enabled_per_settings) { ++ if (!enabled_per_settings) ++ return false; ++ ++ blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); ++ const auto it = cached_autoplay_permissions_.find(frame); ++ if (it != cached_autoplay_permissions_.end()) ++ return it->second; ++ ++ bool allow = true; ++ if (content_setting_rules_) { ++ ContentSetting setting = GetContentSettingFromRules( ++ content_setting_rules_->autoplay_rules, ++ url::Origin(frame->GetDocument().GetSecurityOrigin()).GetURL()); ++ allow = setting != CONTENT_SETTING_BLOCK; ++ } ++ allow = allow || IsAllowlistedForContentSettings(); ++ ++ cached_autoplay_permissions_[frame] = allow; ++ return allow; ++} ++ + bool ContentSettingsAgentImpl::AllowReadFromClipboard(bool default_value) { + return delegate_->AllowReadFromClipboard().value_or(default_value); + } +@@ -430,6 +452,7 @@ void ContentSettingsAgentImpl::ClearBlockedContentSettings() { + content_blocked_.clear(); + cached_storage_permissions_.clear(); + cached_script_permissions_.clear(); ++ cached_autoplay_permissions_.clear(); + } + + bool ContentSettingsAgentImpl::IsAllowlistedForContentSettings() const { +diff --git a/components/content_settings/renderer/content_settings_agent_impl.h b/components/content_settings/renderer/content_settings_agent_impl.h +index 49448d021a2aa..7066cf3a534bf 100644 +--- a/components/content_settings/renderer/content_settings_agent_impl.h ++++ b/components/content_settings/renderer/content_settings_agent_impl.h +@@ -85,6 +85,7 @@ class ContentSettingsAgentImpl + bool AllowScriptFromSource(bool enabled_per_settings, + const blink::WebURL& script_url) override; + bool AllowAutoDarkWebContent(bool enabled_per_settings) override; ++ bool AllowAutoplay(bool enabled_per_settings) override; + bool AllowReadFromClipboard(bool default_value) override; + bool AllowWriteToClipboard(bool default_value) override; + bool AllowMutationEvents(bool default_value) override; +@@ -159,6 +160,8 @@ class ContentSettingsAgentImpl + // Caches the result of AllowScript. + base::flat_map cached_script_permissions_; + ++ base::flat_map cached_autoplay_permissions_; ++ + bool mixed_content_autoupgrades_disabled_ = false; + + // If true, IsAllowlistedForContentSettings will always return true. +diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h +index 87d4a0ee3887d..a810e5bdf55eb 100644 +--- a/third_party/blink/public/platform/web_content_settings_client.h ++++ b/third_party/blink/public/platform/web_content_settings_client.h +@@ -73,6 +73,10 @@ class WebContentSettingsClient { + return enabled_per_settings; + } + ++ virtual bool AllowAutoplay(bool enabled_per_settings) { ++ return enabled_per_settings; ++ } ++ + // Controls whether access to read the clipboard is allowed for this frame. + virtual bool AllowReadFromClipboard(bool default_value) { + return default_value; diff --git a/patches/0092-autoplay-implement-autoplay-policy-to-block-media-au.patch b/patches/0092-autoplay-implement-autoplay-policy-to-block-media-au.patch new file mode 100644 index 000000000..1116cde46 --- /dev/null +++ b/patches/0092-autoplay-implement-autoplay-policy-to-block-media-au.patch @@ -0,0 +1,68 @@ +From dabfa5b5a15c67fcb0f565c5c993f25c2b2ea8f8 Mon Sep 17 00:00:00 2001 +From: octocorvus +Date: Thu, 13 Oct 2022 13:20:05 +0000 +Subject: [PATCH] [autoplay] implement autoplay policy to block media + autoplay... + +... when not allowed by content settings. + +Current autoplay policy (if autoplay is blocked for site as per content +settings): +- Muted autoplay is always blocked. +- Autoplay with sound is allowed if and only if the user has interacted + with domain (click, tap, etc.). If we block this, then the user won't + be able to start a video by tapping on the play button, since those + will be blocked too. +--- + .../renderer/core/html/media/autoplay_policy.cc | 17 +++++++++++++++++ + .../renderer/core/html/media/autoplay_policy.h | 2 ++ + 2 files changed, 19 insertions(+) + +diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc +index 871d82556706b..a2baf0489dddd 100644 +--- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc ++++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc +@@ -310,6 +310,9 @@ void AutoplayPolicy::TryUnlockingUserGesture() { + } + + bool AutoplayPolicy::IsGestureNeededForPlayback() const { ++ if (!IsAutoplayAllowedByContentSettings()) ++ return true; ++ + if (!IsLockedPendingUserGesture()) + return false; + +@@ -337,6 +340,20 @@ void AutoplayPolicy::EnsureAutoplayInitiatedSet() { + autoplay_initiated_ = false; + } + ++bool AutoplayPolicy::IsAutoplayAllowedByContentSettings() const { ++ if (!base::FeatureList::IsEnabled(features::kEnableAutoplayPermission)) ++ return true; ++ ++ LocalFrame* frame = element_->GetDocument().GetFrame(); ++ if (!frame) ++ return false; ++ ++ if (auto* settings_client = frame->GetContentSettingsClient()) ++ return settings_client->AllowAutoplay(true); ++ ++ return true; ++} ++ + void AutoplayPolicy::OnIntersectionChangedForAutoplay( + const HeapVector>& entries) { + bool is_visible = (entries.back()->intersectionRatio() > 0); +diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.h b/third_party/blink/renderer/core/html/media/autoplay_policy.h +index ca5c996363ad8..ae4c094cd1559 100644 +--- a/third_party/blink/renderer/core/html/media/autoplay_policy.h ++++ b/third_party/blink/renderer/core/html/media/autoplay_policy.h +@@ -113,6 +113,8 @@ class CORE_EXPORT AutoplayPolicy final + // avoid false positives. + void EnsureAutoplayInitiatedSet(); + ++ bool IsAutoplayAllowedByContentSettings() const; ++ + virtual void Trace(Visitor*) const; + + private: