mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1209385 - Crash GMPs that don't respond to GMPVideoDecoder::Reset(). r=jwwang
This commit is contained in:
parent
3fd903c9df
commit
a76b46867d
@ -606,10 +606,21 @@ GMPChild::GetGMPStorage()
|
||||
return mStorage;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvCrashPluginNow()
|
||||
static MOZ_NEVER_INLINE void
|
||||
CrashForApiTimeout()
|
||||
{
|
||||
MOZ_CRASH();
|
||||
// Never inline so that crash reports are distinctive.
|
||||
MOZ_CRASH("Bug 1209385; GMP API actor failed to respond.");
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvCrashPluginNow(const GMPCrashReason& aReason)
|
||||
{
|
||||
if (aReason == kGmpApiTimeout) {
|
||||
CrashForApiTimeout();
|
||||
} else {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ private:
|
||||
ProcessId aOtherPid) override;
|
||||
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
|
||||
|
||||
virtual bool RecvCrashPluginNow() override;
|
||||
virtual bool RecvCrashPluginNow(const GMPCrashReason& aReason) override;
|
||||
virtual bool RecvBeginAsyncShutdown() override;
|
||||
virtual bool RecvCloseActive() override;
|
||||
|
||||
|
@ -118,6 +118,18 @@ GMPContentParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
||||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CrashPluginNow(GMPCrashReason aReason)
|
||||
{
|
||||
if (mParent) {
|
||||
mParent->Crash(aReason);
|
||||
} else {
|
||||
nsRefPtr<GeckoMediaPluginServiceChild> gmp(
|
||||
GeckoMediaPluginServiceChild::GetSingleton());
|
||||
gmp->CrashPluginNow(mPluginId, aReason);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CloseIfUnused()
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/gmp/PGMPContentParent.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -61,6 +62,8 @@ public:
|
||||
return mPluginId;
|
||||
}
|
||||
|
||||
void CrashPluginNow(GMPCrashReason aReason);
|
||||
|
||||
private:
|
||||
~GMPContentParent();
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "gmp-audio-codec.h"
|
||||
#include "gmp-decryption.h"
|
||||
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
@ -247,6 +249,13 @@ struct ParamTraits<GMPVideoCodec>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::GMPCrashReason>
|
||||
: public ContiguousEnumSerializer<mozilla::GMPCrashReason,
|
||||
mozilla::kPrefChange,
|
||||
mozilla::kInvalid>
|
||||
{};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // GMPMessageUtils_h_
|
||||
|
@ -119,10 +119,10 @@ GMPParent::Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir)
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::Crash()
|
||||
GMPParent::Crash(GMPCrashReason aReason)
|
||||
{
|
||||
if (mState != GMPStateNotLoaded) {
|
||||
unused << SendCrashPluginNow();
|
||||
unused << SendCrashPluginNow(aReason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsIFile.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
class nsIThread;
|
||||
|
||||
@ -79,7 +80,7 @@ public:
|
||||
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
||||
nsresult CloneFrom(const GMPParent* aOther);
|
||||
|
||||
void Crash();
|
||||
void Crash(GMPCrashReason aReason);
|
||||
|
||||
nsresult LoadProcess();
|
||||
|
||||
|
@ -215,6 +215,38 @@ GeckoMediaPluginServiceChild::UpdateTrialCreateState(const nsAString& aKeySystem
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceChild::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
{
|
||||
if (NS_GetCurrentThread() != mGMPThread) {
|
||||
mGMPThread->Dispatch(NS_NewRunnableMethodWithArgs<uint32_t, GMPCrashReason>(
|
||||
this, &GeckoMediaPluginServiceChild::CrashPluginNow,
|
||||
aPluginId, aReason), NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
class Callback : public GetServiceChildCallback
|
||||
{
|
||||
public:
|
||||
Callback(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
: mPluginId(aPluginId)
|
||||
, mReason(aReason)
|
||||
{ }
|
||||
|
||||
virtual void Done(GMPServiceChild* aService) override
|
||||
{
|
||||
aService->SendCrashPluginNow(mPluginId, mReason);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mPluginId;
|
||||
GMPCrashReason mReason;
|
||||
};
|
||||
|
||||
UniquePtr<GetServiceChildCallback> callback(new Callback(aPluginId, aReason));
|
||||
GetServiceChild(Move(callback));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
#include "mozilla/gmp/PGMPServiceChild.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -52,6 +53,8 @@ public:
|
||||
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
|
||||
uint32_t aState) override;
|
||||
|
||||
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild);
|
||||
|
@ -511,7 +511,7 @@ GeckoMediaPluginServiceParent::CrashPlugins()
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (size_t i = 0; i < mPlugins.Length(); i++) {
|
||||
mPlugins[i]->Crash();
|
||||
mPlugins[i]->Crash(kPrefChange);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1221,6 +1221,19 @@ GeckoMediaPluginServiceParent::UpdateTrialCreateState(const nsAString& aKeySyste
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceParent::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
MutexAutoLock lock(mMutex);
|
||||
LOGD(("%s::%s(%u, %u)", __CLASS__, __FUNCTION__, aPluginId, aReason));
|
||||
for (const auto& plugin : mPlugins) {
|
||||
if (plugin->GetPluginId() == aPluginId) {
|
||||
plugin->Crash(aReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ExtractHostName(const nsACString& aOrigin, nsACString& aOutData)
|
||||
{
|
||||
@ -1555,6 +1568,14 @@ GMPServiceParent::~GMPServiceParent()
|
||||
new DeleteTask<Transport>(GetTransport()));
|
||||
}
|
||||
|
||||
bool
|
||||
GMPServiceParent::RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||
const GMPCrashReason& aReason)
|
||||
{
|
||||
mService->CrashPluginNow(aPluginId, aReason);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
|
||||
@ -57,6 +58,8 @@ public:
|
||||
void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState);
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||
|
||||
private:
|
||||
friend class GMPServiceParent;
|
||||
|
||||
@ -223,6 +226,8 @@ public:
|
||||
nsCString* aVersion);
|
||||
virtual bool RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
|
||||
const uint32_t& aState) override;
|
||||
virtual bool RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||
const GMPCrashReason& aReason) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
@ -37,6 +37,12 @@ SplitAt(const char* aDelims,
|
||||
nsCString
|
||||
ToBase64(const nsTArray<uint8_t>& aBytes);
|
||||
|
||||
enum GMPCrashReason {
|
||||
kPrefChange, // media.gmp.plugin.crash has been toggled.
|
||||
kGmpApiTimeout, // Some API did not respond.
|
||||
kInvalid,
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -188,6 +188,7 @@ GMPVideoDecoderParent::Reset()
|
||||
LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get()));
|
||||
self->mResetCompleteTimeout = nullptr;
|
||||
LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()"));
|
||||
self->mPlugin->CrashPluginNow(kGmpApiTimeout);
|
||||
});
|
||||
CancelResetCompleteTimeout();
|
||||
mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread());
|
||||
|
@ -9,6 +9,7 @@ include protocol PGMPTimer;
|
||||
include protocol PGMPStorage;
|
||||
|
||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -33,7 +34,7 @@ parent:
|
||||
|
||||
child:
|
||||
async BeginAsyncShutdown();
|
||||
async CrashPluginNow();
|
||||
async CrashPluginNow(GMPCrashReason aReason);
|
||||
intr StartPlugin();
|
||||
async SetNodeId(nsCString nodeId);
|
||||
async CloseActive();
|
||||
|
@ -6,6 +6,7 @@
|
||||
include protocol PGMP;
|
||||
|
||||
using base::ProcessId from "base/process.h";
|
||||
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -23,6 +24,8 @@ parent:
|
||||
returns (nsCString id);
|
||||
|
||||
async UpdateGMPTrialCreateState(nsString keySystem, uint32_t status);
|
||||
|
||||
async CrashPluginNow(uint32_t pluginId, GMPCrashReason aReason);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
Loading…
Reference in New Issue
Block a user