Bug 1128768: Part 5 - Update plugin code to retrieve SWF file for hang annotations; r=jimm
This commit is contained in:
@@ -34,8 +34,10 @@
|
||||
#include "prsystem.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "nsPluginTags.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/plugins/PluginSurfaceParent.h"
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#include "PluginHangUIParent.h"
|
||||
#endif
|
||||
@@ -598,6 +600,7 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome)
|
||||
, mNPPIface(nullptr)
|
||||
, mPlugin(nullptr)
|
||||
, mTaskFactory(this)
|
||||
, mIsFlashPlugin(false)
|
||||
, mIsStartingAsync(false)
|
||||
, mNPInitialized(false)
|
||||
, mAsyncNewRv(NS_ERROR_NOT_INITIALIZED)
|
||||
@@ -639,13 +642,14 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32
|
||||
, mPluginId(aPluginId)
|
||||
, mChromeTaskFactory(this)
|
||||
, mHangAnnotationFlags(0)
|
||||
, mHangAnnotatorMutex("PluginModuleChromeParent::mHangAnnotatorMutex")
|
||||
#ifdef XP_WIN
|
||||
, mPluginCpuUsageOnHang()
|
||||
, mHangUIParent(nullptr)
|
||||
, mHangUIEnabled(true)
|
||||
, mIsTimerReset(true)
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
, mCrashReporterMutex("PluginModuleParent::mCrashReporterMutex")
|
||||
, mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
|
||||
, mCrashReporter(nullptr)
|
||||
#endif
|
||||
#endif
|
||||
@@ -658,7 +662,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32
|
||||
, mAsyncInitRv(NS_ERROR_NOT_INITIALIZED)
|
||||
, mAsyncInitError(NPERR_NO_ERROR)
|
||||
, mContentParent(nullptr)
|
||||
, mIsFlashPlugin(false)
|
||||
{
|
||||
NS_ASSERTION(mSubprocess, "Out of memory!");
|
||||
sInstantiated = true;
|
||||
@@ -906,6 +909,119 @@ GetProcessCpuUsage(const InfallibleTArray<base::ProcessHandle>& processHandles,
|
||||
|
||||
#endif // #ifdef XP_WIN
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::OnEnteredCall()
|
||||
{
|
||||
mozilla::ipc::IProtocol* protocol = GetInvokingProtocol();
|
||||
MOZ_ASSERT(protocol);
|
||||
mozilla::MutexAutoLock lock(mHangAnnotatorMutex);
|
||||
mProtocolCallStack.AppendElement(protocol);
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::OnExitedCall()
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mHangAnnotatorMutex);
|
||||
MOZ_ASSERT(!mProtocolCallStack.IsEmpty());
|
||||
mProtocolCallStack.RemoveElementAt(mProtocolCallStack.Length() - 1);
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::OnEnteredSyncSend()
|
||||
{
|
||||
mozilla::ipc::IProtocol* protocol = GetInvokingProtocol();
|
||||
MOZ_ASSERT(protocol);
|
||||
mozilla::MutexAutoLock lock(mHangAnnotatorMutex);
|
||||
mProtocolCallStack.AppendElement(protocol);
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::OnExitedSyncSend()
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mHangAnnotatorMutex);
|
||||
MOZ_ASSERT(!mProtocolCallStack.IsEmpty());
|
||||
mProtocolCallStack.RemoveElementAt(mProtocolCallStack.Length() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function converts the topmost routing id on the call stack (as recorded
|
||||
* by the MessageChannel) into a pointer to a IProtocol object.
|
||||
*/
|
||||
mozilla::ipc::IProtocol*
|
||||
PluginModuleChromeParent::GetInvokingProtocol()
|
||||
{
|
||||
int32_t routingId = GetIPCChannel()->GetTopmostMessageRoutingId();
|
||||
// Nothing being routed. No protocol. Just return nullptr.
|
||||
if (routingId == MSG_ROUTING_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
// If routingId is MSG_ROUTING_CONTROL then we're dealing with control
|
||||
// messages that were initiated by the topmost managing protocol, ie. this.
|
||||
if (routingId == MSG_ROUTING_CONTROL) {
|
||||
return this;
|
||||
}
|
||||
// Otherwise we can look up the protocol object by the routing id.
|
||||
mozilla::ipc::IProtocol* protocol = Lookup(routingId);
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function examines the IProtocol object parameter and converts it into
|
||||
* the PluginInstanceParent object that is associated with that protocol, if
|
||||
* any. Since PluginInstanceParent manages subprotocols, this function needs
|
||||
* to determine whether |aProtocol| is a subprotocol, and if so it needs to
|
||||
* obtain the protocol's manager.
|
||||
*
|
||||
* This function needs to be updated if the subprotocols are modified in
|
||||
* PPluginInstance.ipdl.
|
||||
*/
|
||||
PluginInstanceParent*
|
||||
PluginModuleChromeParent::GetManagingInstance(mozilla::ipc::IProtocol* aProtocol)
|
||||
{
|
||||
MOZ_ASSERT(aProtocol);
|
||||
mozilla::ipc::MessageListener* listener =
|
||||
static_cast<mozilla::ipc::MessageListener*>(aProtocol);
|
||||
switch (listener->GetProtocolTypeId()) {
|
||||
case PPluginInstanceMsgStart:
|
||||
// In this case, aProtocol is the instance itself. Just cast it.
|
||||
return static_cast<PluginInstanceParent*>(aProtocol);
|
||||
case PPluginBackgroundDestroyerMsgStart: {
|
||||
PPluginBackgroundDestroyerParent* actor =
|
||||
static_cast<PPluginBackgroundDestroyerParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
case PPluginScriptableObjectMsgStart: {
|
||||
PPluginScriptableObjectParent* actor =
|
||||
static_cast<PPluginScriptableObjectParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
case PBrowserStreamMsgStart: {
|
||||
PBrowserStreamParent* actor =
|
||||
static_cast<PBrowserStreamParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
case PPluginStreamMsgStart: {
|
||||
PPluginStreamParent* actor =
|
||||
static_cast<PPluginStreamParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
case PStreamNotifyMsgStart: {
|
||||
PStreamNotifyParent* actor =
|
||||
static_cast<PStreamNotifyParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
case PPluginSurfaceMsgStart: {
|
||||
PPluginSurfaceParent* actor =
|
||||
static_cast<PPluginSurfaceParent*>(aProtocol);
|
||||
return static_cast<PluginInstanceParent*>(actor->Manager());
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::EnteredCxxStack()
|
||||
{
|
||||
@@ -948,6 +1064,24 @@ PluginModuleChromeParent::AnnotateHang(mozilla::HangMonitor::HangAnnotations& aA
|
||||
aAnnotations.AddAnnotation(NS_LITERAL_STRING("pluginName"), mPluginName);
|
||||
aAnnotations.AddAnnotation(NS_LITERAL_STRING("pluginVersion"),
|
||||
mPluginVersion);
|
||||
if (mIsFlashPlugin) {
|
||||
bool isWhitelistedForShumway = false;
|
||||
{ // Scope for lock
|
||||
mozilla::MutexAutoLock lock(mHangAnnotatorMutex);
|
||||
if (!mProtocolCallStack.IsEmpty()) {
|
||||
mozilla::ipc::IProtocol* topProtocol =
|
||||
mProtocolCallStack.LastElement();
|
||||
PluginInstanceParent* instance =
|
||||
GetManagingInstance(topProtocol);
|
||||
if (instance) {
|
||||
isWhitelistedForShumway =
|
||||
instance->IsWhitelistedForShumway();
|
||||
}
|
||||
}
|
||||
}
|
||||
aAnnotations.AddAnnotation(NS_LITERAL_STRING("pluginIsWhitelistedForShumway"),
|
||||
isWhitelistedForShumway);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,8 +1245,7 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop)
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::GetPluginDetails(nsACString& aPluginName,
|
||||
nsACString& aPluginVersion)
|
||||
PluginModuleParent::GetPluginDetails()
|
||||
{
|
||||
nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
if (!host) {
|
||||
@@ -1122,8 +1255,9 @@ PluginModuleParent::GetPluginDetails(nsACString& aPluginName,
|
||||
if (!pluginTag) {
|
||||
return false;
|
||||
}
|
||||
aPluginName = pluginTag->mName;
|
||||
aPluginVersion = pluginTag->mVersion;
|
||||
mPluginName = pluginTag->mName;
|
||||
mPluginVersion = pluginTag->mVersion;
|
||||
mIsFlashPlugin = pluginTag->mIsFlashPlugin;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2245,7 +2379,7 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
}
|
||||
|
||||
if (mPluginName.IsEmpty()) {
|
||||
GetPluginDetails(mPluginName, mPluginVersion);
|
||||
GetPluginDetails();
|
||||
/** mTimeBlocked measures the time that the main thread has been blocked
|
||||
* on plugin module initialization. As implemented, this is the sum of
|
||||
* plugin-container launch + toolhelp32 snapshot + NP_Initialize.
|
||||
@@ -2275,6 +2409,15 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
return NS_PLUGIN_INIT_PENDING;
|
||||
}
|
||||
|
||||
class nsCaseInsensitiveUTF8StringArrayComparator
|
||||
{
|
||||
public:
|
||||
template<class A, class B>
|
||||
bool Equals(const A& a, const B& b) const {
|
||||
return a.Equals(b.get(), nsCaseInsensitiveUTF8StringComparator());
|
||||
}
|
||||
};
|
||||
|
||||
nsresult
|
||||
PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
|
||||
uint16_t mode,
|
||||
@@ -2282,13 +2425,20 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
|
||||
InfallibleTArray<nsCString>& values,
|
||||
NPSavedData* saved, NPError* error)
|
||||
{
|
||||
PluginInstanceParent* parentInstance =
|
||||
new PluginInstanceParent(this, instance,
|
||||
nsDependentCString(pluginType), mNPNIface);
|
||||
nsCaseInsensitiveUTF8StringArrayComparator comparator;
|
||||
NS_NAMED_LITERAL_CSTRING(srcAttributeName, "src");
|
||||
auto srcAttributeIndex = names.IndexOf(srcAttributeName, 0, comparator);
|
||||
nsAutoCString srcAttribute;
|
||||
if (srcAttributeIndex != names.NoIndex) {
|
||||
srcAttribute = values[srcAttributeIndex];
|
||||
}
|
||||
|
||||
if (!parentInstance->Init()) {
|
||||
delete parentInstance;
|
||||
return NS_ERROR_FAILURE;
|
||||
nsDependentCString strPluginType(pluginType);
|
||||
PluginInstanceParent* parentInstance =
|
||||
new PluginInstanceParent(this, instance, strPluginType, mNPNIface);
|
||||
|
||||
if (mIsFlashPlugin) {
|
||||
parentInstance->InitMetadata(strPluginType, srcAttribute);
|
||||
}
|
||||
|
||||
// Release the surrogate reference that was in pdata
|
||||
|
||||
Reference in New Issue
Block a user