Bug 564535 - permission manager needs to be remoted [r=dwitte]
authorAlon Zakai <azakai@mozilla.com>
Thu, 15 Jul 2010 10:04:25 -0400
changeset 47686 9944d9dd6aafab90f3dd7175dd7aa3edc41c2256
parent 47685 dbca2e41b41eb4fbe96b8612e0124278ec50a23a
child 47687 82f84943bf009bf9116b897508dcf63cf03698cc
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdwitte
bugs564535
milestone2.0b2pre
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 564535 - permission manager needs to be remoted [r=dwitte]
dom/ipc/ContentProcessParent.cpp
dom/ipc/ContentProcessParent.h
dom/ipc/PContentProcess.ipdl
extensions/cookie/Makefile.in
extensions/cookie/nsPermissionManager.cpp
--- a/dom/ipc/ContentProcessParent.cpp
+++ b/dom/ipc/ContentProcessParent.cpp
@@ -262,27 +262,56 @@ ContentProcessParent::RecvGetChildList(c
       list->SetCapacity(count);
       for (PRUint32 i = 0; i < count; ++i)
         *(list->AppendElement()) = childArray[i];
     }
         
     return true;
 }
 
+bool
+ContentProcessParent::RecvTestPermission(const IPC::URI&  aUri,
+                                         const nsCString& aType,
+                                         const PRBool&    aExact,
+                                         PRUint32*        retValue)
+{
+    EnsurePermissionService();
+
+    nsCOMPtr<nsIURI> uri = aUri;
+    if (aExact) {
+        mPermissionService->TestExactPermission(uri, aType.get(), retValue);
+    } else {
+        mPermissionService->TestPermission(uri, aType.get(), retValue);
+    }
+    return true;
+}
+
 void
 ContentProcessParent::EnsurePrefService()
 {
     nsresult rv;
     if (!mPrefService) {
         mPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
         NS_ASSERTION(NS_SUCCEEDED(rv), 
                      "We lost prefService in the Chrome process !");
     }
 }
 
