Bug 621475: Upgrading Firefox while using third-party theme gives partially themed UI on first run after upgrade. r=robstrong, a=blocks-final
authorDave Townsend <dtownsend@oxymoronical.com>
Tue, 11 Jan 2011 09:43:43 -0800
changeset 60305 3844d838d24afbe1312f0060f31aee3e27b30864
parent 60304 e30ee0ae39b6a0f28289501005a98ddd3d8dcf03
child 60306 d48eb4e9d90301b0a684047109ef4b9cc1e6a2a8
push idunknown
push userunknown
push dateunknown
reviewersrobstrong, blocks-final
bugs621475
milestone2.0b10pre
Bug 621475: Upgrading Firefox while using third-party theme gives partially themed UI on first run after upgrade. r=robstrong, a=blocks-final
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/test/addons/test_bug594058/install.rdf
toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -1357,40 +1357,47 @@ var XPIProvider = {
                                                 true)
     this.checkUpdateSecurity = Prefs.getBoolPref(PREF_EM_CHECK_UPDATE_SECURITY,
                                                  true)
     this.enabledAddons = [];
 
     Services.prefs.addObserver(this.checkCompatibilityPref, this, false);
     Services.prefs.addObserver(PREF_EM_CHECK_UPDATE_SECURITY, this, false);
 
-    this.checkForChanges(aAppChanged);
+    let flushCaches = this.checkForChanges(aAppChanged);
 
     // Changes to installed extensions may have changed which theme is selected
     this.applyThemeChange();
 
     if (Services.prefs.prefHasUserValue(PREF_EM_DISABLED_ADDONS_LIST))
       Services.prefs.clearUserPref(PREF_EM_DISABLED_ADDONS_LIST);
 
     // If the application has been upgraded and there are add-ons outside the
     // application directory then we may need to synchronize compatibility
     // information
     if (aAppChanged && !this.allAppGlobal) {
       // Should we show a UI or just pass the list via a pref?
       if (Prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true)) {
         this.showMismatchWindow();
+        flushCaches = true;
       }
       else if (this.startupChanges.appDisabled.length > 0) {
         // Remember the list of add-ons that were disabled this startup so
         // the application can notify the user however it wants to
         Services.prefs.setCharPref(PREF_EM_DISABLED_ADDONS_LIST,
                                    this.startupChanges.appDisabled.join(","));
       }
     }
 
+    if (flushCaches) {
+      // Init this, so it will get the notification.
+      let xulPrototypeCache = Cc["@mozilla.org/xul/xul-prototype-cache;1"].getService(Ci.nsISupports);
+      Services.obs.notifyObservers(null, "startupcache-invalidate", null);
+    }
+
     this.enabledAddons = Prefs.getCharPref(PREF_EM_ENABLED_ADDONS, "");
     if ("nsICrashReporter" in Ci &&
         Services.appinfo instanceof Ci.nsICrashReporter) {
       // Annotate the crash report with relevant add-on information.
       try {
         Services.appinfo.annotateCrashReport("Theme", this.currentSkin);
       } catch (e) { }
       try {
@@ -2263,21 +2270,16 @@ var XPIProvider = {
         changed = removeMetadata(aLocation, aOldAddon) || changed;
       }, this);
     }, this);
 
     // Cache the new install location states
     cache = JSON.stringify(this.getInstallLocationStates());
     Services.prefs.setCharPref(PREF_INSTALL_CACHE, cache);
 
