Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | package org.mozilla.gecko.fxa.activities; |
michael@0 | 6 | |
michael@0 | 7 | import java.util.concurrent.Executor; |
michael@0 | 8 | import java.util.concurrent.Executors; |
michael@0 | 9 | |
michael@0 | 10 | import org.mozilla.gecko.R; |
michael@0 | 11 | import org.mozilla.gecko.background.common.log.Logger; |
michael@0 | 12 | import org.mozilla.gecko.background.fxa.FxAccountClient; |
michael@0 | 13 | import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate; |
michael@0 | 14 | import org.mozilla.gecko.background.fxa.FxAccountClient20; |
michael@0 | 15 | import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException; |
michael@0 | 16 | import org.mozilla.gecko.fxa.FirefoxAccounts; |
michael@0 | 17 | import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount; |
michael@0 | 18 | import org.mozilla.gecko.fxa.login.Engaged; |
michael@0 | 19 | import org.mozilla.gecko.fxa.login.State; |
michael@0 | 20 | import org.mozilla.gecko.fxa.login.State.Action; |
michael@0 | 21 | import org.mozilla.gecko.fxa.sync.FxAccountSyncStatusHelper; |
michael@0 | 22 | import org.mozilla.gecko.sync.setup.activities.ActivityUtils; |
michael@0 | 23 | |
michael@0 | 24 | import android.accounts.Account; |
michael@0 | 25 | import android.app.Activity; |
michael@0 | 26 | import android.content.Context; |
michael@0 | 27 | import android.os.Bundle; |
michael@0 | 28 | import android.view.View; |
michael@0 | 29 | import android.view.View.OnClickListener; |
michael@0 | 30 | import android.widget.TextView; |
michael@0 | 31 | import android.widget.Toast; |
michael@0 | 32 | |
michael@0 | 33 | /** |
michael@0 | 34 | * Activity which displays account created successfully screen to the user, and |
michael@0 | 35 | * starts them on the email verification path. |
michael@0 | 36 | */ |
michael@0 | 37 | public class FxAccountConfirmAccountActivity extends FxAccountAbstractActivity implements OnClickListener { |
michael@0 | 38 | private static final String LOG_TAG = FxAccountConfirmAccountActivity.class.getSimpleName(); |
michael@0 | 39 | |
michael@0 | 40 | // Set in onCreate. |
michael@0 | 41 | protected TextView verificationLinkTextView; |
michael@0 | 42 | protected View resendLink; |
michael@0 | 43 | |
michael@0 | 44 | // Set in onResume. |
michael@0 | 45 | protected AndroidFxAccount fxAccount; |
michael@0 | 46 | |
michael@0 | 47 | protected final InnerSyncStatusDelegate syncStatusDelegate = new InnerSyncStatusDelegate(); |
michael@0 | 48 | |
michael@0 | 49 | public FxAccountConfirmAccountActivity() { |
michael@0 | 50 | super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST); |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | /** |
michael@0 | 54 | * {@inheritDoc} |
michael@0 | 55 | */ |
michael@0 | 56 | @Override |
michael@0 | 57 | public void onCreate(Bundle icicle) { |
michael@0 | 58 | Logger.debug(LOG_TAG, "onCreate(" + icicle + ")"); |
michael@0 | 59 | |
michael@0 | 60 | super.onCreate(icicle); |
michael@0 | 61 | setContentView(R.layout.fxaccount_confirm_account); |
michael@0 | 62 | |
michael@0 | 63 | verificationLinkTextView = (TextView) ensureFindViewById(null, R.id.verification_link_text, "verification link text"); |
michael@0 | 64 | resendLink = ensureFindViewById(null, R.id.resend_confirmation_email_link, "resend confirmation email link"); |
michael@0 | 65 | resendLink.setOnClickListener(this); |
michael@0 | 66 | |
michael@0 | 67 | View backToBrowsingButton = ensureFindViewById(null, R.id.button, "back to browsing button"); |
michael@0 | 68 | backToBrowsingButton.setOnClickListener(new OnClickListener() { |
michael@0 | 69 | @Override |
michael@0 | 70 | public void onClick(View v) { |
michael@0 | 71 | ActivityUtils.openURLInFennec(v.getContext(), null); |
michael@0 | 72 | setResult(Activity.RESULT_OK); |
michael@0 | 73 | finish(); |
michael@0 | 74 | } |
michael@0 | 75 | }); |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | @Override |
michael@0 | 79 | public void onResume() { |
michael@0 | 80 | super.onResume(); |
michael@0 | 81 | this.fxAccount = getAndroidFxAccount(); |
michael@0 | 82 | if (fxAccount == null) { |
michael@0 | 83 | Logger.warn(LOG_TAG, "Could not get Firefox Account."); |
michael@0 | 84 | setResult(RESULT_CANCELED); |
michael@0 | 85 | finish(); |
michael@0 | 86 | return; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | FxAccountSyncStatusHelper.getInstance().startObserving(syncStatusDelegate); |
michael@0 | 90 | |
michael@0 | 91 | refresh(); |
michael@0 | 92 | |
michael@0 | 93 | fxAccount.requestSync(FirefoxAccounts.NOW); |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | @Override |
michael@0 | 97 | public void onPause() { |
michael@0 | 98 | super.onPause(); |
michael@0 | 99 | FxAccountSyncStatusHelper.getInstance().stopObserving(syncStatusDelegate); |
michael@0 | 100 | |
michael@0 | 101 | if (fxAccount != null) { |
michael@0 | 102 | fxAccount.requestSync(FirefoxAccounts.SOON); |
michael@0 | 103 | } |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | protected class InnerSyncStatusDelegate implements FirefoxAccounts.SyncStatusListener { |
michael@0 | 107 | protected final Runnable refreshRunnable = new Runnable() { |
michael@0 | 108 | @Override |
michael@0 | 109 | public void run() { |
michael@0 | 110 | refresh(); |
michael@0 | 111 | } |
michael@0 | 112 | }; |
michael@0 | 113 | |
michael@0 | 114 | @Override |
michael@0 | 115 | public Context getContext() { |
michael@0 | 116 | return FxAccountConfirmAccountActivity.this; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | @Override |
michael@0 | 120 | public Account getAccount() { |
michael@0 | 121 | return fxAccount.getAndroidAccount(); |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | @Override |
michael@0 | 125 | public void onSyncStarted() { |
michael@0 | 126 | Logger.info(LOG_TAG, "Got sync started message; ignoring."); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | @Override |
michael@0 | 130 | public void onSyncFinished() { |
michael@0 | 131 | if (fxAccount == null) { |
michael@0 | 132 | return; |
michael@0 | 133 | } |
michael@0 | 134 | Logger.info(LOG_TAG, "Got sync finished message; refreshing."); |
michael@0 | 135 | runOnUiThread(refreshRunnable); |
michael@0 | 136 | } |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | protected void refresh() { |
michael@0 | 140 | final State state = fxAccount.getState(); |
michael@0 | 141 | final Action neededAction = state.getNeededAction(); |
michael@0 | 142 | switch (neededAction) { |
michael@0 | 143 | case NeedsVerification: |
michael@0 | 144 | // This is what we're here to handle. |
michael@0 | 145 | break; |
michael@0 | 146 | case NeedsPassword: |
michael@0 | 147 | case NeedsUpgrade: |
michael@0 | 148 | case None: |
michael@0 | 149 | default: |
michael@0 | 150 | // We're not in the right place! Redirect to status. |
michael@0 | 151 | Logger.warn(LOG_TAG, "No need to verifiy Firefox Account that needs action " + neededAction.toString() + |
michael@0 | 152 | " (in state " + state.getStateLabel() + ")."); |
michael@0 | 153 | setResult(RESULT_CANCELED); |
michael@0 | 154 | this.redirectToActivity(FxAccountStatusActivity.class); |
michael@0 | 155 | return; |
michael@0 | 156 | } |
michael@0 | 157 | |
michael@0 | 158 | final String email = fxAccount.getEmail(); |
michael@0 | 159 | final String text = getResources().getString(R.string.fxaccount_confirm_account_verification_link, email); |
michael@0 | 160 | verificationLinkTextView.setText(text); |
michael@0 | 161 | |
michael@0 | 162 | boolean resendLinkShouldBeEnabled = ((Engaged) state).getSessionToken() != null; |
michael@0 | 163 | resendLink.setEnabled(resendLinkShouldBeEnabled); |
michael@0 | 164 | resendLink.setClickable(resendLinkShouldBeEnabled); |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | public static class FxAccountResendCodeTask extends FxAccountSetupTask<Void> { |
michael@0 | 168 | protected static final String LOG_TAG = FxAccountResendCodeTask.class.getSimpleName(); |
michael@0 | 169 | |
michael@0 | 170 | protected final byte[] sessionToken; |
michael@0 | 171 | |
michael@0 | 172 | public FxAccountResendCodeTask(Context context, byte[] sessionToken, FxAccountClient client, RequestDelegate<Void> delegate) { |
michael@0 | 173 | super(context, null, client, delegate); |
michael@0 | 174 | this.sessionToken = sessionToken; |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | @Override |
michael@0 | 178 | protected InnerRequestDelegate<Void> doInBackground(Void... arg0) { |
michael@0 | 179 | try { |
michael@0 | 180 | client.resendCode(sessionToken, innerDelegate); |
michael@0 | 181 | latch.await(); |
michael@0 | 182 | return innerDelegate; |
michael@0 | 183 | } catch (Exception e) { |
michael@0 | 184 | Logger.error(LOG_TAG, "Got exception signing in.", e); |
michael@0 | 185 | delegate.handleError(e); |
michael@0 | 186 | } |
michael@0 | 187 | return null; |
michael@0 | 188 | } |
michael@0 | 189 | } |
michael@0 | 190 | |
michael@0 | 191 | protected static class ResendCodeDelegate implements RequestDelegate<Void> { |
michael@0 | 192 | public final Context context; |
michael@0 | 193 | |
michael@0 | 194 | public ResendCodeDelegate(Context context) { |
michael@0 | 195 | this.context = context; |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | @Override |
michael@0 | 199 | public void handleError(Exception e) { |
michael@0 | 200 | Logger.warn(LOG_TAG, "Got exception requesting fresh confirmation link; ignoring.", e); |
michael@0 | 201 | Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_not_sent, Toast.LENGTH_LONG).show(); |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | @Override |
michael@0 | 205 | public void handleFailure(FxAccountClientRemoteException e) { |
michael@0 | 206 | handleError(e); |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | @Override |
michael@0 | 210 | public void handleSuccess(Void result) { |
michael@0 | 211 | Toast.makeText(context, R.string.fxaccount_confirm_account_verification_link_sent, Toast.LENGTH_SHORT).show(); |
michael@0 | 212 | } |
michael@0 | 213 | } |
michael@0 | 214 | |
michael@0 | 215 | public static void resendCode(Context context, AndroidFxAccount fxAccount) { |
michael@0 | 216 | RequestDelegate<Void> delegate = new ResendCodeDelegate(context); |
michael@0 | 217 | |
michael@0 | 218 | byte[] sessionToken; |
michael@0 | 219 | try { |
michael@0 | 220 | sessionToken = ((Engaged) fxAccount.getState()).getSessionToken(); |
michael@0 | 221 | } catch (Exception e) { |
michael@0 | 222 | delegate.handleError(e); |
michael@0 | 223 | return; |
michael@0 | 224 | } |
michael@0 | 225 | if (sessionToken == null) { |
michael@0 | 226 | delegate.handleError(new IllegalStateException("sessionToken should not be null")); |
michael@0 | 227 | return; |
michael@0 | 228 | } |
michael@0 | 229 | |
michael@0 | 230 | Executor executor = Executors.newSingleThreadExecutor(); |
michael@0 | 231 | FxAccountClient client = new FxAccountClient20(fxAccount.getAccountServerURI(), executor); |
michael@0 | 232 | new FxAccountResendCodeTask(context, sessionToken, client, delegate).execute(); |
michael@0 | 233 | } |
michael@0 | 234 | |
michael@0 | 235 | @Override |
michael@0 | 236 | public void onClick(View v) { |
michael@0 | 237 | resendCode(this, fxAccount); |
michael@0 | 238 | } |
michael@0 | 239 | } |