delegate = new ResendCodeDelegate(context);
-
- byte[] sessionToken;
- try {
- sessionToken = ((Engaged) fxAccount.getState()).getSessionToken();
- } catch (Exception e) {
- delegate.handleError(e);
- return;
- }
- if (sessionToken == null) {
- delegate.handleError(new IllegalStateException("sessionToken should not be null"));
- return;
- }
-
- Executor executor = Executors.newSingleThreadExecutor();
- FxAccountClient client = new FxAccountClient20(fxAccount.getAccountServerURI(), executor);
- new FxAccountResendCodeTask(context, sessionToken, client, delegate).execute();
- }
-
@Override
public void onClick(View v) {
- resendCode(this, fxAccount);
+ FxAccountCodeResender.resendCode(this, fxAccount);
}
}
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java mozilla-release/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java 2014-09-24 03:05:32.000000000 +0200
@@ -21,7 +21,7 @@
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
import org.mozilla.gecko.background.fxa.PasswordStretcher;
import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.FxAccountCreateAccountTask;
+import org.mozilla.gecko.fxa.tasks.FxAccountCreateAccountTask;
import android.app.AlertDialog;
import android.app.Dialog;
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java mozilla-release/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java 2014-09-24 03:05:32.000000000 +0200
@@ -6,13 +6,11 @@
import java.util.Locale;
-import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
import org.mozilla.gecko.fxa.FirefoxAccounts;
import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
import org.mozilla.gecko.sync.setup.activities.LocaleAware;
@@ -109,11 +107,7 @@
protected void linkifyOldFirefoxLink() {
TextView oldFirefox = (TextView) findViewById(R.id.old_firefox);
String text = getResources().getString(R.string.fxaccount_getting_started_old_firefox);
- String VERSION = AppConstants.MOZ_APP_VERSION;
- String OS = AppConstants.OS_TARGET;
-
- String LOCALE = Utils.getLanguageTag(Locale.getDefault());
- String url = getResources().getString(R.string.fxaccount_link_old_firefox, VERSION, OS, LOCALE);
+ 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.
ActivityUtils.linkTextView(oldFirefox, text, url);
}
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountSetupTask.java mozilla-release/mobile/android/base/fxa/activities/FxAccountSetupTask.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountSetupTask.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountSetupTask.java 1970-01-01 01:00:00.000000000 +0100
@@ -1,172 +0,0 @@
-/* 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.activities;
-
-import java.io.UnsupportedEncodingException;
-import java.util.concurrent.CountDownLatch;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.background.fxa.FxAccountClient;
-import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
-import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
-import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
-import org.mozilla.gecko.background.fxa.PasswordStretcher;
-import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.InnerRequestDelegate;
-
-import android.content.Context;
-import android.os.AsyncTask;
-
-/**
- * An AsyncTask
wrapper around signing up for, and signing in to, a
- * Firefox Account.
- *
- * It's strange to add explicit blocking to callback-threading code, but we do
- * it here to take advantage of Android's built in support for background work.
- * We really want to avoid making a threading mistake that brings down the whole
- * process.
- */
-abstract class FxAccountSetupTask extends AsyncTask> {
- private static final String LOG_TAG = FxAccountSetupTask.class.getSimpleName();
-
- public interface ProgressDisplay {
- public void showProgress();
- public void dismissProgress();
- }
-
- protected final Context context;
- protected final FxAccountClient client;
- protected final ProgressDisplay progressDisplay;
-
- // Initialized lazily.
- protected byte[] quickStretchedPW;
-
- // AsyncTask's are one-time-use, so final members are fine.
- protected final CountDownLatch latch = new CountDownLatch(1);
- protected final InnerRequestDelegate innerDelegate = new InnerRequestDelegate(latch);
-
- protected final RequestDelegate delegate;
-
- public FxAccountSetupTask(Context context, ProgressDisplay progressDisplay, FxAccountClient client, RequestDelegate delegate) {
- this.context = context;
- this.client = client;
- this.delegate = delegate;
- this.progressDisplay = progressDisplay;
- }
-
- @Override
- protected void onPreExecute() {
- if (progressDisplay != null) {
- progressDisplay.showProgress();
- }
- }
-
- @Override
- protected void onPostExecute(InnerRequestDelegate result) {
- if (progressDisplay != null) {
- progressDisplay.dismissProgress();
- }
-
- // We are on the UI thread, and need to invoke these callbacks here to allow UI updating.
- if (innerDelegate.failure != null) {
- delegate.handleFailure(innerDelegate.failure);
- } else if (innerDelegate.exception != null) {
- delegate.handleError(innerDelegate.exception);
- } else {
- delegate.handleSuccess(result.response);
- }
- }
-
- @Override
- protected void onCancelled(InnerRequestDelegate result) {
- if (progressDisplay != null) {
- progressDisplay.dismissProgress();
- }
- delegate.handleError(new IllegalStateException("Task was cancelled."));
- }
-
- protected static class InnerRequestDelegate implements RequestDelegate {
- protected final CountDownLatch latch;
- public T response = null;
- public Exception exception = null;
- public FxAccountClientRemoteException failure = null;
-
- protected InnerRequestDelegate(CountDownLatch latch) {
- this.latch = latch;
- }
-
- @Override
- public void handleError(Exception e) {
- Logger.error(LOG_TAG, "Got exception.");
- this.exception = e;
- latch.countDown();
- }
-
- @Override
- public void handleFailure(FxAccountClientRemoteException e) {
- Logger.warn(LOG_TAG, "Got failure.");
- this.failure = e;
- latch.countDown();
- }
-
- @Override
- public void handleSuccess(T result) {
- Logger.info(LOG_TAG, "Got success.");
- this.response = result;
- latch.countDown();
- }
- }
-
- public static class FxAccountCreateAccountTask extends FxAccountSetupTask {
- private static final String LOG_TAG = FxAccountCreateAccountTask.class.getSimpleName();
-
- protected final byte[] emailUTF8;
- protected final PasswordStretcher passwordStretcher;
-
- public FxAccountCreateAccountTask(Context context, ProgressDisplay progressDisplay, String email, PasswordStretcher passwordStretcher, FxAccountClient client, RequestDelegate delegate) throws UnsupportedEncodingException {
- super(context, progressDisplay, client, delegate);
- this.emailUTF8 = email.getBytes("UTF-8");
- this.passwordStretcher = passwordStretcher;
- }
-
- @Override
- protected InnerRequestDelegate doInBackground(Void... arg0) {
- try {
- client.createAccountAndGetKeys(emailUTF8, passwordStretcher, innerDelegate);
- latch.await();
- return innerDelegate;
- } catch (Exception e) {
- Logger.error(LOG_TAG, "Got exception logging in.", e);
- delegate.handleError(e);
- }
- return null;
- }
- }
-
- public static class FxAccountSignInTask extends FxAccountSetupTask {
- protected static final String LOG_TAG = FxAccountSignInTask.class.getSimpleName();
-
- protected final byte[] emailUTF8;
- protected final PasswordStretcher passwordStretcher;
-
- public FxAccountSignInTask(Context context, ProgressDisplay progressDisplay, String email, PasswordStretcher passwordStretcher, FxAccountClient client, RequestDelegate delegate) throws UnsupportedEncodingException {
- super(context, progressDisplay, client, delegate);
- this.emailUTF8 = email.getBytes("UTF-8");
- this.passwordStretcher = passwordStretcher;
- }
-
- @Override
- protected InnerRequestDelegate doInBackground(Void... arg0) {
- try {
- client.loginAndGetKeys(emailUTF8, passwordStretcher, innerDelegate);
- latch.await();
- return innerDelegate;
- } catch (Exception e) {
- Logger.error(LOG_TAG, "Got exception signing in.", e);
- delegate.handleError(e);
- }
- return null;
- }
- }
-}
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountSignInActivity.java mozilla-release/mobile/android/base/fxa/activities/FxAccountSignInActivity.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountSignInActivity.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountSignInActivity.java 2014-09-24 03:05:32.000000000 +0200
@@ -16,7 +16,7 @@
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
import org.mozilla.gecko.background.fxa.PasswordStretcher;
import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.FxAccountSignInTask;
+import org.mozilla.gecko.fxa.tasks.FxAccountSignInTask;
import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
import android.content.Intent;
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountStatusFragment.java mozilla-release/mobile/android/base/fxa/activities/FxAccountStatusFragment.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountStatusFragment.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountStatusFragment.java 2014-09-24 03:05:32.000000000 +0200
@@ -17,6 +17,8 @@
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;
+import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
import org.mozilla.gecko.sync.SyncConfiguration;
import android.accounts.Account;
@@ -27,10 +29,13 @@
import android.os.Bundle;
import android.os.Handler;
import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
+import android.text.TextUtils;
/**
* A fragment that displays the status of an AndroidFxAccount.
@@ -38,7 +43,9 @@
* The owning activity is responsible for providing an AndroidFxAccount at
* appropriate times.
*/
-public class FxAccountStatusFragment extends PreferenceFragment implements OnPreferenceClickListener {
+public class FxAccountStatusFragment
+ extends PreferenceFragment
+ implements OnPreferenceClickListener, OnPreferenceChangeListener {
private static final String LOG_TAG = FxAccountStatusFragment.class.getSimpleName();
// When a checkbox is toggled, wait 5 seconds (for other checkbox actions)
@@ -64,7 +71,12 @@
protected CheckBoxPreference tabsPreference;
protected CheckBoxPreference passwordsPreference;
+ protected EditTextPreference deviceNamePreference;
+
protected volatile AndroidFxAccount fxAccount;
+ // The contract is: when fxAccount is non-null, then clientsDataDelegate is
+ // non-null. If violated then an IllegalStateException is thrown.
+ protected volatile SharedPreferencesClientsDataDelegate clientsDataDelegate;
// Used to post delayed sync requests.
protected Handler handler;
@@ -87,6 +99,10 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ addPreferences();
+ }
+
+ protected void addPreferences() {
addPreferencesFromResource(R.xml.fxaccount_status_prefscreen);
emailPreference = ensureFindPreference("email");
@@ -118,6 +134,9 @@
historyPreference.setOnPreferenceClickListener(this);
tabsPreference.setOnPreferenceClickListener(this);
passwordsPreference.setOnPreferenceClickListener(this);
+
+ deviceNamePreference = (EditTextPreference) ensureFindPreference("device_name");
+ deviceNamePreference.setOnPreferenceChangeListener(this);
}
/**
@@ -142,7 +161,7 @@
}
if (preference == needsVerificationPreference) {
- FxAccountConfirmAccountActivity.resendCode(getActivity().getApplicationContext(), fxAccount);
+ FxAccountCodeResender.resendCode(getActivity().getApplicationContext(), fxAccount);
Intent intent = new Intent(getActivity(), FxAccountConfirmAccountActivity.class);
// Per http://stackoverflow.com/a/8992365, this triggers a known bug with
@@ -176,6 +195,8 @@
historyPreference.setEnabled(enabled);
tabsPreference.setEnabled(enabled);
passwordsPreference.setEnabled(enabled);
+ // Since we can't sync, we can't update our remote client record.
+ deviceNamePreference.setEnabled(enabled);
}
/**
@@ -293,6 +314,14 @@
throw new IllegalArgumentException("fxAccount must not be null");
}
this.fxAccount = fxAccount;
+ try {
+ this.clientsDataDelegate = new SharedPreferencesClientsDataDelegate(fxAccount.getSyncPrefs());
+ } catch (Exception e) {
+ Logger.error(LOG_TAG, "Got exception fetching Sync prefs associated to Firefox Account; aborting.", e);
+ // Something is terribly wrong; best to get a stack trace rather than
+ // continue with a null clients delegate.
+ throw new IllegalStateException(e);
+ }
handler = new Handler(); // Attached to current (assumed to be UI) thread.
@@ -318,6 +347,17 @@
FxAccountSyncStatusHelper.getInstance().stopObserving(syncStatusDelegate);
}
+ protected void hardRefresh() {
+ // This is the only way to guarantee that the EditText dialogs created by
+ // EditTextPreferences are re-created. This works around the issue described
+ // at http://androiddev.orkitra.com/?p=112079.
+ final PreferenceScreen statusScreen = (PreferenceScreen) ensureFindPreference("status_screen");
+ statusScreen.removeAll();
+ addPreferences();
+
+ refresh();
+ }
+
protected void refresh() {
// refresh is called from our onResume, which can happen before the owning
// Activity tells us about an account (via our public
@@ -371,6 +411,10 @@
// No matter our state, we should update the checkboxes.
updateSelectedEngines();
}
+
+ final String clientName = clientsDataDelegate.getClientName();
+ deviceNamePreference.setSummary(clientName);
+ deviceNamePreference.setText(clientName);
}
/**
@@ -570,4 +614,22 @@
button.setOnPreferenceClickListener(listener);
}
}
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == deviceNamePreference) {
+ String newClientName = (String) newValue;
+ if (TextUtils.isEmpty(newClientName)) {
+ newClientName = clientsDataDelegate.getDefaultClientName();
+ }
+ final long now = System.currentTimeMillis();
+ clientsDataDelegate.setClientName(newClientName, now);
+ requestDelayedSync(); // Try to update our remote client record.
+ hardRefresh(); // Updates the value displayed to the user, among other things.
+ return true;
+ }
+
+ // For everything else, accept the change.
+ return true;
+ }
}
diff -ruN mozilla-esr31/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java mozilla-release/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java
--- mozilla-esr31/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/activities/FxAccountUpdateCredentialsActivity.java 2014-09-24 03:05:32.000000000 +0200
@@ -18,11 +18,11 @@
import org.mozilla.gecko.background.fxa.PasswordStretcher;
import org.mozilla.gecko.fxa.FirefoxAccounts;
import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.FxAccountSignInTask;
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;
diff -ruN mozilla-esr31/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java mozilla-release/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java
--- mozilla-esr31/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java 2015-02-25 19:21:06.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/sync/FxAccountSyncAdapter.java 2014-09-24 03:05:33.000000000 +0200
@@ -357,7 +357,11 @@
FxAccountGlobalSession globalSession = null;
try {
- ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs);
+ final ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs);
+ 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());
+ }
// We compute skew over time using SkewHandler. This yields an unchanging
// skew adjustment that the HawkAuthHeaderProvider uses to adjust its
diff -ruN mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountCodeResender.java mozilla-release/mobile/android/base/fxa/tasks/FxAccountCodeResender.java
--- mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountCodeResender.java 1970-01-01 01:00:00.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/tasks/FxAccountCodeResender.java 2014-09-24 03:05:33.000000000 +0200
@@ -0,0 +1,108 @@
+/* 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.tasks;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.background.common.log.Logger;
+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.FxAccountClientException.FxAccountClientRemoteException;
+import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
+import org.mozilla.gecko.fxa.login.Engaged;
+
+import android.content.Context;
+import android.widget.Toast;
+
+/**
+ * A helper class that provides a simple interface for requesting
+ * a Firefox Account verification email to be resent.
+ */
+public class FxAccountCodeResender {
+ private static final String LOG_TAG = FxAccountCodeResender.class.getSimpleName();
+
+ private static class FxAccountResendCodeTask extends FxAccountSetupTask {
+ protected static final String LOG_TAG = FxAccountResendCodeTask.class.getSimpleName();
+
+ protected final byte[] sessionToken;
+
+ public FxAccountResendCodeTask(Context context, byte[] sessionToken, FxAccountClient client, RequestDelegate delegate) {
+ super(context, null, client, delegate);
+ this.sessionToken = sessionToken;
+ }
+
+ @Override
+ protected InnerRequestDelegate doInBackground(Void... arg0) {
+ try {
+ client.resendCode(sessionToken, innerDelegate);
+ latch.await();
+ return innerDelegate;
+ } catch (Exception e) {
+ Logger.error(LOG_TAG, "Got exception signing in.", e);
+ delegate.handleError(e);
+ }
+ return null;
+ }
+ }
+
+ private static class ResendCodeDelegate implements RequestDelegate {
+ public final Context context;
+
+ public ResendCodeDelegate(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public void handleError(Exception e) {
+ Logger.warn(LOG_TAG, "Got exception requesting fresh confirmation link; ignoring.", e);
+ Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_not_sent, Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void handleFailure(FxAccountClientRemoteException e) {
+ handleError(e);
+ }
+
+ @Override
+ public void handleSuccess(Void result) {
+ Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_sent, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * Resends the account verification email, and displays an appropriate
+ * toast on both send success and failure. Note that because the underlying implementation
+ * uses {@link AsyncTask}, the provided context must be UI-capable and
+ * this method called from the UI thread.
+ *
+ * Note that it may actually be possible to run this (and the {@link AsyncTask}) method
+ * from a background thread - but this hasn't been tested.
+ *
+ * @param context A UI-capable Android context.
+ * @param fxAccount The Firefox Account to resend the code to.
+ */
+ public static void resendCode(Context context, AndroidFxAccount fxAccount) {
+ RequestDelegate delegate = new ResendCodeDelegate(context);
+
+ byte[] sessionToken;
+ try {
+ sessionToken = ((Engaged) fxAccount.getState()).getSessionToken();
+ } catch (Exception e) {
+ delegate.handleError(e);
+ return;
+ }
+ if (sessionToken == null) {
+ delegate.handleError(new IllegalStateException("sessionToken should not be null"));
+ return;
+ }
+
+ Executor executor = Executors.newSingleThreadExecutor();
+ FxAccountClient client = new FxAccountClient20(fxAccount.getAccountServerURI(), executor);
+ new FxAccountResendCodeTask(context, sessionToken, client, delegate).execute();
+ }
+}
diff -ruN mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountCreateAccountTask.java mozilla-release/mobile/android/base/fxa/tasks/FxAccountCreateAccountTask.java
--- mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountCreateAccountTask.java 1970-01-01 01:00:00.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/tasks/FxAccountCreateAccountTask.java 2014-09-24 03:05:33.000000000 +0200
@@ -0,0 +1,41 @@
+/* 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.tasks;
+
+import java.io.UnsupportedEncodingException;
+
+import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountClient;
+import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
+import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
+import org.mozilla.gecko.background.fxa.PasswordStretcher;
+
+import android.content.Context;
+
+public class FxAccountCreateAccountTask extends FxAccountSetupTask {
+ private static final String LOG_TAG = FxAccountCreateAccountTask.class.getSimpleName();
+
+ protected final byte[] emailUTF8;
+ protected final PasswordStretcher passwordStretcher;
+
+ public FxAccountCreateAccountTask(Context context, ProgressDisplay progressDisplay, String email, PasswordStretcher passwordStretcher, FxAccountClient client, RequestDelegate delegate) throws UnsupportedEncodingException {
+ super(context, progressDisplay, client, delegate);
+ this.emailUTF8 = email.getBytes("UTF-8");
+ this.passwordStretcher = passwordStretcher;
+ }
+
+ @Override
+ protected InnerRequestDelegate doInBackground(Void... arg0) {
+ try {
+ client.createAccountAndGetKeys(emailUTF8, passwordStretcher, innerDelegate);
+ latch.await();
+ return innerDelegate;
+ } catch (Exception e) {
+ Logger.error(LOG_TAG, "Got exception logging in.", e);
+ delegate.handleError(e);
+ }
+ return null;
+ }
+}
diff -ruN mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountSetupTask.java mozilla-release/mobile/android/base/fxa/tasks/FxAccountSetupTask.java
--- mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountSetupTask.java 1970-01-01 01:00:00.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/tasks/FxAccountSetupTask.java 2014-09-24 03:05:33.000000000 +0200
@@ -0,0 +1,117 @@
+/* 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.tasks;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountClient;
+import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
+import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
+import org.mozilla.gecko.fxa.tasks.FxAccountSetupTask.InnerRequestDelegate;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+/**
+ * An AsyncTask
wrapper around signing up for, and signing in to, a
+ * Firefox Account.
+ *
+ * It's strange to add explicit blocking to callback-threading code, but we do
+ * it here to take advantage of Android's built in support for background work.
+ * We really want to avoid making a threading mistake that brings down the whole
+ * process.
+ */
+public abstract class FxAccountSetupTask extends AsyncTask> {
+ private static final String LOG_TAG = FxAccountSetupTask.class.getSimpleName();
+
+ public interface ProgressDisplay {
+ public void showProgress();
+ public void dismissProgress();
+ }
+
+ protected final Context context;
+ protected final FxAccountClient client;
+ protected final ProgressDisplay progressDisplay;
+
+ // Initialized lazily.
+ protected byte[] quickStretchedPW;
+
+ // AsyncTask's are one-time-use, so final members are fine.
+ protected final CountDownLatch latch = new CountDownLatch(1);
+ protected final InnerRequestDelegate innerDelegate = new InnerRequestDelegate(latch);
+
+ protected final RequestDelegate delegate;
+
+ public FxAccountSetupTask(Context context, ProgressDisplay progressDisplay, FxAccountClient client, RequestDelegate delegate) {
+ this.context = context;
+ this.client = client;
+ this.delegate = delegate;
+ this.progressDisplay = progressDisplay;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ if (progressDisplay != null) {
+ progressDisplay.showProgress();
+ }
+ }
+
+ @Override
+ protected void onPostExecute(InnerRequestDelegate result) {
+ if (progressDisplay != null) {
+ progressDisplay.dismissProgress();
+ }
+
+ // We are on the UI thread, and need to invoke these callbacks here to allow UI updating.
+ if (innerDelegate.failure != null) {
+ delegate.handleFailure(innerDelegate.failure);
+ } else if (innerDelegate.exception != null) {
+ delegate.handleError(innerDelegate.exception);
+ } else {
+ delegate.handleSuccess(result.response);
+ }
+ }
+
+ @Override
+ protected void onCancelled(InnerRequestDelegate result) {
+ if (progressDisplay != null) {
+ progressDisplay.dismissProgress();
+ }
+ delegate.handleError(new IllegalStateException("Task was cancelled."));
+ }
+
+ protected static class InnerRequestDelegate implements RequestDelegate {
+ protected final CountDownLatch latch;
+ public T response = null;
+ public Exception exception = null;
+ public FxAccountClientRemoteException failure = null;
+
+ protected InnerRequestDelegate(CountDownLatch latch) {
+ this.latch = latch;
+ }
+
+ @Override
+ public void handleError(Exception e) {
+ Logger.error(LOG_TAG, "Got exception.");
+ this.exception = e;
+ latch.countDown();
+ }
+
+ @Override
+ public void handleFailure(FxAccountClientRemoteException e) {
+ Logger.warn(LOG_TAG, "Got failure.");
+ this.failure = e;
+ latch.countDown();
+ }
+
+ @Override
+ public void handleSuccess(T result) {
+ Logger.info(LOG_TAG, "Got success.");
+ this.response = result;
+ latch.countDown();
+ }
+ }
+}
diff -ruN mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountSignInTask.java mozilla-release/mobile/android/base/fxa/tasks/FxAccountSignInTask.java
--- mozilla-esr31/mobile/android/base/fxa/tasks/FxAccountSignInTask.java 1970-01-01 01:00:00.000000000 +0100
+++ mozilla-release/mobile/android/base/fxa/tasks/FxAccountSignInTask.java 2014-09-24 03:05:33.000000000 +0200
@@ -0,0 +1,41 @@
+/* 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.tasks;
+
+import java.io.UnsupportedEncodingException;
+
+import org.mozilla.gecko.background.common.log.Logger;
+import org.mozilla.gecko.background.fxa.FxAccountClient;
+import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
+import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
+import org.mozilla.gecko.background.fxa.PasswordStretcher;
+
+import android.content.Context;
+
+public class FxAccountSignInTask extends FxAccountSetupTask {
+ protected static final String LOG_TAG = FxAccountSignInTask.class.getSimpleName();
+
+ protected final byte[] emailUTF8;
+ protected final PasswordStretcher passwordStretcher;
+
+ public FxAccountSignInTask(Context context, ProgressDisplay progressDisplay, String email, PasswordStretcher passwordStretcher, FxAccountClient client, RequestDelegate delegate) throws UnsupportedEncodingException {
+ super(context, progressDisplay, client, delegate);
+ this.emailUTF8 = email.getBytes("UTF-8");
+ this.passwordStretcher = passwordStretcher;
+ }
+
+ @Override
+ protected InnerRequestDelegate doInBackground(Void... arg0) {
+ try {
+ client.loginAndGetKeys(emailUTF8, passwordStretcher, innerDelegate);
+ latch.await();
+ return innerDelegate;
+ } catch (Exception e) {
+ Logger.error(LOG_TAG, "Got exception signing in.", e);
+ delegate.handleError(e);
+ }
+ return null;
+ }
+}
--- mozilla-esr31/mobile/android/base/android-services.mozbuild 2015-02-25 19:21:05.000000000 +0100
+++ mozilla-release/mobile/android/base/android-services.mozbuild 2014-09-24 03:05:32.000000000 +0200
@@ -555,7 +557,6 @@
'fxa/activities/FxAccountCreateAccountActivity.java',
'fxa/activities/FxAccountCreateAccountNotAllowedActivity.java',
'fxa/activities/FxAccountGetStartedActivity.java',
- 'fxa/activities/FxAccountSetupTask.java',
'fxa/activities/FxAccountSignInActivity.java',
'fxa/activities/FxAccountStatusActivity.java',
'fxa/activities/FxAccountStatusFragment.java',
@@ -589,6 +590,10 @@
'fxa/sync/FxAccountSyncService.java',
'fxa/sync/FxAccountSyncStatusHelper.java',
'fxa/sync/SchedulePolicy.java',
+ 'fxa/tasks/FxAccountCodeResender.java',
+ 'fxa/tasks/FxAccountCreateAccountTask.java',
+ 'fxa/tasks/FxAccountSetupTask.java',
+ 'fxa/tasks/FxAccountSignInTask.java',
'sync/AlreadySyncingException.java',
'sync/BackoffHandler.java',
'sync/BadRequiredFieldJSONException.java',