Bug 1267918 - Add GMPCrashHelper for HTMLMediaElement. r=gerald

This ensures that unencrypted GMP decoding crash reporting works.

MozReview-Commit-ID: 84TAV5F9Ie0

--HG--
extra : rebase_source : c0bf3021be9fa0833a7b375967572f1019e4e279
This commit is contained in:
Chris Pearce 2016-06-29 11:42:07 +12:00
Родитель 7517d84f1b
Коммит de045590ac
13 изменённых файлов: 65 добавлений и 5 удалений

Просмотреть файл

@ -18,6 +18,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/TextTrackManager.h" #include "mozilla/dom/TextTrackManager.h"
#include "mozilla/WeakPtr.h"
#include "MediaDecoder.h" #include "MediaDecoder.h"
#ifdef MOZ_EME #ifdef MOZ_EME
#include "mozilla/dom/MediaKeys.h" #include "mozilla/dom/MediaKeys.h"
@ -81,7 +82,8 @@ class HTMLMediaElement : public nsGenericHTMLElement,
public nsIDOMHTMLMediaElement, public nsIDOMHTMLMediaElement,
public MediaDecoderOwner, public MediaDecoderOwner,
public nsIAudioChannelAgentCallback, public nsIAudioChannelAgentCallback,
public PrincipalChangeObserver<DOMMediaStream> public PrincipalChangeObserver<DOMMediaStream>,
public SupportsWeakPtr<HTMLMediaElement>
{ {
friend AutoNotifyAudioChannelAgent; friend AutoNotifyAudioChannelAgent;
@ -94,6 +96,8 @@ public:
typedef mozilla::MediaDecoderOwner MediaDecoderOwner; typedef mozilla::MediaDecoderOwner MediaDecoderOwner;
typedef mozilla::MetadataTags MetadataTags; typedef mozilla::MetadataTags MetadataTags;
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(HTMLMediaElement)
CORSMode GetCORSMode() { CORSMode GetCORSMode() {
return mCORSMode; return mCORSMode;
} }

Просмотреть файл

@ -16,6 +16,8 @@
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
class GMPCrashHelper;
namespace mozilla namespace mozilla
{ {
@ -89,6 +91,8 @@ public:
// Set by Reader if the current audio track can be offloaded // Set by Reader if the current audio track can be offloaded
virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) {} virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) {}
virtual already_AddRefed<GMPCrashHelper> GetCrashHelper() { return nullptr; }
// Stack based class to assist in notifying the frame statistics of // Stack based class to assist in notifying the frame statistics of
// parsed and decoded frames. Use inside video demux & decode functions // parsed and decoded frames. Use inside video demux & decode functions
// to ensure all parsed and decoded frames are reported on all return paths. // to ensure all parsed and decoded frames are reported on all return paths.

Просмотреть файл

@ -30,6 +30,7 @@
#include "mozilla/dom/VideoTrackList.h" #include "mozilla/dom/VideoTrackList.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "GMPService.h"
#ifdef MOZ_ANDROID_OMX #ifdef MOZ_ANDROID_OMX
#include "AndroidBridge.h" #include "AndroidBridge.h"
@ -1108,6 +1109,34 @@ MediaDecoder::OwnerHasError() const
return mShuttingDown || mOwner->HasError(); return mShuttingDown || mOwner->HasError();
} }
class MediaElementGMPCrashHelper : public GMPCrashHelper
{
public:
explicit MediaElementGMPCrashHelper(HTMLMediaElement* aElement)
: mElement(aElement)
{
MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
}
already_AddRefed<nsPIDOMWindowInner> GetPluginCrashedEventTarget() override
{
MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
if (!mElement) {
return nullptr;
}
return do_AddRef(mElement->OwnerDoc()->GetInnerWindow());
}
private:
WeakPtr<HTMLMediaElement> mElement;
};
already_AddRefed<GMPCrashHelper>
MediaDecoder::GetCrashHelper()
{
MOZ_ASSERT(NS_IsMainThread());
return mOwner->GetMediaElement() ?
MakeAndAddRef<MediaElementGMPCrashHelper>(mOwner->GetMediaElement()) : nullptr;
}
bool bool
MediaDecoder::IsEnded() const MediaDecoder::IsEnded() const
{ {

Просмотреть файл

@ -243,6 +243,8 @@ public:
// If the MediaDecoder is shutting down, OwnerHasError will return true. // If the MediaDecoder is shutting down, OwnerHasError will return true.
bool OwnerHasError() const; bool OwnerHasError() const;
already_AddRefed<GMPCrashHelper> GetCrashHelper() override;
protected: protected:
// Updates the media duration. This is called while the media is being // Updates the media duration. This is called while the media is being
// played, calls before the media has reached loaded metadata are ignored. // played, calls before the media has reached loaded metadata are ignored.

Просмотреть файл

@ -178,6 +178,10 @@ MediaFormatReader::Init()
mVideo.mTaskQueue = mVideo.mTaskQueue =
new TaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER)); new TaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER));
// Note: GMPCrashHelper must be created on main thread, as it may use
// weak references, which aren't threadsafe.
mCrashHelper = mDecoder->GetCrashHelper();
return NS_OK; return NS_OK;
} }
@ -411,7 +415,8 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
decoder.mDecoder = mPlatform->CreateDecoder({ decoder.mDecoder = mPlatform->CreateDecoder({
decoder.mInfo ? *decoder.mInfo->GetAsAudioInfo() : mInfo.mAudio, decoder.mInfo ? *decoder.mInfo->GetAsAudioInfo() : mInfo.mAudio,
decoder.mTaskQueue, decoder.mTaskQueue,
decoder.mCallback.get() decoder.mCallback.get(),
mCrashHelper
}); });
break; break;
} }
@ -425,6 +430,7 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
decoder.mCallback.get(), decoder.mCallback.get(),
mLayersBackendType, mLayersBackendType,
GetImageContainer(), GetImageContainer(),
mCrashHelper
}); });
break; break;
} }

