Bug 887118 - Cannot update an preinstalled packaged app (signed or otherwise) to a signed packaged app. r=ferjm
authorAntonio M. Amaya <amac@tid.es>
Wed, 26 Jun 2013 14:18:34 +0200
changeset 137212 1d8be4df9c73ea56fa45464b947e7282772ddf76
parent 137211 ebab7be41e5874930cbb48c51da7911c3a7572db
child 137213 245d3c63d38eb2a7e719b071096513aebd0b10a7
push idunknown
push userunknown
push dateunknown
reviewersferjm
bugs887118
milestone25.0a1
Bug 887118 - Cannot update an preinstalled packaged app (signed or otherwise) to a signed packaged app. r=ferjm
dom/apps/src/Webapps.jsm
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -74,16 +74,23 @@ XPCOMUtils.defineLazyGetter(this, "updat
   const DIRECTORY_NAME = "webappsDir";
 #else
   // If we're executing in the context of the webapp runtime, the data files
   // are in a different directory (currently the Firefox profile that installed
   // the webapp); otherwise, they're in the current profile.
   const DIRECTORY_NAME = WEBAPP_RUNTIME ? "WebappRegD" : "ProfD";
 #endif
 
+// We'll use this to identify privileged apps that have been preinstalled
+// For those apps we'll set
+// STORE_ID_PENDING_PREFIX + installOrigin
+// as the storeID. This ensures it's unique and can't be set from a legit
+// store even by error.
+const STORE_ID_PENDING_PREFIX = "#unknownID#";
+
 this.DOMApplicationRegistry = {
   appsFile: null,
   webapps: { },
   children: [ ],
   allAppsLaunchable: false,
 #ifdef MOZ_OFFICIAL_BRANDING
   get allowSideloadingCertified() false,
 #else
@@ -341,16 +348,21 @@ this.DOMApplicationRegistry = {
                             .path;
 
     if (!isPackage) {
       return;
     }
 
     app.origin = "app://" + aId;
 
+    // Do this for all preinstalled apps... we can't know at this
+    // point if the updates will be signed or not and it doesn't
+    // hurt to have it always.
+    app.storeId = STORE_ID_PENDING_PREFIX + app.installOrigin;
+
     // Extract the manifest.webapp file from application.zip.
     let zipFile = baseDir.clone();
     zipFile.append("application.zip");
     let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
                       .createInstance(Ci.nsIZipReader);
     try {
       debug("Opening " + zipFile.path);
       zipReader.open(zipFile);
@@ -2248,38 +2260,42 @@ this.DOMApplicationRegistry = {
     }
 
     // aStoreId must be a string of the form
     //   <installOrigin>#<storeId from ids.json>
     // aStoreVersion must be a positive integer.
     function checkForStoreIdMatch(aStoreId, aStoreVersion) {
       // Things to check:
       // 1. if it's a update:
-      //   a. We should already have this storeId
+      //   a. We should already have this storeId, or the original storeId must start
+      //      with STORE_ID_PENDING_PREFIX
       //   b. The manifestURL for the stored app should be the same one we're
       //      updating
       //   c. And finally the version of the update should be higher than the one
       //      on the already installed package
       // 2. else
       //   a. We should not have this storeId on the list
       // We're currently launching WRONG_APP_STORE_ID for all the mismatch kind of
       // errors, and APP_STORE_VERSION_ROLLBACK for the version error.
 
       // Does an app with this storeID exist already?
       let appId = self.getAppLocalIdByStoreId(aStoreId);
       let isInstalled = appId != Ci.nsIScriptSecurityManager.NO_APP_ID;
       if (aIsUpdate) {
-        if (!isInstalled || (app.localId !== appId)) {
-          // If we don't have the storeId on track already, this
-          // cannot be an update
+        let isDifferent = app.localId !== appId;
+        let isPending = app.storeId.indexOf(STORE_ID_PENDING_PREFIX) == 0;
+
+        if ((!isInstalled && !isPending) || (isInstalled && isDifferent)) {
           throw "WRONG_APP_STORE_ID";
         }
-        if (app.storeVersion >= aStoreVersion) {
+
+        if (!isPending && (app.storeVersion >= aStoreVersion)) {
           throw "APP_STORE_VERSION_ROLLBACK";
         }
+
       } else if (isInstalled) {
         throw "WRONG_APP_STORE_ID";
       }
     }
 
     function download() {
       debug("About to download " + aManifest.fullPackagePath());