Bug 1282410 - part1 : open unsupported type media.
MozReview-Commit-ID: 4fjkDlRgdt7
--- 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);