mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-11 14:28:42 +00:00
Bug 965366 - Make Firefox Account's StatusActivity checkboxes live. r=rnewman
This commit is contained in:
parent
cbe3deed81
commit
c07cdccfb4
@ -6,6 +6,7 @@ package org.mozilla.gecko.fxa.activities;
|
||||
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.authenticator.FxAccountAuthenticator;
|
||||
import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
|
||||
|
||||
@ -130,4 +131,15 @@ public abstract class FxAccountAbstractActivity extends Activity {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to fetch (unique) Android Firefox Account if one exists, or return null.
|
||||
*/
|
||||
protected AndroidFxAccount getAndroidFxAccount() {
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(this);
|
||||
if (accounts.length < 1 || accounts[0] == null) {
|
||||
return null;
|
||||
}
|
||||
return new AndroidFxAccount(this, accounts[0]);
|
||||
}
|
||||
}
|
||||
|
@ -189,9 +189,7 @@ abstract public class FxAccountAbstractSetupActivity extends FxAccountAbstractAc
|
||||
successIntent = new Intent(this, FxAccountVerifiedAccountActivity.class);
|
||||
} else {
|
||||
successIntent = new Intent(this, FxAccountConfirmAccountActivity.class);
|
||||
successIntent.putExtra("sessionToken", result.sessionToken);
|
||||
}
|
||||
successIntent.putExtra("email", email);
|
||||
// Per http://stackoverflow.com/a/8992365, this triggers a known bug with
|
||||
// the soft keyboard not being shown for the started activity. Why, Android, why?
|
||||
successIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
|
@ -13,9 +13,11 @@ 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.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 android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
@ -27,31 +29,18 @@ import android.widget.Toast;
|
||||
* Activity which displays account created successfully screen to the user, and
|
||||
* starts them on the email verification path.
|
||||
*/
|
||||
public class FxAccountConfirmAccountActivity extends Activity implements OnClickListener {
|
||||
protected static final String LOG_TAG = FxAccountConfirmAccountActivity.class.getSimpleName();
|
||||
public class FxAccountConfirmAccountActivity extends FxAccountAbstractActivity implements OnClickListener {
|
||||
private static final String LOG_TAG = FxAccountConfirmAccountActivity.class.getSimpleName();
|
||||
|
||||
protected byte[] sessionToken;
|
||||
// Set in onCreate.
|
||||
protected TextView verificationLinkTextView;
|
||||
protected View resendLink;
|
||||
|
||||
/**
|
||||
* Helper to find view or error if it is missing.
|
||||
*
|
||||
* @param id of view to find.
|
||||
* @param description to print in error.
|
||||
* @return non-null <code>View</code> instance.
|
||||
*/
|
||||
public View ensureFindViewById(View v, int id, String description) {
|
||||
View view;
|
||||
if (v != null) {
|
||||
view = v.findViewById(id);
|
||||
} else {
|
||||
view = findViewById(id);
|
||||
}
|
||||
if (view == null) {
|
||||
String message = "Could not find view " + description + ".";
|
||||
Logger.error(LOG_TAG, message);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
return view;
|
||||
// Set in onResume.
|
||||
protected AndroidFxAccount fxAccount;
|
||||
|
||||
public FxAccountConfirmAccountActivity() {
|
||||
super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,21 +53,36 @@ public class FxAccountConfirmAccountActivity extends Activity implements OnClick
|
||||
super.onCreate(icicle);
|
||||
setContentView(R.layout.fxaccount_confirm_account);
|
||||
|
||||
if (getIntent() != null && getIntent().getExtras() != null) {
|
||||
Bundle extras = getIntent().getExtras();
|
||||
TextView verificationLinkTextView = (TextView) ensureFindViewById(null, R.id.verification_link_text, "verification link text");
|
||||
String text = getResources().getString(R.string.fxaccount_confirm_account_verification_link, extras.getString("email"));
|
||||
verificationLinkTextView.setText(text);
|
||||
sessionToken = extras.getByteArray("sessionToken");
|
||||
}
|
||||
|
||||
View resendLink = ensureFindViewById(null, R.id.resend_confirmation_email_link, "resend confirmation email link");
|
||||
verificationLinkTextView = (TextView) ensureFindViewById(null, R.id.verification_link_text, "verification link text");
|
||||
resendLink = ensureFindViewById(null, R.id.resend_confirmation_email_link, "resend confirmation email link");
|
||||
resendLink.setOnClickListener(this);
|
||||
}
|
||||
|
||||
if (sessionToken == null) {
|
||||
resendLink.setEnabled(false);
|
||||
resendLink.setClickable(false);
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
this.fxAccount = getAndroidFxAccount();
|
||||
if (fxAccount == null) {
|
||||
Logger.warn(LOG_TAG, "Could not get Firefox Account.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
State state = fxAccount.getState();
|
||||
if (state.getStateLabel() != StateLabel.Engaged) {
|
||||
Logger.warn(LOG_TAG, "Cannot confirm Firefox Account in state: " + state.getStateLabel());
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final String email = fxAccount.getEmail();
|
||||
final String text = getResources().getString(R.string.fxaccount_confirm_account_verification_link, email);
|
||||
verificationLinkTextView.setText(text);
|
||||
|
||||
boolean resendLinkShouldBeEnabled = ((Engaged) state).getSessionToken() != null;
|
||||
resendLink.setEnabled(resendLinkShouldBeEnabled);
|
||||
resendLink.setClickable(resendLinkShouldBeEnabled);
|
||||
}
|
||||
|
||||
public static class FxAccountResendCodeTask extends FxAccountSetupTask<Void> {
|
||||
@ -105,11 +109,17 @@ public class FxAccountConfirmAccountActivity extends Activity implements OnClick
|
||||
}
|
||||
}
|
||||
|
||||
protected class ResendCodeDelegate implements RequestDelegate<Void> {
|
||||
protected static class ResendCodeDelegate implements RequestDelegate<Void> {
|
||||
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(getApplicationContext(), R.string.fxaccount_confirm_account_verification_link_not_sent, Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_not_sent, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -119,20 +129,32 @@ public class FxAccountConfirmAccountActivity extends Activity implements OnClick
|
||||
|
||||
@Override
|
||||
public void handleSuccess(Void result) {
|
||||
Toast.makeText(getApplicationContext(), R.string.fxaccount_confirm_account_verification_link_sent, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_sent, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
protected void resendCode(byte[] sessionToken) {
|
||||
String serverURI = FxAccountConstants.DEFAULT_AUTH_SERVER_ENDPOINT;
|
||||
RequestDelegate<Void> delegate = new ResendCodeDelegate();
|
||||
public static void resendCode(Context context, AndroidFxAccount fxAccount) {
|
||||
RequestDelegate<Void> 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(serverURI, executor);
|
||||
new FxAccountResendCodeTask(this, sessionToken, client, delegate).execute();
|
||||
FxAccountClient client = new FxAccountClient20(fxAccount.getAccountServerURI(), executor);
|
||||
new FxAccountResendCodeTask(context, sessionToken, client, delegate).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resendCode(sessionToken);
|
||||
resendCode(this, fxAccount);
|
||||
}
|
||||
}
|
||||
|
@ -4,38 +4,67 @@
|
||||
|
||||
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.db.BrowserContract;
|
||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.authenticator.FxAccountAuthenticator;
|
||||
import org.mozilla.gecko.fxa.login.Married;
|
||||
import org.mozilla.gecko.fxa.login.State;
|
||||
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ViewFlipper;
|
||||
|
||||
/**
|
||||
* Activity which displays account status.
|
||||
*/
|
||||
public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
protected static final String LOG_TAG = FxAccountStatusActivity.class.getSimpleName();
|
||||
public class FxAccountStatusActivity extends FxAccountAbstractActivity implements OnClickListener {
|
||||
private static final String LOG_TAG = FxAccountStatusActivity.class.getSimpleName();
|
||||
|
||||
// When a checkbox is toggled, wait 5 seconds (for other checkbox actions)
|
||||
// before trying to sync. Should we quit the activity before the sync request
|
||||
// happens, that's okay: the runnable will run if the UI thread is still
|
||||
// around to service it, and since we're not updating any UI, we'll just
|
||||
// schedule the sync as usual. See also comment below about garbage
|
||||
// collection.
|
||||
private static final long DELAY_IN_MILLISECONDS_BEFORE_REQUESTING_SYNC = 5 * 1000;
|
||||
|
||||
// Set in onCreate.
|
||||
protected TextView syncStatusTextView;
|
||||
protected ViewFlipper connectionStatusViewFlipper;
|
||||
protected View connectionStatusUnverifiedView;
|
||||
protected View connectionStatusSignInView;
|
||||
protected TextView emailTextView;
|
||||
|
||||
protected CheckBox bookmarksCheckBox;
|
||||
protected CheckBox historyCheckBox;
|
||||
protected CheckBox passwordsCheckBox;
|
||||
protected CheckBox tabsCheckBox;
|
||||
|
||||
// Used to post delayed sync requests.
|
||||
protected Handler handler;
|
||||
|
||||
// Set in onResume.
|
||||
protected AndroidFxAccount fxAccount;
|
||||
// Member variable so that re-posting pushes back the already posted instance.
|
||||
// This Runnable references the fxAccount above, so it is not specific a
|
||||
// single account. (That is, it does not capture a single account instance.)
|
||||
protected Runnable requestSyncRunnable;
|
||||
|
||||
public FxAccountStatusActivity() {
|
||||
super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST);
|
||||
}
|
||||
@ -58,8 +87,42 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
|
||||
launchActivityOnClick(connectionStatusSignInView, FxAccountUpdateCredentialsActivity.class);
|
||||
|
||||
connectionStatusUnverifiedView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
FxAccountConfirmAccountActivity.resendCode(getApplicationContext(), fxAccount);
|
||||
launchActivity(FxAccountConfirmAccountActivity.class);
|
||||
}
|
||||
});
|
||||
|
||||
emailTextView = (TextView) findViewById(R.id.email);
|
||||
|
||||
bookmarksCheckBox = (CheckBox) findViewById(R.id.bookmarks_checkbox);
|
||||
historyCheckBox = (CheckBox) findViewById(R.id.history_checkbox);
|
||||
passwordsCheckBox = (CheckBox) findViewById(R.id.passwords_checkbox);
|
||||
tabsCheckBox = (CheckBox) findViewById(R.id.tabs_checkbox);
|
||||
bookmarksCheckBox.setOnClickListener(this);
|
||||
historyCheckBox.setOnClickListener(this);
|
||||
passwordsCheckBox.setOnClickListener(this);
|
||||
tabsCheckBox.setOnClickListener(this);
|
||||
|
||||
handler = new Handler(); // Attached to current (UI) thread.
|
||||
// Runnable is not specific to one Firefox Account. This runnable will keep
|
||||
// a reference to this activity alive, but we expect posted runnables to be
|
||||
// serviced very quickly, so this is not an issue.
|
||||
requestSyncRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (fxAccount == null) {
|
||||
return;
|
||||
}
|
||||
Logger.info(LOG_TAG, "Requesting a sync sometime soon.");
|
||||
// Request a sync, but not necessarily an immediate sync.
|
||||
ContentResolver.requestSync(fxAccount.getAndroidAccount(), BrowserContract.AUTHORITY, Bundle.EMPTY);
|
||||
// SyncAdapter.requestImmediateSync(fxAccount.getAndroidAccount(), null);
|
||||
}
|
||||
};
|
||||
|
||||
if (FxAccountConstants.LOG_PERSONAL_INFORMATION) {
|
||||
createDebugButtons();
|
||||
}
|
||||
@ -68,41 +131,55 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
this.fxAccount = getAndroidFxAccount();
|
||||
if (fxAccount == null) {
|
||||
Logger.warn(LOG_TAG, "Could not get Firefox Account.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
protected void setCheckboxesEnabled(boolean enabled) {
|
||||
bookmarksCheckBox.setEnabled(enabled);
|
||||
historyCheckBox.setEnabled(enabled);
|
||||
passwordsCheckBox.setEnabled(enabled);
|
||||
tabsCheckBox.setEnabled(enabled);
|
||||
}
|
||||
|
||||
protected void showNeedsUpgrade() {
|
||||
syncStatusTextView.setText(R.string.fxaccount_status_sync);
|
||||
connectionStatusViewFlipper.setVisibility(View.VISIBLE);
|
||||
connectionStatusViewFlipper.setDisplayedChild(0);
|
||||
setCheckboxesEnabled(false);
|
||||
}
|
||||
|
||||
protected void showNeedsPassword() {
|
||||
syncStatusTextView.setText(R.string.fxaccount_status_sync);
|
||||
connectionStatusViewFlipper.setVisibility(View.VISIBLE);
|
||||
connectionStatusViewFlipper.setDisplayedChild(1);
|
||||
setCheckboxesEnabled(false);
|
||||
}
|
||||
|
||||
protected void showNeedsVerification() {
|
||||
syncStatusTextView.setText(R.string.fxaccount_status_sync);
|
||||
connectionStatusViewFlipper.setVisibility(View.VISIBLE);
|
||||
connectionStatusViewFlipper.setDisplayedChild(2);
|
||||
setCheckboxesEnabled(false);
|
||||
}
|
||||
|
||||
protected void showConnected() {
|
||||
syncStatusTextView.setText(R.string.fxaccount_status_sync_enabled);
|
||||
connectionStatusViewFlipper.setVisibility(View.GONE);
|
||||
setCheckboxesEnabled(true);
|
||||
}
|
||||
|
||||
protected void refresh(Account account) {
|
||||
if (account == null) {
|
||||
redirectToActivity(FxAccountGetStartedActivity.class);
|
||||
return;
|
||||
}
|
||||
emailTextView.setText(account.name);
|
||||
protected void refresh() {
|
||||
emailTextView.setText(fxAccount.getEmail());
|
||||
|
||||
// Interrogate the Firefox Account's state.
|
||||
AndroidFxAccount fxAccount = new AndroidFxAccount(this, account);
|
||||
State state = fxAccount.getState();
|
||||
switch (state.getNeededAction()) {
|
||||
case NeedsUpgrade:
|
||||
@ -117,17 +194,82 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
default:
|
||||
showConnected();
|
||||
}
|
||||
|
||||
updateSelectedEngines();
|
||||
}
|
||||
|
||||
protected void refresh() {
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(this);
|
||||
if (accounts.length < 1) {
|
||||
refresh(null);
|
||||
protected void updateSelectedEngines() {
|
||||
try {
|
||||
SharedPreferences syncPrefs = fxAccount.getSyncPrefs();
|
||||
Map<String, Boolean> engines = SyncConfiguration.getUserSelectedEngines(syncPrefs);
|
||||
if (engines != null) {
|
||||
bookmarksCheckBox.setChecked(engines.containsKey("bookmarks") && engines.get("bookmarks"));
|
||||
historyCheckBox.setChecked(engines.containsKey("history") && engines.get("history"));
|
||||
passwordsCheckBox.setChecked(engines.containsKey("passwords") && engines.get("passwords"));
|
||||
tabsCheckBox.setChecked(engines.containsKey("tabs") && engines.get("tabs"));
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't have user specified preferences. Perhaps we have seen a meta/global?
|
||||
Set<String> enabledNames = SyncConfiguration.getEnabledEngineNames(syncPrefs);
|
||||
if (enabledNames != null) {
|
||||
bookmarksCheckBox.setChecked(enabledNames.contains("bookmarks"));
|
||||
historyCheckBox.setChecked(enabledNames.contains("history"));
|
||||
passwordsCheckBox.setChecked(enabledNames.contains("passwords"));
|
||||
tabsCheckBox.setChecked(enabledNames.contains("tabs"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Okay, we don't have userSelectedEngines or enabledEngines. That means
|
||||
// the user hasn't specified to begin with, we haven't specified here, and
|
||||
// we haven't already seen, Sync engines. We don't know our state, so
|
||||
// let's check everything (the default) and disable everything.
|
||||
bookmarksCheckBox.setChecked(true);
|
||||
historyCheckBox.setChecked(true);
|
||||
passwordsCheckBox.setChecked(true);
|
||||
tabsCheckBox.setChecked(true);
|
||||
setCheckboxesEnabled(false);
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Got exception getting engines to select; ignoring.", e);
|
||||
return;
|
||||
}
|
||||
refresh(accounts[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (view == bookmarksCheckBox ||
|
||||
view == historyCheckBox ||
|
||||
view == passwordsCheckBox ||
|
||||
view == tabsCheckBox) {
|
||||
saveEngineSelections();
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveEngineSelections() {
|
||||
Map<String, Boolean> engineSelections = new HashMap<String, Boolean>();
|
||||
engineSelections.put("bookmarks", bookmarksCheckBox.isChecked());
|
||||
engineSelections.put("history", historyCheckBox.isChecked());
|
||||
engineSelections.put("passwords", passwordsCheckBox.isChecked());
|
||||
engineSelections.put("tabs", tabsCheckBox.isChecked());
|
||||
Logger.info(LOG_TAG, "Persisting engine selections: " + engineSelections.toString());
|
||||
|
||||
try {
|
||||
// No GlobalSession.config, so store directly to prefs. We'd like to do
|
||||
// this on a background thread to avoid IO on the main thread and strict
|
||||
// mode warnings, but all in good time.
|
||||
SyncConfiguration.storeSelectedEnginesToPrefs(fxAccount.getSyncPrefs(), engineSelections);
|
||||
requestDelayedSync();
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Got exception persisting selected engines; ignoring.", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected void requestDelayedSync() {
|
||||
Logger.info(LOG_TAG, "Posting a delayed request for a sync sometime soon.");
|
||||
handler.removeCallbacks(requestSyncRunnable);
|
||||
handler.postDelayed(requestSyncRunnable, DELAY_IN_MILLISECONDS_BEFORE_REQUESTING_SYNC);
|
||||
}
|
||||
|
||||
protected void createDebugButtons() {
|
||||
if (!FxAccountConstants.LOG_PERSONAL_INFORMATION) {
|
||||
@ -141,7 +283,7 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
|
||||
final LinearLayout debugButtonsView = new LinearLayout(this);
|
||||
debugButtonsView.setOrientation(LinearLayout.VERTICAL);
|
||||
debugButtonsView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
|
||||
debugButtonsView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
existingUserView.addView(debugButtonsView, existingUserView.getChildCount());
|
||||
|
||||
Button button;
|
||||
@ -163,13 +305,7 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
button.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Logger.info(LOG_TAG, "Dumping account details.");
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(FxAccountStatusActivity.this);
|
||||
if (accounts.length < 1) {
|
||||
return;
|
||||
}
|
||||
AndroidFxAccount account = new AndroidFxAccount(FxAccountStatusActivity.this, accounts[0]);
|
||||
account.dump();
|
||||
fxAccount.dump();
|
||||
}
|
||||
});
|
||||
|
||||
@ -180,13 +316,9 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Logger.info(LOG_TAG, "Syncing.");
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(FxAccountStatusActivity.this);
|
||||
if (accounts.length < 1) {
|
||||
return;
|
||||
}
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
|
||||
ContentResolver.requestSync(accounts[0], BrowserContract.AUTHORITY, extras);
|
||||
ContentResolver.requestSync(fxAccount.getAndroidAccount(), BrowserContract.AUTHORITY, extras);
|
||||
// No sense refreshing, since the sync will complete in the future.
|
||||
}
|
||||
});
|
||||
@ -197,16 +329,11 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
button.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(FxAccountStatusActivity.this);
|
||||
if (accounts.length < 1) {
|
||||
return;
|
||||
}
|
||||
AndroidFxAccount account = new AndroidFxAccount(FxAccountStatusActivity.this, accounts[0]);
|
||||
State state = account.getState();
|
||||
State state = fxAccount.getState();
|
||||
try {
|
||||
Married married = (Married) state;
|
||||
Logger.info(LOG_TAG, "Moving to Cohabiting state: Forgetting certificate.");
|
||||
account.setState(married.makeCohabitingState());
|
||||
fxAccount.setState(married.makeCohabitingState());
|
||||
refresh();
|
||||
} catch (ClassCastException e) {
|
||||
Logger.info(LOG_TAG, "Not in Married state; can't forget certificate.");
|
||||
@ -222,13 +349,8 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Logger.info(LOG_TAG, "Moving to Separated state: Forgetting password.");
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(FxAccountStatusActivity.this);
|
||||
if (accounts.length < 1) {
|
||||
return;
|
||||
}
|
||||
AndroidFxAccount account = new AndroidFxAccount(FxAccountStatusActivity.this, accounts[0]);
|
||||
State state = account.getState();
|
||||
account.setState(state.makeSeparatedState());
|
||||
State state = fxAccount.getState();
|
||||
fxAccount.setState(state.makeSeparatedState());
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
@ -240,13 +362,8 @@ public class FxAccountStatusActivity extends FxAccountAbstractActivity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Logger.info(LOG_TAG, "Moving to Doghouse state: Requiring upgrade.");
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(FxAccountStatusActivity.this);
|
||||
if (accounts.length < 1) {
|
||||
return;
|
||||
}
|
||||
AndroidFxAccount account = new AndroidFxAccount(FxAccountStatusActivity.this, accounts[0]);
|
||||
State state = account.getState();
|
||||
account.setState(state.makeDoghouseState());
|
||||
State state = fxAccount.getState();
|
||||
fxAccount.setState(state.makeDoghouseState());
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
@ -20,13 +20,10 @@ import org.mozilla.gecko.background.fxa.QuickPasswordStretcher;
|
||||
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.authenticator.FxAccountAuthenticator;
|
||||
import org.mozilla.gecko.fxa.login.Engaged;
|
||||
import org.mozilla.gecko.fxa.login.Separated;
|
||||
import org.mozilla.gecko.fxa.login.State;
|
||||
import org.mozilla.gecko.fxa.login.State.StateLabel;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -42,7 +39,6 @@ public class FxAccountUpdateCredentialsActivity extends FxAccountAbstractSetupAc
|
||||
protected static final String LOG_TAG = FxAccountUpdateCredentialsActivity.class.getSimpleName();
|
||||
|
||||
protected AndroidFxAccount fxAccount;
|
||||
protected Separated accountState;
|
||||
|
||||
public FxAccountUpdateCredentialsActivity() {
|
||||
// We want to share code with the other setup activities, but this activity
|
||||
@ -84,29 +80,21 @@ public class FxAccountUpdateCredentialsActivity extends FxAccountAbstractSetupAc
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(this);
|
||||
if (accounts.length < 1 || accounts[0] == null) {
|
||||
Logger.warn(LOG_TAG, "No Android accounts.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
this.fxAccount = new AndroidFxAccount(this, accounts[0]);
|
||||
this.fxAccount = getAndroidFxAccount();
|
||||
if (fxAccount == null) {
|
||||
Logger.warn(LOG_TAG, "Could not get Firefox Account from Android account.");
|
||||
Logger.warn(LOG_TAG, "Could not get Firefox Account.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
State state = fxAccount.getState();
|
||||
if (state.getStateLabel() != StateLabel.Separated) {
|
||||
Logger.warn(LOG_TAG, "Could not get state from Firefox Account.");
|
||||
Logger.warn(LOG_TAG, "Cannot update credentials from Firefox Account in state: " + state.getStateLabel());
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
this.accountState = (Separated) state;
|
||||
emailEdit.setText(fxAccount.getAndroidAccount().name);
|
||||
emailEdit.setText(fxAccount.getEmail());
|
||||
}
|
||||
|
||||
protected class UpdateCredentialsDelegate implements RequestDelegate<LoginResponse> {
|
||||
@ -165,7 +153,7 @@ public class FxAccountUpdateCredentialsActivity extends FxAccountAbstractSetupAc
|
||||
}
|
||||
|
||||
public void updateCredentials(String email, String password) {
|
||||
String serverURI = FxAccountConstants.DEFAULT_AUTH_SERVER_ENDPOINT;
|
||||
String serverURI = fxAccount.getAccountServerURI();
|
||||
Executor executor = Executors.newSingleThreadExecutor();
|
||||
FxAccountClient client = new FxAccountClient20(serverURI, executor);
|
||||
PasswordStretcher passwordStretcher = new QuickPasswordStretcher(password);
|
||||
|
@ -6,40 +6,24 @@ package org.mozilla.gecko.fxa.activities;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.login.State;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Activity which displays "Account verified" success screen.
|
||||
*/
|
||||
public class FxAccountVerifiedAccountActivity extends Activity {
|
||||
protected static final String LOG_TAG = FxAccountVerifiedAccountActivity.class.getSimpleName();
|
||||
public class FxAccountVerifiedAccountActivity extends FxAccountAbstractActivity {
|
||||
private static final String LOG_TAG = FxAccountVerifiedAccountActivity.class.getSimpleName();
|
||||
|
||||
protected AndroidFxAccount fxAccount;
|
||||
|
||||
protected TextView emailText;
|
||||
|
||||
/**
|
||||
* Helper to find view or error if it is missing.
|
||||
*
|
||||
* @param id of view to find.
|
||||
* @param description to print in error.
|
||||
* @return non-null <code>View</code> instance.
|
||||
*/
|
||||
public View ensureFindViewById(View v, int id, String description) {
|
||||
View view;
|
||||
if (v != null) {
|
||||
view = v.findViewById(id);
|
||||
} else {
|
||||
view = findViewById(id);
|
||||
}
|
||||
if (view == null) {
|
||||
String message = "Could not find view " + description + ".";
|
||||
Logger.error(LOG_TAG, message);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
return view;
|
||||
public FxAccountVerifiedAccountActivity() {
|
||||
super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,8 +37,25 @@ public class FxAccountVerifiedAccountActivity extends Activity {
|
||||
setContentView(R.layout.fxaccount_account_verified);
|
||||
|
||||
emailText = (TextView) ensureFindViewById(null, R.id.email, "email text");
|
||||
if (getIntent() != null && getIntent().getExtras() != null) {
|
||||
emailText.setText(getIntent().getStringExtra("email"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
this.fxAccount = getAndroidFxAccount();
|
||||
if (fxAccount == null) {
|
||||
Logger.warn(LOG_TAG, "Could not get Firefox Account.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
State state = fxAccount.getState();
|
||||
if (!state.verified) {
|
||||
Logger.warn(LOG_TAG, "Firefox Account is not verified; not displaying verified account activity.");
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
emailText.setText(fxAccount.getEmail());
|
||||
}
|
||||
}
|
||||
|
@ -371,4 +371,16 @@ public class AndroidFxAccount {
|
||||
FxAccountConstants.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.
|
||||
*
|
||||
* @return local email address.
|
||||
*/
|
||||
public String getEmail() {
|
||||
return account.name;
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,11 @@ 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;
|
||||
|
||||
@ -68,7 +70,10 @@ public class Engaged extends State {
|
||||
delegate.handleTransition(new RemoteError(e), new Separated(email, uid, verified));
|
||||
return;
|
||||
}
|
||||
delegate.handleTransition(new LogMessage("keys succeeded"), new Cohabiting(email, uid, sessionToken, result.kA, kB, keyPair));
|
||||
Transition transition = verified
|
||||
? new LogMessage("keys succeeded")
|
||||
: new AccountVerified();
|
||||
delegate.handleTransition(transition, new Cohabiting(email, uid, sessionToken, result.kA, kB, keyPair));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -80,4 +85,8 @@ public class Engaged extends State {
|
||||
}
|
||||
return Action.None;
|
||||
}
|
||||
|
||||
public byte[] getSessionToken() {
|
||||
return sessionToken;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,12 @@ public class FxAccountLoginTransition {
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccountVerified extends LogMessage {
|
||||
public AccountVerified() {
|
||||
super(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PasswordRequired extends LogMessage {
|
||||
public PasswordRequired() {
|
||||
super(null);
|
||||
|
@ -43,10 +43,6 @@ public abstract class State {
|
||||
return this.stateLabel;
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return this.verified;
|
||||
}
|
||||
|
||||
public ExtendedJSONObject toJSONObject() {
|
||||
ExtendedJSONObject o = new ExtendedJSONObject();
|
||||
o.put("version", State.CURRENT_VERSION);
|
||||
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false" android:color="@color/fxaccount_input_textColor_inactive" />
|
||||
<item android:state_pressed="true" android:color="@color/fxaccount_input_textColor_pressed" />
|
||||
<item android:color="@color/fxaccount_input_textColor" />
|
||||
</selector>
|
@ -87,31 +87,23 @@
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/bookmarks_checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
style="@style/FxAccountCheckBox"
|
||||
android:text="@string/fxaccount_status_bookmarks" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/history_checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
style="@style/FxAccountCheckBox"
|
||||
android:text="@string/fxaccount_status_history" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/passwords_checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/fxaccount_status_passwords" />
|
||||
android:id="@+id/tabs_checkbox"
|
||||
style="@style/FxAccountCheckBox"
|
||||
android:text="@string/fxaccount_status_tabs" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/tabs_checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:text="@string/fxaccount_status_tabs" />
|
||||
android:id="@+id/passwords_checkbox"
|
||||
style="@style/FxAccountCheckBox"
|
||||
android:text="@string/fxaccount_status_passwords" />
|
||||
|
||||
<TextView
|
||||
style="@style/FxAccountHeaderItem"
|
||||
@ -135,4 +127,4 @@
|
||||
</TextView>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
|
@ -20,6 +20,8 @@
|
||||
<color name="fxaccount_button_background_loading">#424f59</color>
|
||||
<color name="fxaccount_button_background_inactive">#c0c9d0</color>
|
||||
<color name="fxaccount_input_textColor">#424f59</color>
|
||||
<color name="fxaccount_input_textColor_pressed">#424f59</color>
|
||||
<color name="fxaccount_input_textColor_inactive">#c0c9d0</color>
|
||||
<color name="fxaccount_input_textColorHint">#c0c9d0</color>
|
||||
<color name="fxaccount_link_textColor">#0096dd</color>
|
||||
<color name="fxaccount_link_textColor_pressed">#00767d</color>
|
||||
|
@ -120,4 +120,11 @@
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
</style>
|
||||
|
||||
<style name="FxAccountCheckBox">
|
||||
<item name="android:layout_width">fill_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginBottom">10dp</item>
|
||||
<item name="android:textColor">@drawable/fxaccount_checkbox_textcolor</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -65,6 +65,7 @@ public class SelectEnginesActivity extends Activity implements
|
||||
protected Account account;
|
||||
protected SharedPreferences accountPrefs;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mContext = getApplicationContext();
|
||||
@ -123,7 +124,7 @@ public class SelectEnginesActivity extends Activity implements
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private Set<String> getEnginesFromPrefs(SharedPreferences syncPrefs) {
|
||||
private static Set<String> getEnginesFromPrefs(SharedPreferences syncPrefs) {
|
||||
Set<String> engines = SyncConfiguration.getEnabledEngineNames(syncPrefs);
|
||||
if (engines == null) {
|
||||
engines = SyncConfiguration.validEngineNames();
|
||||
@ -142,7 +143,7 @@ public class SelectEnginesActivity extends Activity implements
|
||||
* @return Set<String> of engine names to display as selected. Should never be
|
||||
* null.
|
||||
*/
|
||||
private Set<String> getEnginesToSelect(SharedPreferences syncPrefs) {
|
||||
public static Set<String> getEnginesToSelect(SharedPreferences syncPrefs) {
|
||||
Set<String> engines = getEnginesFromPrefs(syncPrefs);
|
||||
Map<String, Boolean> engineSelections = SyncConfiguration.getUserSelectedEngines(syncPrefs);
|
||||
if (engineSelections != null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user