Bug 982557 - Migrate old prefs and set apkPackageName after updating app via APK. r=mfinkle, a=sledru
authorMyk Melez <myk@mozilla.org>
Sat, 22 Mar 2014 14:26:43 -0700
changeset 191363 a2c41778abf33c86010b18ea46d9327c846ca096
parent 191362 7a26beae0e476b8beb4b354c188b65a80f66fbc5
child 191364 d46c23f82bfa7075a9c248830f077d2d3150d3f3
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, sledru
bugs982557
milestone30.0a2
Bug 982557 - Migrate old prefs and set apkPackageName after updating app via APK. r=mfinkle, a=sledru
mobile/android/base/webapp/Allocator.java
mobile/android/base/webapp/WebappImpl.java
mobile/android/modules/WebappManager.jsm
--- a/mobile/android/base/webapp/Allocator.java
+++ b/mobile/android/base/webapp/Allocator.java
@@ -6,24 +6,32 @@
 package org.mozilla.gecko.webapp;
 
 import java.util.ArrayList;
 
 import org.mozilla.gecko.GeckoAppShell;
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.util.Log;
 
 public class Allocator {
 
     private final String LOGTAG = "GeckoWebappAllocator";
 
     private static final String PREFIX_ORIGIN = "webapp-origin-";
     private static final String PREFIX_PACKAGE_NAME = "webapp-package-name-";
 
+    // These prefixes are for prefs used by the old shortcut-based runtime.
+    // We define them here so maybeMigrateOldPrefs can migrate them to their
+    // new equivalents if this app was originally installed as a shortcut.
+    // Maybe we can remove this code in the future!
+    private static final String PREFIX_OLD_APP = "app";
+    private static final String PREFIX_OLD_ICON = "icon";
+
     // The number of Webapp# and WEBAPP# activities/apps/intents
     private final static int MAX_WEB_APPS = 100;
 
     protected static Allocator sInstance = null;
     public static Allocator getInstance() {
         return getInstance(GeckoAppShell.getContext());
     }
 
@@ -48,16 +56,24 @@ public class Allocator {
     public static String iconKey(int index) {
         return "web-app-color-" + index;
     }
 
     public static String originKey(int i) {
         return PREFIX_ORIGIN + i;
     }
 
+    private static String oldAppKey(int index) {
+        return PREFIX_OLD_APP + index;
+    }
+
+    private static String oldIconKey(int index) {
+        return PREFIX_OLD_ICON + index;
+    }
+
     public ArrayList<String> getInstalledPackageNames() {
         ArrayList<String> installedPackages = new ArrayList<String>();
 
         for (int i = 0; i < MAX_WEB_APPS; ++i) {
             if (mPrefs.contains(appKey(i))) {
                 installedPackages.add(mPrefs.getString(appKey(i), ""));
             }
         }
@@ -133,9 +149,32 @@ public class Allocator {
 
     public String getOrigin(int index) {
         return mPrefs.getString(originKey(index), null);
     }
 
     public int getColor(int index) {
         return mPrefs.getInt(iconKey(index), -1);
     }
+
+    /**
+     * Migrate old prefs to their new equivalents if this app was originally
+     * installed by the shortcut-based implementation.
+     */
+    public void maybeMigrateOldPrefs(int index) {
+        if (!mPrefs.contains(oldAppKey(index))) {
+            return;
+        }
+
+        Log.i(LOGTAG, "migrating old prefs");
+
+        // The old appKey pref stored the origin, while the new appKey pref
+        // stores the packageName, so we migrate oldAppKey to the origin pref.
+        putOrigin(index, mPrefs.getString(oldAppKey(index), null));
+
+        // The old iconKey pref actually stored the splash screen background
+        // color, so we migrate oldIconKey to the color pref.
+        updateColor(index, mPrefs.getInt(oldIconKey(index), -1));
+
+        // Remove the old prefs so we don't migrate them the next time around.
+        mPrefs.edit().remove(oldAppKey(index)).remove(oldIconKey(index)).apply();
+    }
 }
--- a/mobile/android/base/webapp/WebappImpl.java
+++ b/mobile/android/base/webapp/WebappImpl.java
@@ -95,17 +95,24 @@ public class WebappImpl extends GeckoApp
 
         // start Gecko.
         super.onCreate(savedInstance);
 
         mTitlebarText = (TextView)findViewById(R.id.webapp_title);
         mTitlebar = findViewById(R.id.webapp_titlebar);
         mSplashscreen = findViewById(R.id.splashscreen);
 
-        String origin = Allocator.getInstance(this).getOrigin(getIndex());
+        Allocator allocator = Allocator.getInstance(this);
+        int index = getIndex();
+
+        // We have to migrate old prefs before getting the origin because origin
+        // is one of the prefs we might migrate.
+        allocator.maybeMigrateOldPrefs(index);
+
+        String origin = allocator.getOrigin(index);
         boolean isInstallCompleting = (origin == null);
 
         if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning) || !isInstalled || isInstallCompleting) {
             // Show the splash screen if we need to start Gecko, or we need to install this.
             overridePendingTransition(R.anim.grow_fade_in_center, android.R.anim.fade_out);
             showSplash(true);
         } else {
             mSplashscreen.setVisibility(View.GONE);
--- a/mobile/android/modules/WebappManager.jsm
+++ b/mobile/android/modules/WebappManager.jsm
@@ -240,16 +240,23 @@ this.WebappManager = {
           break;
       }
     });
   },
 
   _autoUpdate: function(aData, aOldApp) { return Task.spawn((function*() {
     debug("_autoUpdate app of type " + aData.type);
 
+    if (aOldApp.apkPackageName != aData.apkPackageName) {
+      // This happens when the app was installed as a shortcut via the old
+      // runtime and is now being updated to an APK.
+      debug("update apkPackageName from " + aOldApp.apkPackageName + " to " + aData.apkPackageName);
+      aOldApp.apkPackageName = aData.apkPackageName;
+    }
+
     if (aData.type == "hosted") {
       let oldManifest = yield DOMApplicationRegistry.getManifestFor(aData.manifestURL);
       DOMApplicationRegistry.updateHostedApp(aData, aOldApp.id, aOldApp, oldManifest, aData.manifest);
     } else {
       DOMApplicationRegistry.updatePackagedApp(aData, aOldApp.id, aOldApp, aData.manifest);
     }
   }).bind(this)); },