Просмотреть файл

@ -571,6 +571,7 @@ private:
#ifdef MOZ_EME #ifdef MOZ_EME
RefPtr<CDMProxy> mCDMProxy; RefPtr<CDMProxy> mCDMProxy;
#endif #endif
RefPtr<GMPCrashHelper> mCrashHelper;
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/LayersTypes.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "GMPService.h"
#include <queue> #include <queue>
namespace mozilla { namespace mozilla {
@ -62,6 +63,7 @@ struct CreateDecoderParams {
DecoderDoctorDiagnostics* mDiagnostics = nullptr; DecoderDoctorDiagnostics* mDiagnostics = nullptr;
layers::ImageContainer* mImageContainer = nullptr; layers::ImageContainer* mImageContainer = nullptr;
layers::LayersBackend mLayersBackend = layers::LayersBackend::LAYERS_NONE; layers::LayersBackend mLayersBackend = layers::LayersBackend::LAYERS_NONE;
RefPtr<GMPCrashHelper> mCrashHelper;
private: private:
void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; } void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
@ -69,6 +71,7 @@ private:
void Set(DecoderDoctorDiagnostics* aDiagnostics) { mDiagnostics = aDiagnostics; } void Set(DecoderDoctorDiagnostics* aDiagnostics) { mDiagnostics = aDiagnostics; }
void Set(layers::ImageContainer* aImageContainer) { mImageContainer = aImageContainer; } void Set(layers::ImageContainer* aImageContainer) { mImageContainer = aImageContainer; }
void Set(layers::LayersBackend aLayersBackend) { mLayersBackend = aLayersBackend; } void Set(layers::LayersBackend aLayersBackend) { mLayersBackend = aLayersBackend; }
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
template <typename T1, typename T2, typename... Ts> template <typename T1, typename T2, typename... Ts>
void Set(T1 a1, T2 a2, Ts... as) void Set(T1 a1, T2 a2, Ts... as)
{ {

Просмотреть файл

@ -131,6 +131,7 @@ GMPAudioDecoderParams::GMPAudioDecoderParams(const CreateDecoderParams& aParams)
, mTaskQueue(aParams.mTaskQueue) , mTaskQueue(aParams.mTaskQueue)
, mCallback(nullptr) , mCallback(nullptr)
, mAdapter(nullptr) , mAdapter(nullptr)
, mCrashHelper(aParams.mCrashHelper)
{} {}
GMPAudioDecoderParams& GMPAudioDecoderParams&
@ -158,6 +159,7 @@ GMPAudioDecoder::GMPAudioDecoder(const GMPAudioDecoderParams& aParams)
, mCallback(aParams.mCallback) , mCallback(aParams.mCallback)
, mGMP(nullptr) , mGMP(nullptr)
, mAdapter(aParams.mAdapter) , mAdapter(aParams.mAdapter)
, mCrashHelper(aParams.mCrashHelper)
{ {
MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback()); MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback());
if (!mAdapter) { if (!mAdapter) {
@ -230,7 +232,7 @@ GMPAudioDecoder::Init()
nsTArray<nsCString> tags; nsTArray<nsCString> tags;
InitTags(tags); InitTags(tags);
UniquePtr<GetGMPAudioDecoderCallback> callback(new GMPInitDoneCallback(this)); UniquePtr<GetGMPAudioDecoderCallback> callback(new GMPInitDoneCallback(this));
if (NS_FAILED(mMPS->GetGMPAudioDecoder(nullptr, &tags, GetNodeId(), Move(callback)))) { if (NS_FAILED(mMPS->GetGMPAudioDecoder(mCrashHelper, &tags, GetNodeId(), Move(callback)))) {
mInitPromise.Reject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__); mInitPromise.Reject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__);
} }

Просмотреть файл

@ -57,6 +57,7 @@ struct GMPAudioDecoderParams {
TaskQueue* mTaskQueue; TaskQueue* mTaskQueue;
MediaDataDecoderCallbackProxy* mCallback; MediaDataDecoderCallbackProxy* mCallback;
AudioCallbackAdapter* mAdapter; AudioCallbackAdapter* mAdapter;
RefPtr<GMPCrashHelper> mCrashHelper;
}; };
class GMPAudioDecoder : public MediaDataDecoder { class GMPAudioDecoder : public MediaDataDecoder {
@ -103,6 +104,7 @@ private:
GMPAudioDecoderProxy* mGMP; GMPAudioDecoderProxy* mGMP;
nsAutoPtr<AudioCallbackAdapter> mAdapter; nsAutoPtr<AudioCallbackAdapter> mAdapter;
MozPromiseHolder<InitPromise> mInitPromise; MozPromiseHolder<InitPromise> mInitPromise;
RefPtr<GMPCrashHelper> mCrashHelper;
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -111,6 +111,7 @@ GMPVideoDecoderParams::GMPVideoDecoderParams(const CreateDecoderParams& aParams)
, mAdapter(nullptr) , mAdapter(nullptr)
, mImageContainer(aParams.mImageContainer) , mImageContainer(aParams.mImageContainer)
, mLayersBackend(aParams.mLayersBackend) , mLayersBackend(aParams.mLayersBackend)
, mCrashHelper(aParams.mCrashHelper)
{} {}
GMPVideoDecoderParams& GMPVideoDecoderParams&
@ -140,6 +141,7 @@ GMPVideoDecoder::GMPVideoDecoder(const GMPVideoDecoderParams& aParams)
, mHost(nullptr) , mHost(nullptr)
, mAdapter(aParams.mAdapter) , mAdapter(aParams.mAdapter)
, mConvertNALUnitLengths(false) , mConvertNALUnitLengths(false)
, mCrashHelper(aParams.mCrashHelper)
{ {
MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback()); MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback());
if (!mAdapter) { if (!mAdapter) {
@ -281,7 +283,7 @@ GMPVideoDecoder::Init()
nsTArray<nsCString> tags; nsTArray<nsCString> tags;
InitTags(tags); InitTags(tags);
UniquePtr<GetGMPVideoDecoderCallback> callback(new GMPInitDoneCallback(this)); UniquePtr<GetGMPVideoDecoderCallback> callback(new GMPInitDoneCallback(this));
if (NS_FAILED(mMPS->GetGMPVideoDecoder(nullptr, &tags, GetNodeId(), Move(callback)))) { if (NS_FAILED(mMPS->GetGMPVideoDecoder(mCrashHelper, &tags, GetNodeId(), Move(callback)))) {
mInitPromise.Reject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__); mInitPromise.Reject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__);
} }

Просмотреть файл

@ -62,6 +62,7 @@ struct GMPVideoDecoderParams {
VideoCallbackAdapter* mAdapter; VideoCallbackAdapter* mAdapter;
layers::ImageContainer* mImageContainer; layers::ImageContainer* mImageContainer;
layers::LayersBackend mLayersBackend; layers::LayersBackend mLayersBackend;
RefPtr<GMPCrashHelper> mCrashHelper;
}; };
class GMPVideoDecoder : public MediaDataDecoder { class GMPVideoDecoder : public MediaDataDecoder {
@ -111,6 +112,7 @@ private:
nsAutoPtr<VideoCallbackAdapter> mAdapter; nsAutoPtr<VideoCallbackAdapter> mAdapter;
bool mConvertNALUnitLengths; bool mConvertNALUnitLengths;
MozPromiseHolder<InitPromise> mInitPromise; MozPromiseHolder<InitPromise> mInitPromise;
RefPtr<GMPCrashHelper> mCrashHelper;
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -25,6 +25,7 @@ H264Converter::H264Converter(PlatformDecoderModule* aPDM,
, mTaskQueue(aParams.mTaskQueue) , mTaskQueue(aParams.mTaskQueue)
, mCallback(aParams.mCallback) , mCallback(aParams.mCallback)
, mDecoder(nullptr) , mDecoder(nullptr)
, mGMPCrashHelper(aParams.mCrashHelper)
, mNeedAVCC(aPDM->DecoderNeedsConversion(aParams.mConfig) == PlatformDecoderModule::kNeedAVCC) , mNeedAVCC(aPDM->DecoderNeedsConversion(aParams.mConfig) == PlatformDecoderModule::kNeedAVCC)
, mLastError(NS_OK) , mLastError(NS_OK)
{ {
@ -147,7 +148,8 @@ H264Converter::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
mCallback, mCallback,
aDiagnostics, aDiagnostics,
mImageContainer, mImageContainer,
mLayersBackend mLayersBackend,
mGMPCrashHelper
}); });
if (!mDecoder) { if (!mDecoder) {

Просмотреть файл

@ -65,6 +65,7 @@ private:
MediaDataDecoderCallback* mCallback; MediaDataDecoderCallback* mCallback;
RefPtr<MediaDataDecoder> mDecoder; RefPtr<MediaDataDecoder> mDecoder;
MozPromiseRequestHolder<InitPromise> mInitPromiseRequest; MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
RefPtr<GMPCrashHelper> mGMPCrashHelper;
bool mNeedAVCC; bool mNeedAVCC;
nsresult mLastError; nsresult mLastError;
}; };