Bug 616414: Notify content processes when a pref has been cleared. r=dwitte
authorChris Jones <jones.chris.g@gmail.com>
Wed, 05 Jan 2011 22:54:47 -0600
changeset 60063 549be0618b0aa2a0b69a8d64e9c6d5425e33d7ca
parent 60062 dfafc2c2551e6b4a30400ab82e6805524c1bc9a0
child 60064 79c44d25229d7bdb81f5c29ba4cc35c676a03efc
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersdwitte
bugs616414
milestone2.0b9pre
Bug 616414: Notify content processes when a pref has been cleared. r=dwitte
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/PContent.ipdl
modules/libpref/public/nsIPrefService.idl
modules/libpref/src/nsPrefService.cpp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -488,16 +488,28 @@ ContentChild::RecvPreferenceUpdate(const
         return false;
 
     prefs->SetPreference(&aPref);
 
     return true;
 }
 
 bool
+ContentChild::RecvClearUserPreference(const nsCString& aPrefName)
+{
+    nsCOMPtr<nsIPrefServiceInternal> prefs = do_GetService("@mozilla.org/preferences-service;1");
+    if (!prefs)
+        return false;
+
+    prefs->ClearContentPref(aPrefName);
+
+    return true;
+}
+
+bool
 ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData)
 {
     for (PRUint32 i = 0; i < mAlertObservers.Length();
          /*we mutate the array during the loop; ++i iff no mutation*/) {
         AlertObserver* observer = mAlertObservers[i];
         if (observer->Observes(aData) && observer->Notify(aType)) {
             // if aType == alertfinished, this alert is done.  we can
             // remove the observer.
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -113,16 +113,17 @@ public:
 
     virtual bool RecvSetOffline(const PRBool& offline);
 
     virtual bool RecvNotifyVisited(const IPC::URI& aURI);
     // auto remove when alertfinished is received.
     nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
 
     virtual bool RecvPreferenceUpdate(const PrefTuple& aPref);
+    virtual bool RecvClearUserPreference(const nsCString& aPrefName);
 
     virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
 
     virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
 
     virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
 
     virtual bool RecvAddPermission(const IPC::Permission& permission);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -367,24 +367,36 @@ ContentParent::Observe(nsISupports* aSub
     if (!strcmp(aTopic, "memory-pressure")) {
         SendFlushMemory(nsDependentString(aData));
     }
     // listening for remotePrefs...
     else if (!strcmp(aTopic, "nsPref:changed")) {
         // We know prefs are ASCII here.
         NS_LossyConvertUTF16toASCII strData(aData);
 
-        PrefTuple pref;
         nsCOMPtr<nsIPrefServiceInternal> prefService =
           do_GetService("@mozilla.org/preferences-service;1");
 
-        prefService->MirrorPreference(strData, &pref);
-
-        if (!SendPreferenceUpdate(pref))
-            return NS_ERROR_NOT_AVAILABLE;
+        PRBool prefHasValue;
+        prefService->PrefHasUserValue(strData, &prefHasValue);
+        if (prefHasValue) {
+            // Pref was created, or previously existed and its value
+            // changed.
+            PrefTuple pref;
+            nsresult rv = prefService->MirrorPreference(strData, &pref);
+            NS_ASSERTION(NS_SUCCEEDED(rv), "Pref has value but can't mirror?");
+            if (!SendPreferenceUpdate(pref)) {
+                return NS_ERROR_NOT_AVAILABLE;
+            }
+        } else {
+            // Pref wasn't found.  It was probably removed.
+            if (!SendClearUserPreference(strData)) {
+                return NS_ERROR_NOT_AVAILABLE;
+            }
+        }
     }
     else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
       NS_ConvertUTF16toUTF8 dataStr(aData);
       const char *offline = dataStr.get();
       if (!SendSetOffline(!strcmp(offline, "true") ? true : false))
           return NS_ERROR_NOT_AVAILABLE;
     }
     // listening for alert notifications
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -99,16 +99,17 @@ child:
     RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                    OverrideMapping[] overrides);
 
     async SetOffline(PRBool offline);
 
     async NotifyVisited(URI uri);
 
     PreferenceUpdate(PrefTuple pref);
+    ClearUserPreference(nsCString prefName);
 
     NotifyAlertsObserver(nsCString topic, nsString data);
 
     GeolocationUpdate(GeoPosition somewhere);
 
     // nsIPermissionManager messages
     AddPermission(Permission permission);
 
--- a/modules/libpref/public/nsIPrefService.idl
+++ b/modules/libpref/public/nsIPrefService.idl
@@ -158,17 +158,17 @@ interface nsIPrefService : nsISupports
    * @return nsIPrefBranch The object representing the requested default branch.
    *
    * @see getBranch
    */
   nsIPrefBranch getDefaultBranch(in string aPrefRoot);
 
 };
 
-[scriptable, uuid(37577836-e3fc-4a5e-b5d1-92a17fe0e7f7)]
+[scriptable, uuid(08c8cd2f-8345-45ee-938d-37ee6d3661b2)]
 interface nsIPrefServiceInternal : nsISupports
 {
   /**
    * Called to read the preferences in the defaults/preferences/
    * directory of a zip file
    *
    * @param aFile The zip file to be read.
    *
@@ -176,17 +176,19 @@ interface nsIPrefServiceInternal : nsISu
    * @return Other The file failed to read or contained invalid data.
    *
    * @see readUserPrefs
    */
   void readExtensionPrefs(in nsILocalFile aFile);
 
   [noscript] void mirrorPreferences(in nsPreferencesArrayPtr aArray);
   [noscript] void mirrorPreference(in ACString aPrefName, in nsPreferencePtr aPref);
+  [noscript] boolean prefHasUserValue(in ACString aPrefName);
   [noscript] void setPreference(in nsPreferencePtrConst aPref);
+  [noscript] void clearContentPref(in ACString aPrefName);
 };
 
 %{C++
 
 #define NS_PREFSERVICE_CID                             \
   { /* {1cd91b88-1dd2-11b2-92e1-ed22ed298000} */       \
     0x91ca2441,                                        \
     0x050f,                                            \
--- a/modules/libpref/src/nsPrefService.cpp
+++ b/modules/libpref/src/nsPrefService.cpp
@@ -345,21 +345,33 @@ NS_IMETHODIMP nsPrefService::ReadExtensi
         break;
       }
     }
     PREF_FinalizeParseState(&ps);
   }
   return rv;
 }
 
+NS_IMETHODIMP nsPrefService::PrefHasUserValue(const nsACString& aPrefName,
+                                              PRBool* aHasValue)
+{
+  *aHasValue = PREF_HasUserPref(aPrefName.BeginReading());
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsPrefService::SetPreference(const PrefTuple *aPref)
 {
   return pref_SetPrefTuple(*aPref, PR_TRUE);
 }
 
+NS_IMETHODIMP nsPrefService::ClearContentPref(const nsACString& aPrefName)
+{
+  return PREF_ClearUserPref(aPrefName.BeginReading());
+}
+
 NS_IMETHODIMP nsPrefService::MirrorPreference(const nsACString& aPrefName,
                                               PrefTuple *aPref)
 {
   PrefHashEntry *pref = pref_HashTableLookup(nsDependentCString(aPrefName).get());
 
   if (!pref)
     return NS_ERROR_NOT_AVAILABLE;