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

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

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

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

@ -30,6 +30,7 @@
#include "mozilla/dom/VideoTrackList.h"
#include "nsPrintfCString.h"
#include "mozilla/Telemetry.h"
#include "GMPService.h"
#ifdef MOZ_ANDROID_OMX
#include "AndroidBridge.h"
@ -1108,6 +1109,34 @@ MediaDecoder::OwnerHasError() const
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
MediaDecoder::IsEnded() const
{

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

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

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

@ -178,6 +178,10 @@ MediaFormatReader::Init()
mVideo.mTaskQueue =
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;
}
@ -411,7 +415,8 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
decoder.mDecoder = mPlatform->CreateDecoder({
decoder.mInfo ? *decoder.mInfo->GetAsAudioInfo() : mInfo.mAudio,
decoder.mTaskQueue,
decoder.mCallback.get()
decoder.mCallback.get(),
mCrashHelper
});
break;
}
@ -425,6 +430,7 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack)
decoder.mCallback.get(),
mLayersBackendType,
GetImageContainer(),
mCrashHelper
});
break;
}

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

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

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

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

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

@ -131,6 +131,7 @@ GMPAudioDecoderParams::GMPAudioDecoderParams(const CreateDecoderParams& aParams)
, mTaskQueue(aParams.mTaskQueue)
, mCallback(nullptr)
, mAdapter(nullptr)
, mCrashHelper(aParams.mCrashHelper)
{}
GMPAudioDecoderParams&
@ -158,6 +159,7 @@ GMPAudioDecoder::GMPAudioDecoder(const GMPAudioDecoderParams& aParams)
, mCallback(aParams.mCallback)
, mGMP(nullptr)
, mAdapter(aParams.mAdapter)
, mCrashHelper(aParams.mCrashHelper)
{
MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback());
if (!mAdapter) {
@ -230,7 +232,7 @@ GMPAudioDecoder::Init()
nsTArray<nsCString> tags;
InitTags(tags);
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__);
}

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

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

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

@ -111,6 +111,7 @@ GMPVideoDecoderParams::GMPVideoDecoderParams(const CreateDecoderParams& aParams)
, mAdapter(nullptr)
, mImageContainer(aParams.mImageContainer)
, mLayersBackend(aParams.mLayersBackend)
, mCrashHelper(aParams.mCrashHelper)
{}
GMPVideoDecoderParams&
@ -140,6 +141,7 @@ GMPVideoDecoder::GMPVideoDecoder(const GMPVideoDecoderParams& aParams)
, mHost(nullptr)
, mAdapter(aParams.mAdapter)
, mConvertNALUnitLengths(false)
, mCrashHelper(aParams.mCrashHelper)
{
MOZ_ASSERT(!mAdapter || mCallback == mAdapter->Callback());
if (!mAdapter) {
@ -281,7 +283,7 @@ GMPVideoDecoder::Init()
nsTArray<nsCString> tags;
InitTags(tags);
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__);
}

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

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

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

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

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

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