-    if (changed) {
-      // Init this, so it will get the notification.
-      let xulPrototypeCache = Cc["@mozilla.org/xul/xul-prototype-cache;1"].getService(Ci.nsISupports);
-      Services.obs.notifyObservers(null, "startupcache-invalidate", null);
-    }
     return changed;
   },
 
   /**
    * Imports the xpinstall permissions from preferences into the permissions
    * manager for the user to change later.
    */
   importPermissions: function XPI_importPermissions() {
@@ -2415,17 +2417,17 @@ var XPIProvider = {
       if (extensionListChanged || hasPendingChanges) {
         LOG("Updating database with changes to installed add-ons");
         XPIDatabase.updateActiveAddons();
         XPIDatabase.commitTransaction();
         XPIDatabase.writeAddonsList();
         Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
         Services.prefs.setCharPref(PREF_BOOTSTRAP_ADDONS,
                                    JSON.stringify(this.bootstrappedAddons));
-        return;
+        return true;
       }
 
       LOG("No changes found");
       XPIDatabase.commitTransaction();
     }
     catch (e) {
       ERROR("Error during startup file checks, rolling back any database " +
             "changes", e);
@@ -2434,16 +2436,18 @@ var XPIProvider = {
 
     // Check that the add-ons list still exists
     let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
                                        true);
     if (!addonsList.exists()) {
       LOG("Add-ons list is missing, recreating");
       XPIDatabase.writeAddonsList();
     }
+
+    return false;
   },
 
   /**
    * Called to test whether this provider supports installing a particular
    * mimetype.
    *
    * @param  aMimetype
    *         The mimetype to check for
--- a/toolkit/mozapps/extensions/test/addons/test_bug594058/install.rdf
+++ b/toolkit/mozapps/extensions/test/addons/test_bug594058/install.rdf
@@ -6,16 +6,16 @@
   <Description about="urn:mozilla:install-manifest">
     <em:id>bug594058@tests.mozilla.org</em:id>
     <em:version>1.0</em:version>
     
     <em:targetApplication>
       <Description>
         <em:id>xpcshell@tests.mozilla.org</em:id>
         <em:minVersion>1</em:minVersion>
-        <em:maxVersion>1</em:maxVersion>
+        <em:maxVersion>2</em:maxVersion>
       </Description>
     </em:targetApplication>
     <em:name>bug 594058</em:name>
     <em:description>stat-based invalidation</em:description>
     <em:unpack>true</em:unpack>
   </Description>      
 </RDF>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
@@ -2,79 +2,118 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // This tests is modifying a file in an unpacked extension
 // causes cache invalidation.
 
 // Disables security checking our updates which haven't been signed
 Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
+// Allow the mismatch UI to show
+Services.prefs.setBoolPref("extensions.showMismatchUI", true);
 
 const Ci = Components.interfaces;
 const extDir = gProfD.clone();
 extDir.append("extensions");
 
 var gFastLoadService = AM_Cc["@mozilla.org/fast-load-service;1"].
                        getService(AM_Ci.nsIFastLoadService);
 var gFastLoadFile = null;
 
+var gCachePurged = false;
+
+// Override the window watcher
+var WindowWatcher = {
+  openWindow: function(parent, url, name, features, arguments) {
+    do_check_false(gCachePurged);
+  },
+
+  QueryInterface: function(iid) {
+    if (iid.equals(Ci.nsIWindowWatcher)
+     || iid.equals(Ci.nsISupports))
+      return this;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  }
+}
+
+var WindowWatcherFactory = {
+  createInstance: function createInstance(outer, iid) {
+    if (outer != null)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return WindowWatcher.QueryInterface(iid);
+  }
+};
+
+var registrar = Components.manager.QueryInterface(AM_Ci.nsIComponentRegistrar);
+registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"),
+                          "Fake Window Watcher",
+                          "@mozilla.org/embedcomp/window-watcher;1", WindowWatcherFactory);
+
 /**
  * Start the test by installing extensions.
  */
 function run_test() {
   do_test_pending();
-  let cachePurged = false;
+  gCachePurged = false;
 
   let obs = AM_Cc["@mozilla.org/observer-service;1"].
     getService(AM_Ci.nsIObserverService);
   obs.addObserver({
     observe: function(aSubject, aTopic, aData) {
-      cachePurged = true;
+      gCachePurged = true;
     }
   }, "startupcache-invalidate", false);
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
 
   gFastLoadFile = gFastLoadService.newFastLoadFile("XUL");
   do_check_false(gFastLoadFile.exists());
   gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   startupManager();
   // nsAppRunner takes care of clearing this when a new app is installed
   do_check_true(gFastLoadFile.exists());
+  do_check_false(gCachePurged);
 
   installAllFiles([do_get_addon("test_bug594058")], function() {
     restartManager();
     do_check_false(gFastLoadFile.exists());
     gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-    do_check_true(cachePurged);
-    cachePurged = false;
+    do_check_true(gCachePurged);
+    gCachePurged = false;
 
     // Now, make it look like we've updated the file. First, start the EM
     // so it records the bogus old time, then update the file and restart.
     let extFile = extDir.clone();
     let pastTime = extFile.lastModifiedTime - 5000;
     extFile.append("bug594058@tests.mozilla.org");
     setExtensionModifiedTime(extFile, pastTime);
     let otherFile = extFile.clone();
     otherFile.append("directory");
     otherFile.lastModifiedTime = pastTime;
     otherFile.append("file1");
     otherFile.lastModifiedTime = pastTime;
 
     restartManager();
     do_check_false(gFastLoadFile.exists());
     gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-    cachePurged = false;
+    gCachePurged = false;
 
     otherFile.lastModifiedTime = pastTime + 5000;
     restartManager();
     do_check_false(gFastLoadFile.exists());
     gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-    do_check_true(cachePurged);
-    cachePurged = false;
+    do_check_true(gCachePurged);
+    gCachePurged = false;
 
     restartManager();
     do_check_true(gFastLoadFile.exists());
-    do_check_false(cachePurged);
+    do_check_false(gCachePurged);
+
+    // Upgrading the app should force a cache flush due to potentially showing
+    // the compatibility UI
+    restartManager("2");
+    do_check_true(gCachePurged);
+    gCachePurged = false;
 
     do_test_finished();
   });  
 }