Bug 1102488 - Part 0: Make FxAccountConstants independent of Logger. r=rnewman
☠☠ backed out by 23410bbf2161 ☠ ☠
authorNick Alexander <nalexander@mozilla.com>
Thu, 20 Nov 2014 15:07:35 -0800
changeset 241381 8d1d39582e497c2c47400740304bdc98f0aef0a7
parent 241380 fa85f8d8b182fad743556a012a982daad121f0b1
child 241382 d2c14599cbab6c476465a6ba142c7c2501895cb3
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs1102488
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1102488 - Part 0: Make FxAccountConstants independent of Logger. r=rnewman
mobile/android/base/background/fxa/FxAccountAgeLockoutHelper.java
mobile/android/base/background/fxa/FxAccountClient20.java
mobile/android/base/background/fxa/FxAccountUtils.java
mobile/android/base/fxa/FxAccountConstants.java.in
mobile/android/base/fxa/activities/FxAccountAbstractSetupActivity.java
mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
mobile/android/base/fxa/activities/FxAccountStatusFragment.java
mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java
mobile/android/base/fxa/authenticator/AndroidFxAccount.java
mobile/android/base/fxa/login/Cohabiting.java
mobile/android/base/fxa/login/Engaged.java
mobile/android/base/fxa/login/Married.java
mobile/android/base/fxa/login/StateFactory.java
mobile/android/base/fxa/receivers/FxAccountUpgradeReceiver.java
mobile/android/base/fxa/sync/FxAccountNotificationManager.java
mobile/android/base/fxa/sync/FxAccountSyncAdapter.java
--- a/mobile/android/base/background/fxa/FxAccountAgeLockoutHelper.java
+++ b/mobile/android/base/background/fxa/FxAccountAgeLockoutHelper.java
@@ -30,23 +30,23 @@ public class FxAccountAgeLockoutHelper {
     if (ELAPSED_REALTIME_OF_LAST_FAILED_AGE_CHECK == 0L) {
       // We never failed, so we're not locked out.
       return false;
     }
 
     // Otherwise, find out how long it's been since we last failed.
     long millsecondsSinceLastFailedAgeCheck = elapsedRealtime - ELAPSED_REALTIME_OF_LAST_FAILED_AGE_CHECK;
     boolean isLockedOut = millsecondsSinceLastFailedAgeCheck < FxAccountConstants.MINIMUM_TIME_TO_WAIT_AFTER_AGE_CHECK_FAILED_IN_MILLISECONDS;
-    FxAccountConstants.pii(LOG_TAG, "Checking if locked out: it's been " + millsecondsSinceLastFailedAgeCheck + "ms " +
+    FxAccountUtils.pii(LOG_TAG, "Checking if locked out: it's been " + millsecondsSinceLastFailedAgeCheck + "ms " +
         "since last lockout, so " + (isLockedOut ? "yes." : "no."));
     return isLockedOut;
   }
 
   public static synchronized void lockOut(long elapsedRealtime) {
-      FxAccountConstants.pii(LOG_TAG, "Locking out at time: " + elapsedRealtime);
+      FxAccountUtils.pii(LOG_TAG, "Locking out at time: " + elapsedRealtime);
       ELAPSED_REALTIME_OF_LAST_FAILED_AGE_CHECK = Math.max(elapsedRealtime, ELAPSED_REALTIME_OF_LAST_FAILED_AGE_CHECK);
   }
 
   /**
    * Return true if the age of somebody born in <code>yearOfBirth</code> is
    * definitely old enough to create an account.
    * <p>
    * This errs towards locking out users who might be old enough, but are not
@@ -55,18 +55,18 @@ public class FxAccountAgeLockoutHelper {
    * @param yearOfBirth
    * @return true if somebody born in <code>yearOfBirth</code> is definitely old
    *         enough.
    */
   public static boolean passesAgeCheck(int yearOfBirth) {
     int thisYear = Calendar.getInstance().get(Calendar.YEAR);
     int approximateAge = thisYear - yearOfBirth;
     boolean oldEnough = approximateAge >= FxAccountConstants.MINIMUM_AGE_TO_CREATE_AN_ACCOUNT;
-    if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
-      FxAccountConstants.pii(LOG_TAG, "Age check " + (oldEnough ? "passes" : "fails") +
+    if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+      FxAccountUtils.pii(LOG_TAG, "Age check " + (oldEnough ? "passes" : "fails") +
           ": age is " + approximateAge + " = " + thisYear + " - " + yearOfBirth);
     }
     return oldEnough;
   }
 
   /**
    * Custom function for UI use only.
    */
@@ -74,23 +74,23 @@ public class FxAccountAgeLockoutHelper {
     if (yearText == null) {
       throw new IllegalArgumentException("yearText must not be null");
     }
     if (yearItems == null) {
       throw new IllegalArgumentException("yearItems must not be null");
     }
     if (!Arrays.asList(yearItems).contains(yearText)) {
       // This should never happen, but let's be careful.
-      FxAccountConstants.pii(LOG_TAG, "Failed age check: year text was not found in item list.");
+      FxAccountUtils.pii(LOG_TAG, "Failed age check: year text was not found in item list.");
       return false;
     }
     Integer yearOfBirth;
     try {
       yearOfBirth = Integer.valueOf(yearText, 10);
     } catch (NumberFormatException e) {
       // Any non-numbers in the list are ranges (and we say as much to
       // translators in the resource file), so these people pass the age check.
-      FxAccountConstants.pii(LOG_TAG, "Passed age check: year text was found in item list but was not a number.");
+      FxAccountUtils.pii(LOG_TAG, "Passed age check: year text was found in item list but was not a number.");
       return true;
     }
     return passesAgeCheck(yearOfBirth);
   }
 }
