Bug 1282410 - part1 : open unsupported type media. draft
authorAlastor Wu <alwu@mozilla.com>
Wed, 06 Jul 2016 10:34:29 +0800
changeset 384322 03cd1e7b4ecbe180c2919f38d7f3ac65a20bc7c5
parent 384274 70e05c6832e831374604ac3ce7433971368dffe0
child 384323 475195c43a1b0e092acc273460480d83c57e9952
child 384333 e7cf9c37951c2dae87bf2e347ef5f21266fd6a80
push id22241
push useralwu@mozilla.com
push dateWed, 06 Jul 2016 02:37:36 +0000
bugs1282410
milestone50.0a1
Bug 1282410 - part1 : open unsupported type media. MozReview-Commit-ID: 4fjkDlRgdt7
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
mobile/android/app/mobile.js
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -964,16 +964,17 @@ void HTMLMediaElement::NoSupportedMediaS
   NS_ASSERTION(mNetworkState == NETWORK_LOADING,
                "Not loading during source selection?");
 
   mError = new MediaError(this, nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE);
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
   ChangeDelayLoadStatus(false);
   UpdateAudioChannelPlayingState();
+  OpenUnsupportedMediaWithExtenalAppIfNeeded();
 }
 
 typedef void (HTMLMediaElement::*SyncSectionFn)();
 
 // Runs a "synchronous section", a function that must run once the event loop
 // has reached a "stable state". See:
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
 class nsSyncSection : public nsMediaEvent
@@ -2611,16 +2612,20 @@ HTMLMediaElement::PlayInternal(bool aCal
 
   // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
   // and our preload status.
   AddRemoveSelfReference();
   UpdatePreloadAction();
   UpdateSrcMediaStreamPlaying();
   UpdateAudioChannelPlayingState();
 
+  // The check here is to handle the case that the media element starts playing
+  // after it loaded fail. eg. preload the data before playing.
+  OpenUnsupportedMediaWithExtenalAppIfNeeded();
+
   return NS_OK;
 }
 
 NS_IMETHODIMP HTMLMediaElement::Play()
 {
   return PlayInternal(/* aCallerIsChrome = */ true);
 }
 
@@ -5827,16 +5832,51 @@ HTMLMediaElement::IsAudible() const
   // Silent audio track.
   if (!mIsAudioTrackAudible) {
     return false;
   }
 
   return true;
 }
 
+bool
+HTMLMediaElement::HaveFailedWithSourceNotSupportedError() const
+{
+  if (!mError) {
+    return false;
+  }
+
+  uint16_t errorCode;
+  mError->GetCode(&errorCode);
+  return (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE &&
+          errorCode == nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
+}
+
+void
+HTMLMediaElement::OpenUnsupportedMediaWithExtenalAppIfNeeded()
+{
+  if (!Preferences::GetBool("media.openUnsupportedTypeWithExternalApp")) {
+    return;
+  }
+
+  if (!HaveFailedWithSourceNotSupportedError()) {
+    return;
+  }
+
+  // If media doesn't start playing, we don't need to open it.
+  if (mPaused) {
+    return;
+  }
+
+  nsContentUtils::DispatchTrustedEvent(OwnerDoc(), static_cast<nsIContent*>(this),
+                                       NS_LITERAL_STRING("OpenMediaWithExtenalApp"),
+                                       true,
+                                       true);
+}
+
 static const char* VisibilityString(Visibility aVisibility) {
   switch(aVisibility) {
     case Visibility::UNTRACKED: {
       return "UNTRACKED";
     }
     case Visibility::NONVISIBLE: {
       return "NONVISIBLE";
     }
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1188,16 +1188,19 @@ protected:
   void ResumeFromAudioChannelBlocked();
 
   bool IsSuspendedByAudioChannel() const;
   void SetAudioChannelSuspended(SuspendTypes aSuspend);
 
   bool IsAllowedToPlay();
 
   bool IsAudible() const;
+  bool HaveFailedWithSourceNotSupportedError() const;
+
+  void OpenUnsupportedMediaWithExtenalAppIfNeeded();
 
   class nsAsyncEventRunner;
   using nsGenericHTMLElement::DispatchEvent;
   // For nsAsyncEventRunner.
   nsresult DispatchEvent(const nsAString& aName);
 
   // The current decoder. Load() has been called on this decoder.
   // At most one of mDecoder and mSrcStream can be non-null.
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -913,8 +913,10 @@ pref("identity.fxaccounts.remote.oauth.u
 pref("identity.sync.tokenserver.uri", "https://token.services.mozilla.com/1.0/sync/1.5");
 
 // Enable Presentation API
 pref("dom.presentation.enabled", true);
 pref("dom.presentation.discovery.enabled", true);
 
 pref("dom.audiochannel.audioCompeting", true);
 pref("dom.audiochannel.mediaControl", true);
+
+pref("media.openUnsupportedTypeWithExternalApp", true);