Bug 1148012 - Expose run ID through nsIObjectLoadingContent.idl. r=josh,smaug.
authorMike Conley <mconley@mozilla.com>
Tue, 17 Mar 2015 13:28:32 -0400
changeset 238175 fb8373ac7558eebd2a28a43ef8e8d85b1d8aa161
parent 238174 a423c6fdc3d47aca7f7933c36b8a1f9f4dafff4f
child 238176 84d46805a0796748bed802103a57686f26d6dc86
push id28557
push userkwierso@gmail.com
push dateThu, 09 Apr 2015 00:04:16 +0000
treeherdermozilla-central@9a29065e2311 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjosh, smaug
bugs1148012
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1148012 - Expose run ID through nsIObjectLoadingContent.idl. r=josh,smaug. The run ID for a plugin is retrieved and cached in the nsObjectLoadingContent on plugin instantiation.
dom/base/nsIObjectLoadingContent.idl
dom/base/nsObjectLoadingContent.cpp
dom/base/nsObjectLoadingContent.h
dom/plugins/base/PluginPRLibrary.h
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/ipc/PluginLibrary.h
dom/plugins/ipc/PluginModuleParent.h
dom/webidl/HTMLObjectElement.webidl
--- a/dom/base/nsIObjectLoadingContent.idl
+++ b/dom/base/nsIObjectLoadingContent.idl
@@ -20,17 +20,17 @@ class nsNPAPIPluginInstance;
 
 /**
  * This interface represents a content node that loads objects.
  *
  * Please make sure to update the MozObjectLoadingContent WebIDL
  * interface to mirror this interface when changing it.
  */
 
-[scriptable, uuid(16c14177-52eb-49d3-9842-a1a0b92be11a)]
+[scriptable, uuid(5efbd411-5bbe-4de1-9f3a-1c3459696eb2)]
 interface nsIObjectLoadingContent : nsISupports
 {
   /**
    * See notes in nsObjectLoadingContent.h
    */
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
@@ -183,9 +183,17 @@ interface nsIObjectLoadingContent : nsIS
    * not one is pending spawn/despawn.
    */
   readonly attribute bool hasRunningPlugin;
 
   /**
    * This method will disable the play-preview plugin state.
    */
   void cancelPlayPreview();
+
+  /**
+   * If this plugin runs out-of-process, it has a runID to differentiate
+   * between different times the plugin process has been instantiated.
+   *
+   * This throws NS_ERROR_NOT_IMPLEMENTED for in-process plugins.
+   */
+  readonly attribute unsigned long runID;
 };
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -696,16 +696,18 @@ nsObjectLoadingContent::UnbindFromTree(b
                                                        NS_LITERAL_STRING("PluginRemoved"));
     NS_DispatchToCurrentThread(ev);
   }
 }
 
 nsObjectLoadingContent::nsObjectLoadingContent()
   : mType(eType_Loading)
   , mFallbackType(eFallbackAlternate)
+  , mRunID(0)
+  , mHasRunID(false)
   , mChannelLoaded(false)
   , mInstantiating(false)
   , mNetworkCreated(true)
   , mActivated(false)
   , mPlayPreviewCanceled(false)
   , mIsStopping(false)
   , mIsLoading(false)
   , mScriptRequested(false) {}
@@ -810,16 +812,27 @@ nsObjectLoadingContent::InstantiatePlugi
       }
       newOwner->Destroy();
     }
     return NS_OK;
   }
 
   mInstanceOwner = newOwner;
 