--- a/mobile/android/base/background/fxa/FxAccountClient20.java
+++ b/mobile/android/base/background/fxa/FxAccountClient20.java
@@ -8,17 +8,16 @@ import java.io.UnsupportedEncodingExcept
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.util.concurrent.Executor;
 
 import org.json.simple.JSONObject;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.Utils;
 import org.mozilla.gecko.sync.net.BaseResource;
 
 import ch.boye.httpclientandroidlib.HttpResponse;
 
 public class FxAccountClient20 extends FxAccountClient10 implements FxAccountClient {
   protected static final String[] LOGIN_RESPONSE_REQUIRED_STRING_FIELDS = new String[] { JSON_KEY_UID, JSON_KEY_SESSIONTOKEN };
@@ -201,17 +200,17 @@ public class FxAccountClient20 extends F
    *          addition to the standard <code>sessionToken</code>).
    * @param delegate
    *          to invoke callbacks.
    */
   public void login(final byte[] emailUTF8, final PasswordStretcher stretcher, final boolean getKeys,
       final RequestDelegate<LoginResponse> delegate) {
     byte[] quickStretchedPW;
     try {
-      FxAccountConstants.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, "UTF-8") + "'" );
+      FxAccountUtils.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, "UTF-8") + "'" );
       quickStretchedPW = stretcher.getQuickStretchedPW(emailUTF8);
     } catch (Exception e) {
       delegate.handleError(e);
       return;
     }
 
     this.login(emailUTF8, quickStretchedPW, getKeys, new RequestDelegate<LoginResponse>() {
       @Override
@@ -228,17 +227,17 @@ public class FxAccountClient20 extends F
       public void handleFailure(FxAccountClientRemoteException e) {
         String alternateEmail = e.body.getString(JSON_KEY_EMAIL);
         if (!e.isBadEmailCase() || alternateEmail == null) {
           delegate.handleFailure(e);
           return;
         };
 
         Logger.info(LOG_TAG, "Server returned alternate email; retrying login with provided email.");
-        FxAccountConstants.pii(LOG_TAG, "Trying server provided email: '" + alternateEmail + "'" );
+        FxAccountUtils.pii(LOG_TAG, "Trying server provided email: '" + alternateEmail + "'" );
 
         try {
           // Nota bene: this is not recursive, since we call the fixed password
           // signature here, which invokes a non-retrying version.
           byte[] alternateEmailUTF8 = alternateEmail.getBytes("UTF-8");
           byte[] alternateQuickStretchedPW = stretcher.getQuickStretchedPW(alternateEmailUTF8);
           login(alternateEmailUTF8, alternateQuickStretchedPW, getKeys, delegate);
         } catch (Exception innerException) {
--- a/mobile/android/base/background/fxa/FxAccountUtils.java
+++ b/mobile/android/base/background/fxa/FxAccountUtils.java
@@ -30,16 +30,26 @@ public class FxAccountUtils {
 
   public static final int CRYPTO_KEY_LENGTH_BYTES = 32;
   public static final int CRYPTO_KEY_LENGTH_HEX = 2 * CRYPTO_KEY_LENGTH_BYTES;
 
   public static final String KW_VERSION_STRING = "identity.mozilla.com/picl/v1/";
 
   public static final int NUMBER_OF_QUICK_STRETCH_ROUNDS = 1000;
 
+  // For extra debugging.  Not final so it can be changed from Fennec, or from
+  // an add-on.
+  public static boolean LOG_PERSONAL_INFORMATION = false;
+
+  public static void pii(String tag, String message) {
+    if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+      Logger.info(tag, "$$FxA PII$$: " + message);
+    }
+  }
+
   public static String bytes(String string) throws UnsupportedEncodingException {
     return Utils.byte2Hex(string.getBytes("UTF-8"));
   }
 
   public static byte[] KW(String name) throws UnsupportedEncodingException {
     return Utils.concatAll(
         KW_VERSION_STRING.getBytes("UTF-8"),
         name.getBytes("UTF-8"));
--- a/mobile/android/base/fxa/FxAccountConstants.java.in
+++ b/mobile/android/base/fxa/FxAccountConstants.java.in
@@ -1,38 +1,27 @@
 //#filter substitution
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.fxa;
 
 import org.mozilla.gecko.background.common.GlobalConstants;
-import org.mozilla.gecko.background.common.log.Logger;
 
 public class FxAccountConstants {
   public static final String GLOBAL_LOG_TAG = "FxAccounts";
   public static final String ACCOUNT_TYPE = "@MOZ_ANDROID_SHARED_FXACCOUNT_TYPE@";
 
   public static final String DEFAULT_AUTH_SERVER_ENDPOINT = "https://api.accounts.firefox.com/v1";
   public static final String DEFAULT_TOKEN_SERVER_ENDPOINT = "https://token.services.mozilla.com/1.0/sync/1.5";
 
   public static final String STAGE_AUTH_SERVER_ENDPOINT = "https://api-accounts.stage.mozaws.net/v1";
   public static final String STAGE_TOKEN_SERVER_ENDPOINT = "https://token.stage.mozaws.net/1.0/sync/1.5";
 
-  // For extra debugging.  Not final so it can be changed from Fennec, or from
-  // an add-on.
-  public static boolean LOG_PERSONAL_INFORMATION = false;
-
-  public static void pii(String tag, String message) {
-    if (LOG_PERSONAL_INFORMATION) {
-      Logger.info(tag, "$$FxA PII$$: " + message);
-    }
-  }
-
   // You must be at least 14 years old to create a Firefox Account.
   public static final int MINIMUM_AGE_TO_CREATE_AN_ACCOUNT = 14;
 
   // You must wait 15 minutes after failing an age check before trying to create a different account.
   public static final long MINIMUM_TIME_TO_WAIT_AFTER_AGE_CHECK_FAILED_IN_MILLISECONDS = 15 * 60 * 1000;
 
   public static final String USER_AGENT = "Firefox-Android-FxAccounts/" + GlobalConstants.MOZ_APP_VERSION + " (" + GlobalConstants.MOZ_APP_DISPLAYNAME + ")";
 
--- a/mobile/android/base/fxa/activities/FxAccountAbstractSetupActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountAbstractSetupActivity.java
@@ -319,17 +319,17 @@ abstract public class FxAccountAbstractS
           SyncConfiguration.storeSelectedEnginesToPrefs(fxAccount.getSyncPrefs(), selectedEngines);
         }
       } catch (Exception e) {
         handleError(e);
         return;
       }
 
       // For great debugging.
-      if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+      if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
         fxAccount.dump();
       }
 
       // The GetStarted activity has called us and needs to return a result to the authenticator.
       final Intent intent = new Intent();
       intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, email);
       intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, FxAccountConstants.ACCOUNT_TYPE);
       // intent.putExtra(AccountManager.KEY_AUTHTOKEN, accountType);
@@ -398,19 +398,19 @@ abstract public class FxAccountAbstractS
       emailEdit.setText(bundle.getString(EXTRA_EMAIL));
       passwordEdit.setText(bundle.getString(EXTRA_PASSWORD));
       setPasswordButtonShown(bundle.getBoolean(EXTRA_PASSWORD_SHOWN, false));
     }
 
     // This sets defaults as well as extracting from extras, so it's not conditional.
     updateServersFromIntentExtras(getIntent());
 
