Bug 1485189 - part1 : dispatch related events when play is not allowed. r=cpearce
authoralwu <alwu@mozilla.com>
Tue, 28 Aug 2018 22:03:15 +0000
changeset 482288 58fc60f3fdf14a5534faba7161e35efdbeb05b01
parent 482287 b6b190197966b1da9c3157324c9b010a093fd639
child 482289 cc07ed4ce971e934b151f6e85c1f8e7ddd814b74
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewerscpearce
bugs1485189
milestone63.0a1
Bug 1485189 - part1 : dispatch related events when play is not allowed. r=cpearce "blocked" event is used for testing. "MozAutoplayMediaBlocked" event is used for changing the control UI on Fennec. Differential Revision: https://phabricator.services.mozilla.com/D4267
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -4067,19 +4067,17 @@ HTMLMediaElement::Play(ErrorResult& aRv)
     MaybeDoLoad();
     mPendingPlayPromises.AppendElement(promise);
     return promise.forget();
   }
 
   if (AudioChannelAgentBlockedPlay()) {
     LOG(LogLevel::Debug, ("%p play blocked by AudioChannelAgent.", this));
     promise->MaybeReject(NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR);
-    if (StaticPrefs::MediaBlockEventEnabled()) {
-      DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
-    }
+    DispatchEventsWhenPlayWasNotAllowed();
     return promise.forget();
   }
 
   UpdateHadAudibleAutoplayState();
 
   const bool handlingUserInput = EventStateManager::IsHandlingUserInput();
   if (AutoplayPolicy::IsAllowedToPlay(*this)) {
     mPendingPlayPromises.AppendElement(promise);
@@ -4132,16 +4130,32 @@ HTMLMediaElement::EnsureAutoplayRequeste
              LOG(LogLevel::Debug, ("%s rejecting play promimses", __func__));
              self->AsyncRejectPendingPlayPromises(
                NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR);
            })
     ->Track(mAutoplayPermissionRequest);
 }
 
 void
+HTMLMediaElement::DispatchEventsWhenPlayWasNotAllowed()
+{
+  if (StaticPrefs::MediaBlockEventEnabled()) {
+    DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
+  }
+#if defined(MOZ_WIDGET_ANDROID)
+  RefPtr<AsyncEventDispatcher> asyncDispatcher =
+    new AsyncEventDispatcher(OwnerDoc(),
+                             NS_LITERAL_STRING("MozAutoplayMediaBlocked"),
+                             CanBubble::eYes,
+                             ChromeOnlyDispatch::eYes);
+  asyncDispatcher->PostDOMEvent();
+#endif
+}
+
+void
 HTMLMediaElement::PlayInternal(bool aHandlingUserInput)
 {
   if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
     // The media load algorithm will be initiated by a user interaction.
     // We want to boost the channel priority for better responsiveness.
     // Note this must be done before UpdatePreloadAction() which will
     // update |mPreloadAction|.
     mUseUrgentStartForChannel = true;
@@ -8004,19 +8018,18 @@ HTMLMediaElement::AsyncRejectPendingPlay
     mPaused = true;
     DispatchAsyncEvent(NS_LITERAL_STRING("pause"));
   }
 
   if (mShuttingDown) {
     return;
   }
 
-  if (aError == NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR &&
-      Preferences::GetBool("media.autoplay.block-event.enabled", false)) {
-    DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
+  if (aError == NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR) {
+    DispatchEventsWhenPlayWasNotAllowed();
   }
 
   nsCOMPtr<nsIRunnable> event = new nsResolveOrRejectPendingPlayPromisesRunner(
     this, TakePendingPlayPromises(), aError);
 
   mMainThreadEventTarget->Dispatch(event.forget());
 }
 
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1377,16 +1377,20 @@ protected:
 
   // True when the media element's audio track is containing silence now.
   bool IsAudioTrackCurrentlySilent() const;
 
   // Calculate the audio track silence proportion and then report the telemetry
   // result. we would report the result when decoder is destroyed.
   void ReportAudioTrackSilenceProportionTelemetry();
 
+  // When the play is not allowed, dispatch related events which are used for
+  // testing or changing control UI.
+  void DispatchEventsWhenPlayWasNotAllowed();
+
   // The current decoder. Load() has been called on this decoder.
   // At most one of mDecoder and mSrcStream can be non-null.
   RefPtr<MediaDecoder> mDecoder;
 
   // The DocGroup-specific nsISerialEventTarget of this HTML element on the main
   // thread.
   nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;