Bug 1433309 - Annotate createMediaKeys promise reject with whether failure occurred due to pending shutdown. r=gerald

Around every Firefox update, Netflix see a spike in
MediaKeySystemAccess.createMediaKeys() promise rejects. I am wondering whether
this is caused by the browser restarting to apply a Firefox update while
Netflix's player is loading.  So add more detail to the promise reject as to
the state of the system, to try to validate that theory.

MozReview-Commit-ID: 4IDPsFwKCtq

--HG--
extra : rebase_source : 0a53acb623f895e598845c281edc73b926c74c28
This commit is contained in:
Chris Pearce 2018-01-26 12:20:35 +13:00
Родитель 0bb119e341
Коммит b69a154521
8 изменённых файлов: 56 добавлений и 12 удалений

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

@ -12,6 +12,7 @@
#include "GMPContentChild.h"
#include "GMPContentParent.h"
#include "GMPLog.h"
#include "GMPService.h"
#include "GMPUtils.h"
#include "MediaPrefs.h"
#include "mozilla/dom/MediaKeyMessageEventBinding.h"
@ -44,17 +45,42 @@ bool
ChromiumCDMParent::Init(ChromiumCDMCallback* aCDMCallback,
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState,
nsIEventTarget* aMainThread)
nsIEventTarget* aMainThread,
nsCString& aOutFailureReason)
{
GMP_LOG("ChromiumCDMParent::Init(this=%p)", this);
GMP_LOG("ChromiumCDMParent::Init(this=%p) shutdown=%d abormalShutdown=%d "
"actorDestroyed=%d",
this,
mIsShutdown,
mAbnormalShutdown,
mActorDestroyed);
if (!aCDMCallback || !aMainThread) {
aOutFailureReason = nsPrintfCString("ChromiumCDMParent::Init() failed "
"nullCallback=%d nullMainThread=%d",
!aCDMCallback,
!aMainThread);
GMP_LOG("ChromiumCDMParent::Init(this=%p) failure since aCDMCallback(%p) or"
" aMainThread(%p) is nullptr", this, aCDMCallback, aMainThread);
return false;
}
mCDMCallback = aCDMCallback;
mMainThread = aMainThread;
return SendInit(aAllowDistinctiveIdentifier, aAllowPersistentState);
if (SendInit(aAllowDistinctiveIdentifier, aAllowPersistentState)) {
return true;
}
RefPtr<gmp::GeckoMediaPluginService> service =
gmp::GeckoMediaPluginService::GetGeckoMediaPluginService();
bool xpcomWillShutdown = service && service->XPCOMWillShutdownReceived();
aOutFailureReason = nsPrintfCString(
"ChromiumCDMParent::Init() failed "
"shutdown=%d cdmCrash=%d actorDestroyed=%d browserShutdown=%d",
mIsShutdown,
mAbnormalShutdown,
mActorDestroyed,
xpcomWillShutdown);
return false;
}
void
@ -865,11 +891,11 @@ ChromiumCDMParent::ActorDestroy(ActorDestroyReason aWhy)
mContentParent->ChromiumCDMDestroyed(this);
mContentParent = nullptr;
}
bool abnormalShutdown = (aWhy == AbnormalShutdown);
if (abnormalShutdown && callback) {
mAbnormalShutdown = (aWhy == AbnormalShutdown);
if (mAbnormalShutdown && callback) {
callback->Terminated();
}
MaybeDisconnect(abnormalShutdown);
MaybeDisconnect(mAbnormalShutdown);
}
RefPtr<MediaDataDecoder::InitPromise>

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

