Bug 741246: Simplify plugin instance creation and initialization (further). r=jst
authorJosh Aas <joshmoz@gmail.com>
Mon, 02 Apr 2012 15:17:34 -0400
changeset 90861 029a32f787e928b8b415992231c5a5291d24b54b
parent 90860 2a976fea1a9dd8c3152320be61a265e0a7a6c535
child 90862 c7ce0c86d5e86497deae66b8824dd51d2d6bbecd
push idunknown
push userunknown
push dateunknown
reviewersjst
bugs741246
milestone14.0a1
Bug 741246: Simplify plugin instance creation and initialization (further). r=jst
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginHost.cpp
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -73,44 +73,40 @@
 using namespace mozilla;
 using namespace mozilla::plugins::parent;
 
 static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
 static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
 
 NS_IMPL_THREADSAFE_ISUPPORTS0(nsNPAPIPluginInstance)
 
-nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
+nsNPAPIPluginInstance::nsNPAPIPluginInstance()
   :
     mDrawingModel(kDefaultDrawingModel),
 #ifdef MOZ_WIDGET_ANDROID
     mSurface(nsnull),
     mANPDrawingModel(0),
     mOnScreen(true),
 #endif
     mRunning(NOT_STARTED),
     mWindowless(false),
     mTransparent(false),
     mCached(false),
     mUsesDOMForCursor(false),
     mInPluginInitCall(false),
-    mPlugin(plugin),
+    mPlugin(nsnull),
     mMIMEType(nsnull),
     mOwner(nsnull),
     mCurrentPluginEvent(nsnull),
 #if defined(MOZ_X11) || defined(XP_WIN) || defined(XP_MACOSX)
     mUsePluginLayersPref(true)
 #else
     mUsePluginLayersPref(false)
 #endif
 {
-  NS_ASSERTION(mPlugin != NULL, "Plugin is required when creating an instance.");
-
-  // Initialize the NPP structure.
-
   mNPP.pdata = NULL;
   mNPP.ndata = this;
 
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefs) {
     bool useLayersPref;
     nsresult rv = prefs->GetBoolPref("plugins.use_layers", &useLayersPref);
     if (NS_SUCCEEDED(rv))
@@ -138,40 +134,34 @@ nsNPAPIPluginInstance::Destroy()
 }
 
 TimeStamp
 nsNPAPIPluginInstance::StopTime()
 {
   return mStopTime;
 }
 
-nsresult nsNPAPIPluginInstance::Initialize(nsIPluginInstanceOwner* aOwner, const char* aMIMEType)
+nsresult nsNPAPIPluginInstance::Initialize(nsNPAPIPlugin *aPlugin, nsIPluginInstanceOwner* aOwner, const char* aMIMEType)
 {
   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this));
 
+  NS_ENSURE_ARG_POINTER(aPlugin);
+  NS_ENSURE_ARG_POINTER(aOwner);
+
+  mPlugin = aPlugin;
   mOwner = aOwner;
 
   if (aMIMEType) {
     mMIMEType = (char*)PR_Malloc(PL_strlen(aMIMEType) + 1);
-
-    if (mMIMEType)
+    if (mMIMEType) {
       PL_strcpy(mMIMEType, aMIMEType);
+    }
   }
 