-    if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
-      FxAccountConstants.pii(LOG_TAG, "Using auth server: " + authServerEndpoint);
-      FxAccountConstants.pii(LOG_TAG, "Using sync server: " + syncServerEndpoint);
+    if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+      FxAccountUtils.pii(LOG_TAG, "Using auth server: " + authServerEndpoint);
+      FxAccountUtils.pii(LOG_TAG, "Using sync server: " + syncServerEndpoint);
     }
 
     updateCustomServerView();
   }
 
   @Override
   public void onResume() {
     super.onResume();
--- a/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
@@ -14,18 +14,18 @@ import java.util.concurrent.Executors;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
 import org.mozilla.gecko.background.fxa.FxAccountClient;
 import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
 import org.mozilla.gecko.background.fxa.FxAccountClient20;
 import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
 import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.background.fxa.PasswordStretcher;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.tasks.FxAccountCreateAccountTask;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -245,20 +245,20 @@ public class FxAccountCreateAccountActiv
         }
         final String email = emailEdit.getText().toString();
         final String password = passwordEdit.getText().toString();
         // Only include selected engines if the user currently has the option checked.
         final Map<String, Boolean> engines = chooseCheckBox.isChecked()
             ? selectedEngines
             : null;
         if (FxAccountAgeLockoutHelper.passesAgeCheck(yearEdit.getText().toString(), yearItems)) {
-          FxAccountConstants.pii(LOG_TAG, "Passed age check.");
+          FxAccountUtils.pii(LOG_TAG, "Passed age check.");
           createAccount(email, password, engines);
         } else {
-          FxAccountConstants.pii(LOG_TAG, "Failed age check!");
+          FxAccountUtils.pii(LOG_TAG, "Failed age check!");
           FxAccountAgeLockoutHelper.lockOut(SystemClock.elapsedRealtime());
           setResult(RESULT_CANCELED);
           redirectToActivity(FxAccountCreateAccountNotAllowedActivity.class);
         }
       }
     });
   }
 
