|
@@ -0,0 +1,159 @@
|
|
|
+## Adds a flag to prevent autoplaying media
|
|
|
+
|
|
|
+--- a/chrome/browser/ungoogled_flag_entries.h
|
|
|
++++ b/chrome/browser/ungoogled_flag_entries.h
|
|
|
+@@ -7,1 +7,5 @@
|
|
|
++ {"prevent-autoplay",
|
|
|
++ "PreventAutoplay",
|
|
|
++ "Prevents media from playing automatically. ungoogled-chromium flag.",
|
|
|
++ kOsAll, FEATURE_VALUE_TYPE(media::kPreventAutoplay)},
|
|
|
+ #endif // CHROME_BROWSER_UNGOOGLED_FLAG_ENTRIES_H_
|
|
|
+--- a/media/base/media_switches.cc
|
|
|
++++ b/media/base/media_switches.cc
|
|
|
+@@ -908,6 +908,8 @@ const base::Feature kBresenhamCadence{"B
|
|
|
+ const base::Feature kPlaybackSpeedButton{"PlaybackSpeedButton",
|
|
|
+ base::FEATURE_ENABLED_BY_DEFAULT};
|
|
|
+
|
|
|
++const base::Feature kPreventAutoplay{"PreventAutoplay", base::FEATURE_DISABLED_BY_DEFAULT};
|
|
|
++
|
|
|
+ bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
|
|
|
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
|
|
+ switches::kDisableAcceleratedMjpegDecode)) {
|
|
|
+--- a/media/base/media_switches.h
|
|
|
++++ b/media/base/media_switches.h
|
|
|
+@@ -255,6 +255,8 @@ MEDIA_EXPORT extern const base::Feature
|
|
|
+ MEDIA_EXPORT extern const base::Feature kDeprecateLowUsageCodecs;
|
|
|
+ #endif
|
|
|
+
|
|
|
++MEDIA_EXPORT extern const base::Feature kPreventAutoplay;
|
|
|
++
|
|
|
+ // Based on a |command_line| and the current platform, returns the effective
|
|
|
+ // autoplay policy. In other words, it will take into account the default policy
|
|
|
+ // if none is specified via the command line and options passed for testing.
|
|
|
+--- a/third_party/blink/renderer/core/dom/document.cc
|
|
|
++++ b/third_party/blink/renderer/core/dom/document.cc
|
|
|
+@@ -4081,6 +4081,7 @@ void Document::SetURL(const KURL& url) {
|
|
|
+ if (GetFrame()) {
|
|
|
+ if (FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler())
|
|
|
+ frame_scheduler->TraceUrlChange(url_.GetString());
|
|
|
++ GetFrame()->ClearRealUserActivation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+--- a/third_party/blink/renderer/core/frame/local_frame.h
|
|
|
++++ b/third_party/blink/renderer/core/frame/local_frame.h
|
|
|
+@@ -722,7 +722,17 @@ class CORE_EXPORT LocalFrame final : pub
|
|
|
+ void RebindTextInputHostForTesting();
|
|
|
+ #endif
|
|
|
+
|
|
|
++ void RealUserActivation() { rua_time_ = base::TimeTicks::Now(); }
|
|
|
++ void ClearRealUserActivation() { rua_time_ = base::TimeTicks(); rua_allowed_ = false; }
|
|
|
++ bool HasRealUserActivation() {
|
|
|
++ if (!rua_allowed_) rua_allowed_ = (base::TimeTicks::Now() - rua_time_).InSeconds() < 1;
|
|
|
++ return rua_allowed_;
|
|
|
++ }
|
|
|
++
|
|
|
+ private:
|
|
|
++ bool rua_allowed_ = false;
|
|
|
++ base::TimeTicks rua_time_ = base::TimeTicks();
|
|
|
++
|
|
|
+ friend class FrameNavigationDisabler;
|
|
|
+ // LocalFrameMojoHandler is a part of LocalFrame.
|
|
|
+ friend class LocalFrameMojoHandler;
|
|
|
+--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
|
|
|
++++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
|
|
|
+@@ -2530,6 +2530,7 @@ bool HTMLMediaElement::ended() const {
|
|
|
+ }
|
|
|
+
|
|
|
+ bool HTMLMediaElement::Autoplay() const {
|
|
|
++ if (base::FeatureList::IsEnabled(media::kPreventAutoplay)) return false;
|
|
|
+ return FastHasAttribute(html_names::kAutoplayAttr);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -2638,6 +2639,17 @@ ScriptPromise HTMLMediaElement::playForB
|
|
|
+ absl::optional<DOMExceptionCode> HTMLMediaElement::Play() {
|
|
|
+ DVLOG(2) << "play(" << *this << ")";
|
|
|
+
|
|
|
++ if (base::FeatureList::IsEnabled(media::kPreventAutoplay)) {
|
|
|
++ if (!GetDocument().GetFrame()->HasRealUserActivation()) {
|
|
|
++ if (rua_mute_state_ == -1) rua_mute_state_ = muted_;
|
|
|
++ return DOMExceptionCode::kNotAllowedError;
|
|
|
++ }
|
|
|
++ if (rua_mute_state_ > -1) {
|
|
|
++ if (muted_ != rua_mute_state_) setMuted(rua_mute_state_);
|
|
|
++ rua_mute_state_ = -1;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
+ absl::optional<DOMExceptionCode> exception_code =
|
|
|
+ autoplay_policy_->RequestPlay();
|
|
|
+
|
|
|
+--- a/third_party/blink/renderer/core/html/media/html_media_element.h
|
|
|
++++ b/third_party/blink/renderer/core/html/media/html_media_element.h
|
|
|
+@@ -763,6 +763,8 @@ class CORE_EXPORT HTMLMediaElement
|
|
|
+ // playback raters other than 1.0.
|
|
|
+ bool preserves_pitch_ = true;
|
|
|
+
|
|
|
++ signed char rua_mute_state_ = -1;
|
|
|
++
|
|
|
+ // Keeps track of when the player seek event was sent to the browser process.
|
|
|
+ base::TimeTicks last_seek_update_time_;
|
|
|
+
|
|
|
+--- a/third_party/blink/renderer/core/input/event_handler.cc
|
|
|
++++ b/third_party/blink/renderer/core/input/event_handler.cc
|
|
|
+@@ -830,6 +830,7 @@ WebInputEventResult EventHandler::Handle
|
|
|
+ return WebInputEventResult::kHandledSuppressed;
|
|
|
+ }
|
|
|
+
|
|
|
++ frame_->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ frame_, mojom::blink::UserActivationNotificationType::kInteraction,
|
|
|
+ RuntimeEnabledFeatures::BrowserVerifiedUserActivationMouseEnabled());
|
|
|
+--- a/third_party/blink/renderer/core/input/gesture_manager.cc
|
|
|
++++ b/third_party/blink/renderer/core/input/gesture_manager.cc
|
|
|
+@@ -240,6 +240,7 @@ WebInputEventResult GestureManager::Hand
|
|
|
+ FlooredIntPoint(gesture_event.PositionInRootFrame());
|
|
|
+ Node* tapped_node = current_hit_test.InnerNode();
|
|
|
+ Element* tapped_element = current_hit_test.InnerElement();
|
|
|
++ if(tapped_node) tapped_node->GetDocument().GetFrame()->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ tapped_node ? tapped_node->GetDocument().GetFrame() : nullptr,
|
|
|
+ mojom::blink::UserActivationNotificationType::kInteraction);
|
|
|
+@@ -403,6 +404,7 @@ WebInputEventResult GestureManager::Hand
|
|
|
+ return WebInputEventResult::kNotHandled;
|
|
|
+ }
|
|
|
+
|
|
|
++ if(inner_node) inner_node->GetDocument().GetFrame()->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ inner_node ? inner_node->GetDocument().GetFrame() : nullptr,
|
|
|
+ mojom::blink::UserActivationNotificationType::kInteraction);
|
|
|
+--- a/third_party/blink/renderer/core/input/keyboard_event_manager.cc
|
|
|
++++ b/third_party/blink/renderer/core/input/keyboard_event_manager.cc
|
|
|
+@@ -210,6 +210,7 @@ WebInputEventResult KeyboardEventManager
|
|
|
+ if (!is_modifier && initial_key_event.dom_key != ui::DomKey::ESCAPE &&
|
|
|
+ (initial_key_event.GetType() == WebInputEvent::Type::kKeyDown ||
|
|
|
+ initial_key_event.GetType() == WebInputEvent::Type::kRawKeyDown)) {
|
|
|
++ frame_->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ frame_, mojom::blink::UserActivationNotificationType::kInteraction,
|
|
|
+ RuntimeEnabledFeatures::BrowserVerifiedUserActivationKeyboardEnabled());
|
|
|
+--- a/third_party/blink/renderer/core/input/pointer_event_manager.cc
|
|
|
++++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
|
|
|
+@@ -650,6 +650,7 @@ WebInputEventResult PointerEventManager:
|
|
|
+ // associated with so just pick the pointer event that comes.
|
|
|
+ if (event.GetType() == WebInputEvent::Type::kPointerUp &&
|
|
|
+ !non_hovering_pointers_canceled_ && pointer_event_target.target_frame) {
|
|
|
++ pointer_event_target.target_frame->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ pointer_event_target.target_frame,
|
|
|
+ mojom::blink::UserActivationNotificationType::kInteraction);
|
|
|
+--- a/third_party/blink/renderer/modules/mediasession/media_session.cc
|
|
|
++++ b/third_party/blink/renderer/modules/mediasession/media_session.cc
|
|
|
+@@ -410,6 +410,7 @@ void MediaSession::DidReceiveAction(
|
|
|
+ LocalDOMWindow* window = GetSupplementable()->DomWindow();
|
|
|
+ if (!window)
|
|
|
+ return;
|
|
|
++ window->GetFrame()->RealUserActivation();
|
|
|
+ LocalFrame::NotifyUserActivation(
|
|
|
+ window->GetFrame(),
|
|
|
+ mojom::blink::UserActivationNotificationType::kInteraction);
|