-  return InitializePlugin();
-}
-
-nsresult nsNPAPIPluginInstance::Start()
-{
-  PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Start this=%p\n",this));
-
-  if (RUNNING == mRunning)
-    return NS_OK;
-
-  return InitializePlugin();
+  return Start();
 }
 
 nsresult nsNPAPIPluginInstance::Stop()
 {
   PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Stop this=%p\n",this));
 
   // Make sure the plugin didn't leave popups enabled.
   if (mPopupStates.Length() > 0) {
@@ -311,18 +301,22 @@ nsNPAPIPluginInstance::StreamListeners()
 
 nsTArray<nsPluginStreamListenerPeer*>*
 nsNPAPIPluginInstance::FileCachedStreamListeners()
 {
   return &mFileCachedStreamListeners;
 }
 
 nsresult
-nsNPAPIPluginInstance::InitializePlugin()
-{ 
+nsNPAPIPluginInstance::Start()
+{
+  if (mRunning == RUNNING) {
+    return NS_OK;
+  }
+
   PluginDestructionGuard guard(this);
 
   PRUint16 count = 0;
   const char* const* names = nsnull;
   const char* const* values = nsnull;
   nsPluginTagType tagtype;
   nsresult rv = GetTagType(&tagtype);
   if (NS_SUCCEEDED(rv)) {
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -89,17 +89,17 @@ public:
 class nsNPAPIPluginInstance : public nsISupports
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public:
   NS_DECL_ISUPPORTS
 
-  nsresult Initialize(nsIPluginInstanceOwner* aOwner, const char* aMIMEType);
+  nsresult Initialize(nsNPAPIPlugin *aPlugin, nsIPluginInstanceOwner* aOwner, const char* aMIMEType);
   nsresult Start();
   nsresult Stop();
   nsresult SetWindow(NPWindow* window);
   nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result);
   nsresult Print(NPPrint* platformPrint);
 #ifdef MOZ_WIDGET_ANDROID
   nsresult PostEvent(void* event) { return 0; };
 #endif
@@ -171,17 +171,17 @@ public:
   void* GetJavaSurface();
   void SetJavaSurface(void* aSurface);
   void RequestJavaSurface();
 #endif
 
   nsresult NewStreamListener(const char* aURL, void* notifyData,
                              nsIPluginStreamListener** listener);
 
-  nsNPAPIPluginInstance(nsNPAPIPlugin* plugin);
+  nsNPAPIPluginInstance();
   virtual ~nsNPAPIPluginInstance();
 
   // To be called when an instance becomes orphaned, when
   // it's plugin is no longer guaranteed to be around.
   void Destroy();
 
   // Indicates whether the plugin is running normally.
   bool IsRunning() {
@@ -228,17 +228,16 @@ public:
   NPError FinalizeAsyncSurface(NPAsyncSurface *surface);
   void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed);
 
   // Called when the instance fails to instantiate beceause the Carbon
   // event model is not supported.
   void CarbonNPAPIFailure();
 
 protected:
-  nsresult InitializePlugin();
 
   nsresult GetTagType(nsPluginTagType *result);
   nsresult GetAttributes(PRUint16& n, const char*const*& names,
                          const char*const*& values);
   nsresult GetParameters(PRUint16& n, const char*const*& names,
                          const char*const*& values);
   nsresult GetMode(PRInt32 *result);
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -1289,52 +1289,27 @@ nsPluginHost::TrySetUpPluginInstance(con
   NS_ASSERTION(pluginTag, "Must have plugin tag here!");
 
   nsRefPtr<nsNPAPIPlugin> plugin;
   GetPlugin(mimetype, getter_AddRefs(plugin));
   if (!plugin) {
     return NS_ERROR_FAILURE;
   }
 
-#if defined(XP_WIN)
-  static BOOL firstJavaPlugin = FALSE;
-  BOOL restoreOrigDir = FALSE;
-  WCHAR origDir[_MAX_PATH];
-  if (pluginTag->mIsJavaPlugin && !firstJavaPlugin) {
-    DWORD dw = GetCurrentDirectoryW(_MAX_PATH, origDir);
-    NS_ASSERTION(dw <= _MAX_PATH, "Failed to obtain the current directory, which may lead to incorrect class loading");
-    nsCOMPtr<nsIFile> binDirectory;
-    nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
-                                         getter_AddRefs(binDirectory));
-
-    if (NS_SUCCEEDED(rv)) {
-      nsAutoString path;
-      binDirectory->GetPath(path);
-      restoreOrigDir = SetCurrentDirectoryW(path.get());
-    }
-  }
-#endif
-
-  nsRefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance(plugin.get());
-
-#if defined(XP_WIN)
-  if (!firstJavaPlugin && restoreOrigDir) {
-    BOOL bCheck = SetCurrentDirectoryW(origDir);
-    NS_ASSERTION(bCheck, "Error restoring directory");
-    firstJavaPlugin = TRUE;
-  }
-#endif
-
-  // it is adreffed here
+  nsRefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance();
+
+  // This will create the owning reference. The connection must be made between the
+  // instance and the instance owner before initialization. Plugins can call into
+  // the browser during initialization.
   aOwner->SetInstance(instance.get());
 
   // this should not addref the instance or owner
   // except in some cases not Java, see bug 140931
   // our COM pointer will free the peer
-  nsresult rv = instance->Initialize(aOwner, mimetype);
+  nsresult rv = instance->Initialize(plugin.get(), aOwner, mimetype);
   if (NS_FAILED(rv)) {
     aOwner->SetInstance(nsnull);
     return rv;
   }
 
   // Cancel the plugin unload timer since we are creating
   // an instance for it.
   if (pluginTag->mUnloadTimer) {