@@ -299,17 +299,17 @@ public class FxAccountCreateAccountActiv
         ListView selectionsList = ((AlertDialog) dialog).getListView();
         for (int i = 0; i < NUMBER_OF_ENGINES; i++) {
           checkedItems[i] = selectionsList.isItemChecked(i);
         }
         selectedEngines.put("bookmarks", checkedItems[INDEX_BOOKMARKS]);
         selectedEngines.put("history", checkedItems[INDEX_HISTORY]);
         selectedEngines.put("tabs", checkedItems[INDEX_TABS]);
         selectedEngines.put("passwords", checkedItems[INDEX_PASSWORDS]);
-        FxAccountConstants.pii(LOG_TAG, "Updating selectedEngines: " + selectedEngines.toString());
+        FxAccountUtils.pii(LOG_TAG, "Updating selectedEngines: " + selectedEngines.toString());
       }
     };
 
     final DialogInterface.OnMultiChoiceClickListener multiChoiceClickListener = new DialogInterface.OnMultiChoiceClickListener() {
       @Override
       public void onClick(DialogInterface dialog, int which, boolean isChecked) {
         // Display multi-selection clicks in UI.
         ListView selectionsList = ((AlertDialog) dialog).getListView();
--- a/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
@@ -4,16 +4,17 @@
 
 package org.mozilla.gecko.fxa.activities;
 
 import java.util.Locale;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 import org.mozilla.gecko.LocaleAware;
 
 import android.accounts.AccountAuthenticatorActivity;
 import android.content.Intent;
 import android.os.Bundle;
@@ -128,12 +129,12 @@ public class FxAccountGetStartedActivity
       this.finish();
     }
   }
 
   protected void linkifyOldFirefoxLink() {
     TextView oldFirefox = (TextView) findViewById(R.id.old_firefox);
     String text = getResources().getString(R.string.fxaccount_getting_started_old_firefox);
     final String url = FirefoxAccounts.getOldSyncUpgradeURL(getResources(), Locale.getDefault());
-    FxAccountConstants.pii(LOG_TAG, "Old Firefox url is: " + url); // Don't want to leak locale in particular.
+    FxAccountUtils.pii(LOG_TAG, "Old Firefox url is: " + url); // Don't want to leak locale in particular.
     ActivityUtils.linkTextView(oldFirefox, text, url);
   }
 }
--- a/mobile/android/base/fxa/activities/FxAccountStatusFragment.java
+++ b/mobile/android/base/fxa/activities/FxAccountStatusFragment.java
@@ -5,16 +5,17 @@
 package org.mozilla.gecko.fxa.activities;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.background.preferences.PreferenceFragment;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.Married;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.fxa.sync.FxAccountSyncStatusHelper;
 import org.mozilla.gecko.fxa.tasks.FxAccountCodeResender;
@@ -140,17 +141,17 @@ public class FxAccountStatusFragment
 
     syncCategory = (PreferenceCategory) ensureFindPreference("sync_category");
 
     bookmarksPreference = (CheckBoxPreference) ensureFindPreference("bookmarks");
     historyPreference = (CheckBoxPreference) ensureFindPreference("history");
     tabsPreference = (CheckBoxPreference) ensureFindPreference("tabs");
     passwordsPreference = (CheckBoxPreference) ensureFindPreference("passwords");
 
-    if (!FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+    if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) {
       removeDebugButtons();
     } else {
       connectDebugButtons();
       ALWAYS_SHOW_AUTH_SERVER = true;
       ALWAYS_SHOW_SYNC_SERVER = true;
     }
 
     needsPasswordPreference.setOnPreferenceClickListener(this);
--- a/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java
@@ -12,17 +12,16 @@ import org.mozilla.gecko.background.comm
 import org.mozilla.gecko.background.fxa.FxAccountClient;
 import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
 import org.mozilla.gecko.background.fxa.FxAccountClient20;
 import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
 import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
 import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.background.fxa.PasswordStretcher;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.Engaged;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.fxa.login.State.StateLabel;
 import org.mozilla.gecko.fxa.tasks.FxAccountSignInTask;
 import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.os.Bundle;