+void
+ContentProcessParent::EnsurePermissionService()
+{
+    nsresult rv;
+    if (!mPermissionService) {
+        mPermissionService = do_GetService(
+            NS_PERMISSIONMANAGER_CONTRACTID, &rv);
+        NS_ASSERTION(NS_SUCCEEDED(rv), 
+                     "We lost permissionService in the Chrome process !");
+    }
+}
+
 NS_IMPL_THREADSAFE_ISUPPORTS2(ContentProcessParent,
                               nsIObserver,
                               nsIThreadObserver)
 
 namespace {
 void
 DeleteSubprocess(GeckoChildProcessHost* aSubprocess)
 {
--- a/dom/ipc/ContentProcessParent.h
+++ b/dom/ipc/ContentProcessParent.h
@@ -43,16 +43,17 @@
 
 #include "mozilla/dom/PContentProcessParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "mozilla/Monitor.h"
 #include "nsIPrefService.h"
+#include "nsIPermissionManager.h"
 
 namespace mozilla {
 
 namespace ipc {
 class TestShellParent;
 }
 
 namespace dom {
@@ -131,26 +132,33 @@ private:
             PRBool* retValue, nsresult* rv);
 
     virtual bool RecvPrefIsLocked(const nsCString& prefName,
             PRBool* retValue, nsresult* rv);
 
     virtual bool RecvGetChildList(const nsCString& domain,
             nsTArray<nsCString>* list, nsresult* rv);
 
+    virtual bool RecvTestPermission(const IPC::URI&  aUri,
+                                    const nsCString& aType,
+                                    const PRBool&    aExact,
+                                    PRUint32*        retValue);
+
     void EnsurePrefService();
+    void EnsurePermissionService();
 
     mozilla::Monitor mMonitor;
 
     GeckoChildProcessHost* mSubprocess;
 
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
     nsCOMPtr<nsIThreadObserver> mOldObserver;
 
     bool mIsAlive;
     nsCOMPtr<nsIPrefBranch> mPrefService; 
+    nsCOMPtr<nsIPermissionManager> mPermissionService; 
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/ipc/PContentProcess.ipdl
+++ b/dom/ipc/PContentProcess.ipdl
@@ -37,20 +37,22 @@
  * ***** END LICENSE BLOCK ***** */
 
 include protocol PIFrameEmbedding;
 include protocol PTestShell;
 include protocol PNecko;
 
 include "mozilla/TabTypes.h";
 include "mozilla/chrome/RegistryMessageUtils.h";
+include "mozilla/net/NeckoMessageUtils.h";
 
 using ChromePackage;
 using ResourceMapping;
 using OverrideMapping;
+using IPC::URI;
 
 namespace mozilla {
 namespace dom {
 
 rpc protocol PContentProcess
 {
     manages PIFrameEmbedding;
     manages PTestShell;
@@ -66,21 +68,26 @@ child:
 
     async SetOffline(PRBool offline);
 
     NotifyRemotePrefObserver(nsCString aDomain);
 
 parent:
     PNecko();
 
-    // prefs-related messages ...
+    // Services remoting
+
+    // PrefService messages
     sync GetPrefType(nsCString prefName) returns (PRInt32 retValue, nsresult rv);
     sync GetBoolPref(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync GetIntPref(nsCString prefName)  returns (PRInt32 retValue, nsresult rv);
     sync GetCharPref(nsCString prefName) returns (nsCString retValue, nsresult rv);
     sync GetPrefLocalizedString(nsCString prefName) returns (nsString retValue, nsresult rv);
     sync PrefHasUserValue(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync PrefIsLocked(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync GetChildList(nsCString domain) returns (nsCString[] list, nsresult rv);
+
+    // PermissionsManager messages
+    sync TestPermission(URI uri, nsCString type, PRBool exact) returns (PRUint32 retValue);
 };
 
 }
 }
--- a/extensions/cookie/Makefile.in
+++ b/extensions/cookie/Makefile.in
@@ -72,9 +72,11 @@ EXTRA_DSO_LDOPTS = \
 ifdef MOZ_MAIL_NEWS
 DEFINES += -DMOZ_MAIL_NEWS
 endif
 
 ifdef ENABLE_TESTS
 TOOL_DIRS		+= test
 endif
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -32,16 +32,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifdef MOZ_IPC
+#include "mozilla/dom/ContentProcessChild.h"
+#endif
 #include "nsPermissionManager.h"
 #include "nsPermission.h"
 #include "nsCRT.h"
 #include "nsNetUtil.h"
 #include "nsCOMArray.h"
 #include "nsArrayEnumerator.h"
 #include "nsTArray.h"
 #include "nsReadableUtils.h"
@@ -49,16 +52,51 @@
 #include "nsIIDNService.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "prprf.h"
 #include "mozIStorageService.h"
 #include "mozIStorageStatement.h"
 #include "mozIStorageConnection.h"
 #include "mozStorageHelper.h"
 #include "mozStorageCID.h"
+#include "nsXULAppAPI.h"
+
+#ifdef MOZ_IPC
+static PRBool
+IsChildProcess()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Content;
+}
+
+/**
+ * @returns The child process object, or if we are not in the child
+ *          process, nsnull.
+ */
+static mozilla::dom::ContentProcessChild*
+ChildProcess()
+{
+  if (IsChildProcess()) {
+    mozilla::dom::ContentProcessChild* cpc =
+      mozilla::dom::ContentProcessChild::GetSingleton();
+    if (!cpc)
+      NS_RUNTIMEABORT("Content Process is NULL!");
+    return cpc;
+  }
+
+  return nsnull;
+}
+#endif
+
+#define ENSURE_NOT_CHILD_PROCESS \
+  PR_BEGIN_MACRO \
+  if (IsChildProcess()) { \
+    NS_ERROR("cannot set permission from content process"); \
+    return NS_ERROR_NOT_AVAILABLE; \
+  } \
+  PR_END_MACRO
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #define PL_ARENA_CONST_ALIGN_MASK 3
 #include "plarena.h"
 
 static PLArenaPool *gHostArena = nsnull;
 
@@ -117,16 +155,22 @@ nsresult
 nsPermissionManager::Init()
 {
   nsresult rv;
 
   if (!mHostTable.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
+#ifdef MOZ_IPC
+  // Child will route messages to parent, so no need for further initialization
+  if (IsChildProcess())
+    return NS_OK;
+#endif
+
   // ignore failure here, since it's non-fatal (we can run fine without
   // persistent storage - e.g. if there's no profile).
   // XXX should we tell the user about this?
   InitDB(PR_FALSE);
 
   mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
   if (NS_SUCCEEDED(rv)) {
     mObserverService->AddObserver(this, "profile-before-change", PR_TRUE);
@@ -311,16 +355,20 @@ nsPermissionManager::CreateTable()
 
 NS_IMETHODIMP
 nsPermissionManager::Add(nsIURI     *aURI,
                          const char *aType,
                          PRUint32    aPermission,
                          PRUint32    aExpireType,
                          PRInt64     aExpireTime)
 {
+#ifdef MOZ_IPC
+  ENSURE_NOT_CHILD_PROCESS;
+#endif
+
   NS_ENSURE_ARG_POINTER(aURI);
   NS_ENSURE_ARG_POINTER(aType);
   NS_ENSURE_TRUE(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
                  aExpireType == nsIPermissionManager::EXPIRE_TIME ||
                  aExpireType == nsIPermissionManager::EXPIRE_SESSION,
                  NS_ERROR_INVALID_ARG);
 
   nsresult rv;
@@ -482,32 +530,40 @@ nsPermissionManager::AddInternal(const n
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPermissionManager::Remove(const nsACString &aHost,
                             const char       *aType)
 {
+#ifdef MOZ_IPC
+  ENSURE_NOT_CHILD_PROCESS;
+#endif
+
   NS_ENSURE_ARG_POINTER(aType);
 
   // AddInternal() handles removal, just let it do the work
   return AddInternal(PromiseFlatCString(aHost),
                      nsDependentCString(aType),
                      nsIPermissionManager::UNKNOWN_ACTION,
                      0,
                      nsIPermissionManager::EXPIRE_NEVER,
                      0,
                      eNotify,
                      eWriteToDB);
 }
 
 NS_IMETHODIMP
 nsPermissionManager::RemoveAll()
 {
+#ifdef MOZ_IPC
+  ENSURE_NOT_CHILD_PROCESS;
+#endif
+
   nsresult rv = RemoveAllInternal();
   NotifyObservers(nsnull, NS_LITERAL_STRING("cleared").get());
   return rv;
 }
 
 nsresult
 nsPermissionManager::RemoveAllInternal()
 {
@@ -529,24 +585,38 @@ nsPermissionManager::RemoveAllInternal()
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPermissionManager::TestExactPermission(nsIURI     *aURI,
                                          const char *aType,
                                          PRUint32   *aPermission)
 {
+#ifdef MOZ_IPC
+  mozilla::dom::ContentProcessChild* cpc = ChildProcess();
+  if (cpc) {
+    return cpc->SendTestPermission(IPC::URI(aURI), nsDependentCString(aType), PR_TRUE,
+      aPermission) ? NS_OK : NS_ERROR_FAILURE;
+  }
+#endif
   return CommonTestPermission(aURI, aType, aPermission, PR_TRUE);
 }
 
 NS_IMETHODIMP
 nsPermissionManager::TestPermission(nsIURI     *aURI,
                                     const char *aType,
                                     PRUint32   *aPermission)
 {
+#ifdef MOZ_IPC
+  mozilla::dom::ContentProcessChild* cpc = ChildProcess();
+  if (cpc) {
+    return cpc->SendTestPermission(IPC::URI(aURI), nsDependentCString(aType), PR_FALSE,
+      aPermission) ? NS_OK : NS_ERROR_FAILURE;
+  }
+#endif
   return CommonTestPermission(aURI, aType, aPermission, PR_FALSE);
 }
 
 nsresult
 nsPermissionManager::CommonTestPermission(nsIURI     *aURI,
                                           const char *aType,
                                           PRUint32   *aPermission,
                                           PRBool      aExactHostMatch)
@@ -640,27 +710,35 @@ AddPermissionsToList(nsHostEntry *entry,
     data->array->AppendObject(perm);
   }
 
   return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator **aEnum)
 {
+#ifdef MOZ_IPC
+  ENSURE_NOT_CHILD_PROCESS;
+#endif
+
   // roll an nsCOMArray of all our permissions, then hand out an enumerator
   nsCOMArray<nsIPermission> array;
   nsGetEnumeratorData data(&array, &mTypeArray);
 
   mHostTable.EnumerateEntries(AddPermissionsToList, &data);
 
   return NS_NewArrayEnumerator(aEnum, array);
 }
 
 NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
 {
+#ifdef MOZ_IPC
+  ENSURE_NOT_CHILD_PROCESS;
+#endif
+
   if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     // The profile is about to change,
     // or is going away because the application is shutting down.
     if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
       // clear the permissions file
       RemoveAllInternal();
     } else {
       RemoveAllFromMemory();