+  if (mInstanceOwner) {
+    nsRefPtr<nsNPAPIPluginInstance> inst;
+    rv = mInstanceOwner->GetInstance(getter_AddRefs(inst));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    rv = inst->GetRunID(&mRunID);
+    mHasRunID = NS_SUCCEEDED(rv);
+  }
+
   // Ensure the frame did not change during instantiation re-entry (common).
   // HasNewFrame would not have mInstanceOwner yet, so the new frame would be
   // dangling. (Bug 854082)
   nsIFrame* frame = thisContent->GetPrimaryFrame();
   if (frame && mInstanceOwner) {
     mInstanceOwner->SetFrame(static_cast<nsPluginFrame*>(frame));
 
     // Bug 870216 - Adobe Reader renders with incorrect dimensions until it gets
@@ -3140,16 +3153,34 @@ nsObjectLoadingContent::CancelPlayPrevie
   // If we're in play preview state already, reload
   if (mType == eType_Null && mFallbackType == eFallbackPlayPreview) {
     return LoadObject(true, true);
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsObjectLoadingContent::GetRunID(uint32_t* aRunID)
+{
+  if (NS_WARN_IF(!nsContentUtils::IsCallerChrome())) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  if (NS_WARN_IF(!aRunID)) {
+    return NS_ERROR_INVALID_POINTER;
+  }
+  if (!mHasRunID) {
+    // The plugin instance must not have a run ID, so we must
+    // be running the plugin in-process.
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  *aRunID = mRunID;
+  return NS_OK;
+}
+
 static bool sPrefsInitialized;
 static uint32_t sSessionTimeoutMinutes;
 static uint32_t sPersistentTimeoutDays;
 
 bool
 nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType)
 {
   nsresult rv;
--- a/dom/base/nsObjectLoadingContent.h
+++ b/dom/base/nsObjectLoadingContent.h
@@ -228,16 +228,28 @@ class nsObjectLoadingContent : public ns
     {
       aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
     }
     void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
                     const mozilla::dom::Sequence<JS::Value>& aArguments,
                     JS::MutableHandle<JS::Value> aRetval,
                     mozilla::ErrorResult& aRv);
 
+    uint32_t GetRunID(mozilla::ErrorResult& aRv)
+    {
+      uint32_t runID;
+      nsresult rv = GetRunID(&runID);
+      if (NS_FAILED(rv)) {
+        aRv.Throw(rv);
+        return 0;
+      }
+
+      return runID;
+    }
+
   protected:
     /**
      * Begins loading the object when called
      *
      * Attributes of |this| QI'd to nsIContent will be inspected, depending on
      * the node type. This function currently assumes it is a <applet>,
      * <object>, or <embed> tag.
      *
@@ -574,16 +586,19 @@ class nsObjectLoadingContent : public ns
 
 
 
     // Type of the currently-loaded content.
     ObjectType                  mType           : 8;
     // The type of fallback content we're showing (see ObjectState())
     FallbackType                mFallbackType : 8;
 
+    uint32_t                    mRunID;
+    bool                        mHasRunID;
+
     // If true, we have opened a channel as the listener and it has reached
     // OnStartRequest. Does not get set for channels that are passed directly to
     // the plugin listener.
     bool                        mChannelLoaded    : 1;
 
     // Whether we are about to call instantiate on our frame. If we aren't,
     // SetFrame needs to asynchronously call Instantiate.
     bool                        mInstantiating : 1;
--- a/dom/plugins/base/PluginPRLibrary.h
+++ b/dom/plugins/base/PluginPRLibrary.h
@@ -117,16 +117,17 @@ public:
     virtual nsresult ContentsScaleFactorChanged(NPP aInstance, double aContentsScaleFactor) override;
 #endif
     virtual nsresult SetBackgroundUnknown(NPP instance) override;
     virtual nsresult BeginUpdateBackground(NPP instance,
                                            const nsIntRect&, gfxContext** aCtx) override;
     virtual nsresult EndUpdateBackground(NPP instance,
                                          gfxContext* aCtx, const nsIntRect&) override;
     virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
+    virtual nsresult GetRunID(uint32_t* aRunID) override { return NS_ERROR_NOT_IMPLEMENTED; }
 
 private:
     NP_InitializeFunc mNP_Initialize;
     NP_ShutdownFunc mNP_Shutdown;
     NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     NP_GetValueFunc mNP_GetValue;
 #endif
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -1773,8 +1773,27 @@ double
 nsNPAPIPluginInstance::GetContentsScaleFactor()
 {
   double scaleFactor = 1.0;
   if (mOwner) {
     mOwner->GetContentsScaleFactor(&scaleFactor);
   }
   return scaleFactor;
 }
+
+nsresult
+nsNPAPIPluginInstance::GetRunID(uint32_t* aRunID)
+{
+  if (NS_WARN_IF(!aRunID)) {
+    return NS_ERROR_INVALID_POINTER;
+  }
+
+  if (NS_WARN_IF(!mPlugin)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  PluginLibrary* library = mPlugin->GetLibrary();
+  if (!library) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return library->GetRunID(aRunID);
+}
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -281,16 +281,18 @@ public:
 
   // Called when the instance fails to instantiate beceause the Carbon
   // event model is not supported.
   void CarbonNPAPIFailure();
 
   // Returns the contents scale factor of the screen the plugin is drawn on.
   double GetContentsScaleFactor();
 
+  nsresult GetRunID(uint32_t *aRunID);
+
   static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; }
   static void BeginPluginCall(NSPluginCallReentry aReentryState)
   {
     if (aReentryState == NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO) {
       ++gInUnsafePluginCalls;
     }
   }
   static void EndPluginCall(NSPluginCallReentry aReentryState)
--- a/dom/plugins/ipc/PluginLibrary.h
+++ b/dom/plugins/ipc/PluginLibrary.h
@@ -79,14 +79,15 @@ public:
    * PluginInstanceParent.  They approximately follow the ReadbackSink
    * API.
    */
   virtual nsresult SetBackgroundUnknown(NPP instance) = 0;
   virtual nsresult BeginUpdateBackground(NPP instance,
                                          const nsIntRect&, gfxContext**) = 0;
   virtual nsresult EndUpdateBackground(NPP instance,
                                        gfxContext*, const nsIntRect&) = 0;
+  virtual nsresult GetRunID(uint32_t* aRunID) = 0;
 };
 
 
 } // namespace mozilla
 
 #endif  // ifndef mozilla_PluginLibrary_h
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -123,17 +123,17 @@ public:
     void ProcessRemoteNativeEventsInInterruptCall() override;
 
     virtual bool WaitForIPCConnection() { return true; }
 
     nsCString GetHistogramKey() const {
         return mPluginName + mPluginVersion;
     }
 
-    nsresult GetRunID(uint32_t* aRunID);
+    virtual nsresult GetRunID(uint32_t* aRunID) override;
 
 protected:
     virtual mozilla::ipc::RacyInterruptPolicy
     MediateInterruptRace(const Message& parent, const Message& child) override
     {
         return MediateRace(parent, child);
     }
 
--- a/dom/webidl/HTMLObjectElement.webidl
+++ b/dom/webidl/HTMLObjectElement.webidl
@@ -206,16 +206,19 @@ interface MozObjectLoadingContent {
   [ChromeOnly]
   readonly attribute boolean hasRunningPlugin;
 
   /**
    * This method will disable the play-preview plugin state.
    */
   [ChromeOnly, Throws]
   void cancelPlayPreview();
+
+  [ChromeOnly, Throws]
+  readonly attribute unsigned long runID;
 };
 
 /**
  * Name:Value pair type used for passing parameters to NPAPI or javascript
  * plugins.
  */
 dictionary MozPluginParameter {
   DOMString name = "";