@@ -151,17 +150,17 @@ public class FxAccountUpdateCredentialsA
       } catch (Exception e) {
         this.handleError(e);
         return;
       }
       fxAccount.setState(new Engaged(email, result.uid, result.verified, unwrapkB, result.sessionToken, result.keyFetchToken));
       fxAccount.requestSync(FirefoxAccounts.FORCE);
 
       // For great debugging.
-      if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+      if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
         fxAccount.dump();
       }
 
       setResult(RESULT_OK);
       finish();
     }
   }
 
--- a/mobile/android/base/fxa/authenticator/AndroidFxAccount.java
+++ b/mobile/android/base/fxa/authenticator/AndroidFxAccount.java
@@ -511,24 +511,24 @@ public class AndroidFxAccount {
       throw new IllegalStateException("could not get state", e);
     }
   }
 
   /**
    * <b>For debugging only!</b>
    */
   public void dump() {
-    if (!FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+    if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) {
       return;
     }
     ExtendedJSONObject o = toJSONObject();
     ArrayList<String> list = new ArrayList<String>(o.keySet());
     Collections.sort(list);
     for (String key : list) {
-      FxAccountConstants.pii(LOG_TAG, key + ": " + o.get(key));
+      FxAccountUtils.pii(LOG_TAG, key + ": " + o.get(key));
     }
   }
 
   /**
    * Return the Firefox Account's local email address.
    * <p>
    * It is important to note that this is the local email address, and not
    * necessarily the normalized remote email address that the server expects.
--- a/mobile/android/base/fxa/login/Cohabiting.java
+++ b/mobile/android/base/fxa/login/Cohabiting.java
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.fxa.login;
 
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.browserid.BrowserIDKeyPair;
 import org.mozilla.gecko.browserid.JSONWebTokenUtils;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.login.FxAccountLoginStateMachine.ExecuteDelegate;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.LogMessage;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 
 public class Cohabiting extends TokensAndKeysState {
   private static final String LOG_TAG = Cohabiting.class.getSimpleName();
 
   public Cohabiting(String email, String uid, byte[] sessionToken, byte[] kA, byte[] kB, BrowserIDKeyPair keyPair) {
@@ -19,28 +19,28 @@ public class Cohabiting extends TokensAn
   }
 
   @Override
   public void execute(final ExecuteDelegate delegate) {
     delegate.getClient().sign(sessionToken, keyPair.getPublic().toJSONObject(), delegate.getCertificateDurationInMilliseconds(),
         new BaseRequestDelegate<String>(this, delegate) {
       @Override
       public void handleSuccess(String certificate) {
-        if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+        if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
           try {
-            FxAccountConstants.pii(LOG_TAG, "Fetched certificate: " + certificate);
+            FxAccountUtils.pii(LOG_TAG, "Fetched certificate: " + certificate);
             ExtendedJSONObject c = JSONWebTokenUtils.parseCertificate(certificate);
             if (c != null) {
-              FxAccountConstants.pii(LOG_TAG, "Header   : " + c.getObject("header"));
-              FxAccountConstants.pii(LOG_TAG, "Payload  : " + c.getObject("payload"));
-              FxAccountConstants.pii(LOG_TAG, "Signature: " + c.getString("signature"));
+              FxAccountUtils.pii(LOG_TAG, "Header   : " + c.getObject("header"));
+              FxAccountUtils.pii(LOG_TAG, "Payload  : " + c.getObject("payload"));
+              FxAccountUtils.pii(LOG_TAG, "Signature: " + c.getString("signature"));
             } else {
-              FxAccountConstants.pii(LOG_TAG, "Could not parse certificate!");
+              FxAccountUtils.pii(LOG_TAG, "Could not parse certificate!");
             }
           } catch (Exception e) {
-            FxAccountConstants.pii(LOG_TAG, "Could not parse certificate!");
+            FxAccountUtils.pii(LOG_TAG, "Could not parse certificate!");
           }
         }
         delegate.handleTransition(new LogMessage("sign succeeded"), new Married(email, uid, sessionToken, kA, kB, keyPair, certificate));
       }
     });
   }
 }
--- a/mobile/android/base/fxa/login/Engaged.java
+++ b/mobile/android/base/fxa/login/Engaged.java
@@ -4,17 +4,16 @@
 
 package org.mozilla.gecko.fxa.login;
 
 import java.security.NoSuchAlgorithmException;
 
 import org.mozilla.gecko.background.fxa.FxAccountClient10.TwoKeys;
 import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.browserid.BrowserIDKeyPair;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.login.FxAccountLoginStateMachine.ExecuteDelegate;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.AccountVerified;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.LocalError;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.LogMessage;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.RemoteError;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.Transition;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.Utils;
@@ -56,20 +55,20 @@ public class Engaged extends State {
     final BrowserIDKeyPair keyPair = theKeyPair;
 
     delegate.getClient().keys(keyFetchToken, new BaseRequestDelegate<TwoKeys>(this, delegate) {
       @Override
       public void handleSuccess(TwoKeys result) {
         byte[] kB;
         try {
           kB = FxAccountUtils.unwrapkB(unwrapkB, result.wrapkB);
-          if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
-            FxAccountConstants.pii(LOG_TAG, "Fetched kA: " + Utils.byte2Hex(result.kA));
-            FxAccountConstants.pii(LOG_TAG, "And wrapkB: " + Utils.byte2Hex(result.wrapkB));
-            FxAccountConstants.pii(LOG_TAG, "Giving kB : " + Utils.byte2Hex(kB));
+          if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+            FxAccountUtils.pii(LOG_TAG, "Fetched kA: " + Utils.byte2Hex(result.kA));
+            FxAccountUtils.pii(LOG_TAG, "And wrapkB: " + Utils.byte2Hex(result.wrapkB));
+            FxAccountUtils.pii(LOG_TAG, "Giving kB : " + Utils.byte2Hex(kB));
           }
         } catch (Exception e) {
           delegate.handleTransition(new RemoteError(e), new Separated(email, uid, verified));
           return;
         }
         Transition transition = verified
             ? new LogMessage("keys succeeded")
             : new AccountVerified();
--- a/mobile/android/base/fxa/login/Married.java
+++ b/mobile/android/base/fxa/login/Married.java
@@ -12,17 +12,16 @@ import java.security.NoSuchAlgorithmExce
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 
 import org.json.simple.parser.ParseException;
 import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.browserid.BrowserIDKeyPair;
 import org.mozilla.gecko.browserid.JSONWebTokenUtils;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.login.FxAccountLoginStateMachine.ExecuteDelegate;
 import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.LogMessage;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.NonObjectJSONException;
 import org.mozilla.gecko.sync.Utils;
 import org.mozilla.gecko.sync.crypto.KeyBundle;
 
 public class Married extends TokensAndKeysState {
@@ -56,64 +55,64 @@ public class Married extends TokensAndKe
     delegate.handleTransition(new LogMessage("staying married"), this);
   }
 
   public String generateAssertion(String audience, String issuer) throws NonObjectJSONException, IOException, ParseException, GeneralSecurityException {
     // We generate assertions with no iat and an exp after 2050 to avoid
     // invalid-timestamp errors from the token server.
     final long expiresAt = JSONWebTokenUtils.DEFAULT_FUTURE_EXPIRES_AT_IN_MILLISECONDS;
     String assertion = JSONWebTokenUtils.createAssertion(keyPair.getPrivate(), certificate, audience, issuer, null, expiresAt);
-    if (!FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+    if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) {
       return assertion;
     }
 
     try {
-      FxAccountConstants.pii(LOG_TAG, "Generated assertion: " + assertion);
+      FxAccountUtils.pii(LOG_TAG, "Generated assertion: " + assertion);
       ExtendedJSONObject a = JSONWebTokenUtils.parseAssertion(assertion);
       if (a != null) {
-        FxAccountConstants.pii(LOG_TAG, "aHeader   : " + a.getObject("header"));
-        FxAccountConstants.pii(LOG_TAG, "aPayload  : " + a.getObject("payload"));
-        FxAccountConstants.pii(LOG_TAG, "aSignature: " + a.getString("signature"));
+        FxAccountUtils.pii(LOG_TAG, "aHeader   : " + a.getObject("header"));
+        FxAccountUtils.pii(LOG_TAG, "aPayload  : " + a.getObject("payload"));
+        FxAccountUtils.pii(LOG_TAG, "aSignature: " + a.getString("signature"));
         String certificate = a.getString("certificate");
         if (certificate != null) {
           ExtendedJSONObject c = JSONWebTokenUtils.parseCertificate(certificate);
-          FxAccountConstants.pii(LOG_TAG, "cHeader   : " + c.getObject("header"));
-          FxAccountConstants.pii(LOG_TAG, "cPayload  : " + c.getObject("payload"));
-          FxAccountConstants.pii(LOG_TAG, "cSignature: " + c.getString("signature"));
+          FxAccountUtils.pii(LOG_TAG, "cHeader   : " + c.getObject("header"));
+          FxAccountUtils.pii(LOG_TAG, "cPayload  : " + c.getObject("payload"));
+          FxAccountUtils.pii(LOG_TAG, "cSignature: " + c.getString("signature"));
           // Print the relevant timestamps in sorted order with labels.
           HashMap<Long, String> map = new HashMap<Long, String>();
           map.put(a.getObject("payload").getLong("iat"), "aiat");
           map.put(a.getObject("payload").getLong("exp"), "aexp");
           map.put(c.getObject("payload").getLong("iat"), "ciat");
           map.put(c.getObject("payload").getLong("exp"), "cexp");
           ArrayList<Long> values = new ArrayList<Long>(map.keySet());
           Collections.sort(values);
           for (Long value : values) {
-            FxAccountConstants.pii(LOG_TAG, map.get(value) + ": " + value);
+            FxAccountUtils.pii(LOG_TAG, map.get(value) + ": " + value);
           }
         } else {
-          FxAccountConstants.pii(LOG_TAG, "Could not parse certificate!");
+          FxAccountUtils.pii(LOG_TAG, "Could not parse certificate!");
         }
       } else {
-        FxAccountConstants.pii(LOG_TAG, "Could not parse assertion!");
+        FxAccountUtils.pii(LOG_TAG, "Could not parse assertion!");
       }
     } catch (Exception e) {
-      FxAccountConstants.pii(LOG_TAG, "Got exception dumping assertion debug info.");
+      FxAccountUtils.pii(LOG_TAG, "Got exception dumping assertion debug info.");
     }
     return assertion;
   }
 
   public KeyBundle getSyncKeyBundle() throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
     // TODO Document this choice for deriving from kB.
     return FxAccountUtils.generateSyncKeyBundle(kB);
   }
 
   public String getClientState() {
-    if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
-      FxAccountConstants.pii(LOG_TAG, "Client state: " + this.clientState);
+    if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+      FxAccountUtils.pii(LOG_TAG, "Client state: " + this.clientState);
     }
     return this.clientState;
   }
 
   public State makeCohabitingState() {
     return new Cohabiting(email, uid, sessionToken, kA, kB, keyPair);
   }
 }
--- a/mobile/android/base/fxa/login/StateFactory.java
+++ b/mobile/android/base/fxa/login/StateFactory.java
@@ -3,20 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.fxa.login;
 
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 
 import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.browserid.BrowserIDKeyPair;
 import org.mozilla.gecko.browserid.DSACryptoImplementation;
 import org.mozilla.gecko.browserid.RSACryptoImplementation;
-import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.login.State.StateLabel;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.NonObjectJSONException;
 import org.mozilla.gecko.sync.Utils;
 
 /**
  * Create {@link State} instances from serialized representations.
  * <p>
@@ -130,25 +130,25 @@ public class StateFactory {
           keyPairFromJSONObjectV2(o.getObject("keyPair")),
           o.getString("certificate"));
     default:
       return fromJSONObjectV1(stateLabel, o);
     }
   }
 
   protected static void logMigration(State from, State to) {
-    if (!FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+    if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) {
       return;
     }
     try {
-      FxAccountConstants.pii(LOG_TAG, "V1 persisted state is: " + from.toJSONObject().toJSONString());
+      FxAccountUtils.pii(LOG_TAG, "V1 persisted state is: " + from.toJSONObject().toJSONString());
     } catch (Exception e) {
       Logger.warn(LOG_TAG, "Error producing JSON representation of V1 state.", e);
     }
-    FxAccountConstants.pii(LOG_TAG, "Generated new V2 state: " + to.toJSONObject().toJSONString());
+    FxAccountUtils.pii(LOG_TAG, "Generated new V2 state: " + to.toJSONObject().toJSONString());
   }
 
   protected static State migrateV1toV2(StateLabel stateLabel, State state) throws NoSuchAlgorithmException {
     if (state == null) {
       // This should never happen, but let's be careful.
       Logger.error(LOG_TAG, "Got null state in migrateV1toV2; returning null.");
       return state;
     }
--- a/mobile/android/base/fxa/receivers/FxAccountUpgradeReceiver.java
+++ b/mobile/android/base/fxa/receivers/FxAccountUpgradeReceiver.java
@@ -5,16 +5,17 @@
 package org.mozilla.gecko.fxa.receivers;
 
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 
 import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.fxa.login.State.StateLabel;
 import org.mozilla.gecko.sync.Utils;
 
 import android.accounts.Account;
@@ -107,17 +108,17 @@ public class FxAccountUpgradeReceiver ex
     @Override
     public void run() {
       final Account[] accounts = FirefoxAccounts.getFirefoxAccounts(context);
       Logger.info(LOG_TAG, "Trying to advance " + accounts.length + " existing Firefox Accounts from the Doghouse to Separated (if necessary).");
       for (Account account : accounts) {
         try {
           final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account);
           // For great debugging.
-          if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+          if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
             fxAccount.dump();
           }
           State state = fxAccount.getState();
           if (state == null || state.getStateLabel() != StateLabel.Doghouse) {
             Logger.debug(LOG_TAG, "Account named like " + Utils.obfuscateEmail(account.name) + " is not in the Doghouse; skipping.");
             continue;
           }
           Logger.debug(LOG_TAG, "Account named like " + Utils.obfuscateEmail(account.name) + " is in the Doghouse; advancing to Separated.");
--- a/mobile/android/base/fxa/sync/FxAccountNotificationManager.java
+++ b/mobile/android/base/fxa/sync/FxAccountNotificationManager.java
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.fxa.sync;
 
 import org.mozilla.gecko.BrowserLocaleManager;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.fxa.FxAccountConstants;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.fxa.activities.FxAccountStatusActivity;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.fxa.login.State.Action;
 
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -65,17 +65,17 @@ public class FxAccountNotificationManage
     if (!localeUpdated) {
       localeUpdated = true;
       BrowserLocaleManager.getInstance().getAndApplyPersistedLocale(context);
     }
 
     final String title = context.getResources().getString(R.string.fxaccount_sync_sign_in_error_notification_title);
     final String text = context.getResources().getString(R.string.fxaccount_sync_sign_in_error_notification_text, state.email);
     Logger.info(LOG_TAG, "State " + state.getStateLabel() + " needs action; offering notification with title: " + title);
-    FxAccountConstants.pii(LOG_TAG, "And text: " + text);
+    FxAccountUtils.pii(LOG_TAG, "And text: " + text);
 
     final Intent notificationIntent = new Intent(context, FxAccountStatusActivity.class);
     final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
 
     final Builder builder = new NotificationCompat.Builder(context);
     builder
     .setContentTitle(title)
     .setContentText(text)
--- a/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java
+++ b/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java
@@ -12,16 +12,17 @@ import java.util.Collections;
 import java.util.EnumSet;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountClient;
 import org.mozilla.gecko.background.fxa.FxAccountClient20;
+import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.background.fxa.SkewHandler;
 import org.mozilla.gecko.browserid.BrowserIDKeyPair;
 import org.mozilla.gecko.browserid.JSONWebTokenUtils;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.authenticator.AccountPickler;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.authenticator.FxAccountAuthenticator;
@@ -310,17 +311,17 @@ public class FxAccountSyncAdapter extend
 
       @Override
       public String getUserAgent() {
         return FxAccountConstants.USER_AGENT;
       }
 
       @Override
       public void handleSuccess(final TokenServerToken token) {
-        FxAccountConstants.pii(LOG_TAG, "Got token! uid is " + token.uid + " and endpoint is " + token.endpoint + ".");
+        FxAccountUtils.pii(LOG_TAG, "Got token! uid is " + token.uid + " and endpoint is " + token.endpoint + ".");
 
         if (!didReceiveBackoff) {
           // We must be OK to touch this token server.
           tokenBackoffHandler.setEarliestNextRequest(0L);
         }
 
         final URI storageServerURI;
         try {
@@ -353,19 +354,19 @@ public class FxAccountSyncAdapter extend
 
         // Invalidate the previous backoff, because our storage host has changed,
         // or we never had one at all, or we're OK to sync.
         storageBackoffHandler.setEarliestNextRequest(0L);
 
         FxAccountGlobalSession globalSession = null;
         try {
           final ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs, getContext());
-          if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
-            FxAccountConstants.pii(LOG_TAG, "Client device name is: '" + clientsDataDelegate.getClientName() + "'.");
-            FxAccountConstants.pii(LOG_TAG, "Client device data last modified: " + clientsDataDelegate.getLastModifiedTimestamp());
+          if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
+            FxAccountUtils.pii(LOG_TAG, "Client device name is: '" + clientsDataDelegate.getClientName() + "'.");
+            FxAccountUtils.pii(LOG_TAG, "Client device data last modified: " + clientsDataDelegate.getLastModifiedTimestamp());
           }
 
           // We compute skew over time using SkewHandler. This yields an unchanging
           // skew adjustment that the HawkAuthHeaderProvider uses to adjust its
           // timestamps. Eventually we might want this to adapt within the scope of a
           // global session.
           final SkewHandler storageServerSkewHandler = SkewHandler.getSkewHandlerForHostname(storageHostname);
           final long storageServerSkew = storageServerSkewHandler.getSkewInSeconds();
@@ -439,17 +440,17 @@ public class FxAccountSyncAdapter extend
 
     Logger.info(LOG_TAG, "Syncing FxAccount" +
         " account named like " + Utils.obfuscateEmail(account.name) +
         " for authority " + authority +
         " with instance " + this + ".");
 
     Logger.info(LOG_TAG, "Account last synced at: " + fxAccount.getLastSyncedTimestamp());
 
-    if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
+    if (FxAccountUtils.LOG_PERSONAL_INFORMATION) {
       fxAccount.dump();
     }
 
     final EnumSet<FirefoxAccounts.SyncHint> syncHints = FirefoxAccounts.getHintsToSyncFromBundle(extras);
     FirefoxAccounts.logSyncHints(syncHints);
 
     // This applies even to forced syncs, but only on success.
     if (this.lastSyncRealtimeMillis > 0L &&