mobile/android/base/fxa/receivers/FxAccountUpgradeReceiver.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.fxa.receivers;
michael@0 6
michael@0 7 import java.util.LinkedList;
michael@0 8 import java.util.List;
michael@0 9 import java.util.concurrent.Executor;
michael@0 10 import java.util.concurrent.Executors;
michael@0 11
michael@0 12 import org.mozilla.gecko.background.common.log.Logger;
michael@0 13 import org.mozilla.gecko.fxa.FirefoxAccounts;
michael@0 14 import org.mozilla.gecko.fxa.FxAccountConstants;
michael@0 15 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
michael@0 16 import org.mozilla.gecko.fxa.login.State;
michael@0 17 import org.mozilla.gecko.fxa.login.State.StateLabel;
michael@0 18 import org.mozilla.gecko.sync.Utils;
michael@0 19
michael@0 20 import android.accounts.Account;
michael@0 21 import android.content.BroadcastReceiver;
michael@0 22 import android.content.Context;
michael@0 23 import android.content.Intent;
michael@0 24
michael@0 25 /**
michael@0 26 * A receiver that takes action when our Android package is upgraded (replaced).
michael@0 27 */
michael@0 28 public class FxAccountUpgradeReceiver extends BroadcastReceiver {
michael@0 29 private static final String LOG_TAG = FxAccountUpgradeReceiver.class.getSimpleName();
michael@0 30
michael@0 31 /**
michael@0 32 * Produce a list of Runnable instances to be executed sequentially on
michael@0 33 * upgrade.
michael@0 34 * <p>
michael@0 35 * Each Runnable will be executed sequentially on a background thread. Any
michael@0 36 * unchecked Exception thrown will be caught and ignored.
michael@0 37 *
michael@0 38 * @param context Android context.
michael@0 39 * @return list of Runnable instances.
michael@0 40 */
michael@0 41 protected List<Runnable> onUpgradeRunnables(Context context) {
michael@0 42 List<Runnable> runnables = new LinkedList<Runnable>();
michael@0 43 runnables.add(new MaybeUnpickleRunnable(context));
michael@0 44 // Recovering accounts that are in the Doghouse should happen *after* we
michael@0 45 // unpickle any accounts saved to disk.
michael@0 46 runnables.add(new AdvanceFromDoghouseRunnable(context));
michael@0 47 return runnables;
michael@0 48 }
michael@0 49
michael@0 50 @Override
michael@0 51 public void onReceive(final Context context, Intent intent) {
michael@0 52 Logger.setThreadLogTag(FxAccountConstants.GLOBAL_LOG_TAG);
michael@0 53 Logger.info(LOG_TAG, "Upgrade broadcast received.");
michael@0 54
michael@0 55 // Iterate Runnable instances one at a time.
michael@0 56 final Executor executor = Executors.newSingleThreadExecutor();
michael@0 57 for (final Runnable runnable : onUpgradeRunnables(context)) {
michael@0 58 executor.execute(new Runnable() {
michael@0 59 @Override
michael@0 60 public void run() {
michael@0 61 try {
michael@0 62 runnable.run();
michael@0 63 } catch (Exception e) {
michael@0 64 // We really don't want to throw on a background thread, so we
michael@0 65 // catch, log, and move on.
michael@0 66 Logger.error(LOG_TAG, "Got exception executing background upgrade Runnable; ignoring.", e);
michael@0 67 }
michael@0 68 }
michael@0 69 });
michael@0 70 }
michael@0 71 }
michael@0 72
michael@0 73 /**
michael@0 74 * A Runnable that tries to unpickle any pickled Firefox Accounts.
michael@0 75 */
michael@0 76 protected static class MaybeUnpickleRunnable implements Runnable {
michael@0 77 protected final Context context;
michael@0 78
michael@0 79 public MaybeUnpickleRunnable(Context context) {
michael@0 80 this.context = context;
michael@0 81 }
michael@0 82
michael@0 83 @Override
michael@0 84 public void run() {
michael@0 85 // Querying the accounts will unpickle any pickled Firefox Account.
michael@0 86 Logger.info(LOG_TAG, "Trying to unpickle any pickled Firefox Account.");
michael@0 87 FirefoxAccounts.getFirefoxAccounts(context);
michael@0 88 }
michael@0 89 }
michael@0 90
michael@0 91 /**
michael@0 92 * A Runnable that tries to advance existing Firefox Accounts that are in the
michael@0 93 * Doghouse state to the Separated state.
michael@0 94 * <p>
michael@0 95 * This is our main deprecation-and-upgrade mechanism: in some way, the
michael@0 96 * Account gets moved to the Doghouse state. If possible, an upgraded version
michael@0 97 * of the package advances to Separated, prompting the user to re-connect the
michael@0 98 * Account.
michael@0 99 */
michael@0 100 protected static class AdvanceFromDoghouseRunnable implements Runnable {
michael@0 101 protected final Context context;
michael@0 102
michael@0 103 public AdvanceFromDoghouseRunnable(Context context) {
michael@0 104 this.context = context;
michael@0 105 }
michael@0 106
michael@0 107 @Override
michael@0 108 public void run() {
michael@0 109 final Account[] accounts = FirefoxAccounts.getFirefoxAccounts(context);
michael@0 110 Logger.info(LOG_TAG, "Trying to advance " + accounts.length + " existing Firefox Accounts from the Doghouse to Separated (if necessary).");
michael@0 111 for (Account account : accounts) {
michael@0 112 try {
michael@0 113 final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account);
michael@0 114 // For great debugging.
michael@0 115 if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
michael@0 116 fxAccount.dump();
michael@0 117 }
michael@0 118 State state = fxAccount.getState();
michael@0 119 if (state == null || state.getStateLabel() != StateLabel.Doghouse) {
michael@0 120 Logger.debug(LOG_TAG, "Account named like " + Utils.obfuscateEmail(account.name) + " is not in the Doghouse; skipping.");
michael@0 121 continue;
michael@0 122 }
michael@0 123 Logger.debug(LOG_TAG, "Account named like " + Utils.obfuscateEmail(account.name) + " is in the Doghouse; advancing to Separated.");
michael@0 124 fxAccount.setState(state.makeSeparatedState());
michael@0 125 } catch (Exception e) {
michael@0 126 Logger.warn(LOG_TAG, "Got exception trying to advance account named like " + Utils.obfuscateEmail(account.name) +
michael@0 127 " from Doghouse to Separated state; ignoring.", e);
michael@0 128 }
michael@0 129 }
michael@0 130 }
michael@0 131 }
michael@0 132 }

mercurial