Bug 988437 - Part 1: Allow unpickling across Android Account types; bump pickle version. r=rnewman, a=sylvestre
authorNick Alexander <nalexander@mozilla.com>
Wed, 09 Apr 2014 09:20:15 -0700
changeset 183685 5dfea367b8b9
parent 183684 968f7b3ff551
child 183686 47c8852fde22
push id3446
push usernalexander@mozilla.com
push date2014-04-09 16:21 +0000
Treeherderresults
reviewersrnewman, sylvestre
bugs988437
milestone29.0
Bug 988437 - Part 1: Allow unpickling across Android Account types; bump pickle version. r=rnewman, a=sylvestre
mobile/android/base/fxa/authenticator/AccountPickler.java
--- a/mobile/android/base/fxa/authenticator/AccountPickler.java
+++ b/mobile/android/base/fxa/authenticator/AccountPickler.java
@@ -49,17 +49,17 @@ import android.content.Context;
  * <p>
  * Problem: <a href="http://code.google.com/p/android/issues/detail?id=8485">that intent doesn't work</a>!
  * <p>
  * See bug 768102 for more information in the context of Sync.
  */
 public class AccountPickler {
   public static final String LOG_TAG = AccountPickler.class.getSimpleName();
 
-  public static final long PICKLE_VERSION = 1;
+  public static final long PICKLE_VERSION = 2;
 
   private static final String KEY_PICKLE_VERSION = "pickle_version";
   private static final String KEY_PICKLE_TIMESTAMP = "pickle_timestamp";
 
   private static final String KEY_ACCOUNT_VERSION = "account_version";
   private static final String KEY_ACCOUNT_TYPE = "account_type";
   private static final String KEY_EMAIL = "email";
   private static final String KEY_PROFILE = "profile";
@@ -211,36 +211,54 @@ public class AccountPickler {
     private static UnpickleParams fromJSON(final ExtendedJSONObject json)
         throws InvalidKeySpecException, NoSuchAlgorithmException, NonObjectJSONException {
       final UnpickleParams params = new UnpickleParams();
       params.pickleVersion = json.getLong(KEY_PICKLE_VERSION);
       if (params.pickleVersion == null) {
         throw new IllegalStateException("Pickle version not found.");
       }
 
+      /*
+       * Version 1 and version 2 are identical, except version 2 throws if the
+       * internal Android Account type has changed. Version 1 used to throw in
+       * this case, but we intentionally used the pickle file to migrate across
+       * Account types, bumping the version simultaneously.
+       */
       switch (params.pickleVersion.intValue()) {
-        case 1:
+        case 2: {
+          // Sanity check.
+          final String accountType = json.getString(KEY_ACCOUNT_TYPE);
+          if (!FxAccountConstants.ACCOUNT_TYPE.equals(accountType)) {
+            throw new IllegalStateException("Account type has changed from " + accountType + " to " + FxAccountConstants.ACCOUNT_TYPE + ".");
+          }
+
           params.unpickleV1(json);
-          break;
+        }
+        break;
+
+        case 1: {
+          // Warn about account type changing, but don't throw over it.
+          final String accountType = json.getString(KEY_ACCOUNT_TYPE);
+          if (!FxAccountConstants.ACCOUNT_TYPE.equals(accountType)) {
+            Logger.warn(LOG_TAG, "Account type has changed from " + accountType + " to " + FxAccountConstants.ACCOUNT_TYPE + "; ignoring.");
+          }
+
+          params.unpickleV1(json);
+        }
+        break;
 
         default:
           throw new IllegalStateException("Unknown pickle version, " + params.pickleVersion + ".");
       }
 
       return params;
     }
 
     private void unpickleV1(final ExtendedJSONObject json)
         throws NonObjectJSONException, NoSuchAlgorithmException, InvalidKeySpecException {
-      // Sanity check.
-      final String accountType = json.getString(KEY_ACCOUNT_TYPE);
-      if (!FxAccountConstants.ACCOUNT_TYPE.equals(accountType)) {
-        throw new IllegalStateException("Account type has changed from, " + accountType +
-            ", to, " + FxAccountConstants.ACCOUNT_TYPE + ".");
-      }
 
       this.accountVersion = json.getIntegerSafely(KEY_ACCOUNT_VERSION);
       this.email = json.getString(KEY_EMAIL);
       this.profile = json.getString(KEY_PROFILE);
       this.idpServerURI = json.getString(KEY_IDP_SERVER_URI);
       this.tokenServerURI = json.getString(KEY_TOKEN_SERVER_URI);
       this.isSyncingEnabled = json.getBoolean(KEY_IS_SYNCING_ENABLED);