@ -43,7 +43,8 @@ public:
bool Init(ChromiumCDMCallback* aCDMCallback,
bool aAllowDistinctiveIdentifier,
bool aAllowPersistentState,
nsIEventTarget* aMainThread);
nsIEventTarget* aMainThread,
nsCString& aOutFailureReason);
void CreateSession(uint32_t aCreateSessionToken,
uint32_t aSessionType,
@ -182,6 +183,7 @@ protected:
bool mIsShutdown = false;
bool mVideoDecoderInitialized = false;
bool mActorDestroyed = false;
bool mAbnormalShutdown = false;
// The H.264 decoder in Widevine CDM versions 970 and later output in decode
// order rather than presentation order, so we reorder in presentation order

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

@ -101,13 +101,13 @@ ChromiumCDMProxy::Init(PromiseId aPromiseId,
[self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) {
self->mCallback =
MakeUnique<ChromiumCDMCallbackProxy>(self, self->mMainThread);
nsCString failureReason;
if (!cdm->Init(self->mCallback.get(),
self->mDistinctiveIdentifierRequired,
self->mPersistentStateRequired,
self->mMainThread)) {
self->RejectPromise(aPromiseId,
NS_ERROR_FAILURE,
NS_LITERAL_CSTRING("GetCDM failed due to CDM initialization failure."));
self->mMainThread,
failureReason)) {
self->RejectPromise(aPromiseId, NS_ERROR_FAILURE, failureReason);
return;
}
{

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

@ -150,6 +150,7 @@ GeckoMediaPluginService::GeckoMediaPluginService()
: mMutex("GeckoMediaPluginService::mMutex")
, mGMPThreadShutdown(false)
, mShuttingDownOnGMPThread(false)
, mXPCOMWillShutdown(false)
{
MOZ_ASSERT(NS_IsMainThread());
@ -224,6 +225,8 @@ GeckoMediaPluginService::Init()
nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
MOZ_ASSERT(obsService);
MOZ_ALWAYS_SUCCEEDS(obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false));
MOZ_ALWAYS_SUCCEEDS(
obsService->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false));
// Kick off scanning for plugins
nsCOMPtr<nsIThread> thread;

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

@ -10,6 +10,7 @@
#include "mozIGeckoMediaPluginService.h"
#include "nsIObserver.h"
#include "nsTArray.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/Monitor.h"
#include "nsString.h"
@ -107,6 +108,8 @@ public:
void ConnectCrashHelper(uint32_t aPluginId, GMPCrashHelper* aHelper);
void DisconnectCrashHelper(GMPCrashHelper* aHelper);
bool XPCOMWillShutdownReceived() const { return mXPCOMWillShutdown; }
protected:
GeckoMediaPluginService();
virtual ~GeckoMediaPluginService();
@ -135,6 +138,7 @@ protected:
RefPtr<AbstractThread> mAbstractGMPThread;
bool mGMPThreadShutdown;
bool mShuttingDownOnGMPThread;
Atomic<bool> mXPCOMWillShutdown;
nsClassHashtable<nsUint32HashKey, nsTArray<RefPtr<GMPCrashHelper>>> mPluginCrashHelpers;
};

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

@ -387,6 +387,8 @@ GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
mServiceChild = nullptr;
}
ShutdownGMPThread();
} else if (!strcmp(NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, aTopic)) {
mXPCOMWillShutdown = true;
}
return NS_OK;

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

@ -309,6 +309,8 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject,
} else if (!strcmp(NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, aTopic)) {
MOZ_ASSERT(mShuttingDown);
ShutdownGMPThread();
} else if (!strcmp(NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, aTopic)) {
mXPCOMWillShutdown = true;
} else if (!strcmp("last-pb-context-exited", aTopic)) {
// When Private Browsing mode exits, all we need to do is clear
// mTempNodeIds. This drops all the node ids we've cached in memory

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

@ -465,7 +465,12 @@ class CDMStorageTest
self->mCDM = cdm;
EXPECT_TRUE(!!self->mCDM);
self->mCallback.reset(new CallbackProxy(self));
self->mCDM->Init(self->mCallback.get(), false, true, GetMainThreadEventTarget());
nsCString failureReason;
self->mCDM->Init(self->mCallback.get(),
false,
true,
GetMainThreadEventTarget(),
failureReason);
for (auto& update : aUpdates) {
self->Update(update);