From baab4090720deaae0994f4028316d08f5c8839f5 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Tue, 28 Aug 2018 09:05:22 +0200 Subject: [PATCH 01/13] Fix google sign-up --- .../android/ui/accounts/LoginActivity.java | 36 ++++++++++++---- .../android/login/GoogleFragment.java | 37 +++++++++------- .../android/login/LoginGoogleFragment.java | 42 +++++++++++-------- .../android/login/SignupGoogleFragment.java | 38 +++++++++-------- 4 files changed, 93 insertions(+), 60 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java index 6defddcab3ef..b3e13f0789d7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java @@ -19,6 +19,7 @@ import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; +import org.jetbrains.annotations.NotNull; import org.wordpress.android.R; import org.wordpress.android.WordPress; import org.wordpress.android.analytics.AnalyticsTracker; @@ -51,6 +52,8 @@ import org.wordpress.android.ui.accounts.login.LoginPrologueFragment; import org.wordpress.android.ui.accounts.login.LoginPrologueListener; import org.wordpress.android.ui.notifications.services.NotificationsUpdateServiceStarter; +import org.wordpress.android.ui.posts.BasicFragmentDialog; +import org.wordpress.android.ui.posts.BasicFragmentDialog.BasicDialogPositiveClickInterface; import org.wordpress.android.ui.reader.services.update.ReaderUpdateLogic; import org.wordpress.android.ui.reader.services.update.ReaderUpdateServiceStarter; import org.wordpress.android.util.AppLog; @@ -76,7 +79,7 @@ public class LoginActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener, Callback, LoginListener, GoogleListener, LoginPrologueListener, SignupSheetListener, - HasSupportFragmentInjector { + HasSupportFragmentInjector, BasicDialogPositiveClickInterface { public static final String ARG_JETPACK_CONNECT_SOURCE = "ARG_JETPACK_CONNECT_SOURCE"; public static final String MAGIC_LOGIN = "magic-login"; public static final String TOKEN_PARAMETER = "token"; @@ -86,6 +89,8 @@ public class LoginActivity extends AppCompatActivity implements ConnectionCallba private static final String FORGOT_PASSWORD_URL_SUFFIX = "wp-login.php?action=lostpassword"; + private static final String GOOGLE_ERROR_DIALOG_TAG = "google_error_dialog_tag"; + private enum SmartLockHelperState { NOT_TRIGGERED, TRIGGER_FILL_IN_ON_CONNECT, @@ -158,14 +163,6 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onSaveInstanceState(Bundle outState) { - SignupGoogleFragment signupGoogleFragment; - FragmentManager fragmentManager = getSupportFragmentManager(); - signupGoogleFragment = (SignupGoogleFragment) fragmentManager.findFragmentByTag(SignupGoogleFragment.TAG); - - if (signupGoogleFragment != null) { - fragmentManager.beginTransaction().remove(signupGoogleFragment).commit(); - } - super.onSaveInstanceState(outState); outState.putBoolean(KEY_SIGNUP_SHEET_DISPLAYED, mSignupSheetDisplayed); @@ -364,6 +361,7 @@ public void onSignupSheetEmailClicked() { @Override public void onSignupSheetGoogleClicked() { + dismissSignupSheet(); AnalyticsTracker.track(AnalyticsTracker.Stat.CREATE_ACCOUNT_INITIATED); AnalyticsTracker.track(AnalyticsTracker.Stat.SIGNUP_GOOGLE_BUTTON_TAPPED); @@ -375,6 +373,8 @@ public void onSignupSheetGoogleClicked() { if (signupGoogleFragment != null) { fragmentTransaction.remove(signupGoogleFragment); + // REMOVE THIS BLOCK - just for testing purposes + throw new RuntimeException("fail"); } signupGoogleFragment = new SignupGoogleFragment(); @@ -761,6 +761,24 @@ public void onGoogleSignupFinished(String name, String email, String photoUrl, S finish(); } + @Override public void onGoogleSignupError(String msg) { + BasicFragmentDialog dialog = new BasicFragmentDialog(); + dialog.initialize(GOOGLE_ERROR_DIALOG_TAG, getString(R.string.error), + msg, + getString(org.wordpress.android.login.R.string.login_error_button), + null, + null); + dialog.show(this.getSupportFragmentManager(), GOOGLE_ERROR_DIALOG_TAG); + } + + @Override public void onPositiveClicked(@NotNull String instanceTag) { + switch (instanceTag) { + case GOOGLE_ERROR_DIALOG_TAG: + // just dismiss the dialog + break; + } + } + private void dismissSignupSheet() { if (mSignupSheet != null) { mSignupSheet.dismiss(); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java index 744a73c079b7..aa057b456576 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java @@ -6,9 +6,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; -import android.support.v7.app.AlertDialog; import android.util.Log; -import android.view.ContextThemeWrapper; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; @@ -52,6 +50,7 @@ public interface GoogleListener { void onGoogleEmailSelected(String email); void onGoogleLoginFinished(); void onGoogleSignupFinished(String name, String email, String photoUrl, String username); + void onGoogleSignupError(String msg); } @Override @@ -71,7 +70,7 @@ public void onCreate(Bundle savedInstanceState) { .build(); // Build Google API client with access to sign-in API and options specified above. - mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) + mGoogleApiClient = new GoogleApiClient.Builder(getActivity().getApplicationContext()) .addApi(Auth.GOOGLE_SIGN_IN_API, googleSignInOptions) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) @@ -83,7 +82,7 @@ public void onCreate(Bundle savedInstanceState) { } @Override - public void onSaveInstanceState(Bundle outState) { + public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_RESOLVING_ERROR, mIsResolvingError); } @@ -98,11 +97,6 @@ public void onAttach(Context context) { } catch (ClassCastException exception) { throw new ClassCastException(context.toString() + " must implement GoogleListener"); } - - // Show account dialog when Google API onConnected callback returns before fragment is attached. - if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && !mIsResolvingError && !mShouldResolveError) { - showAccountDialog(); - } } @Override @@ -111,6 +105,14 @@ public void onDetach() { disconnectGoogleClient(); } + @Override public void onResume() { + super.onResume(); + // Show account dialog when Google API onConnected callback returns before fragment is attached. + if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && !mIsResolvingError && !mShouldResolveError) { + showAccountDialog(); + } + } + @Override public void onStart() { super.onStart(); @@ -154,7 +156,7 @@ public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { mIsResolvingError = false; AppLog.e(AppLog.T.NUX, GoogleApiAvailability.getInstance().getErrorString( connectionResult.getErrorCode())); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); } } } @@ -187,12 +189,15 @@ protected void showAccountDialog() { // Do nothing here. This should be overridden by inheriting class. } - protected void showErrorDialog(String message) { - AlertDialog dialog = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.LoginTheme)) - .setMessage(message) - .setPositiveButton(R.string.login_error_button, null) - .create(); - dialog.show(); + protected void finishSignUp() { + if (getActivity() != null) { + getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); + } + } + + protected void showError(String message) { + finishSignUp(); + mGoogleListener.onGoogleSignupError(message); } @Override diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index 6259b0955b0c..efe58a0bb20d 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -25,6 +25,7 @@ public class LoginGoogleFragment extends GoogleFragment { private static final int REQUEST_LOGIN = 1001; + private boolean mLoginRequested = false; public static final String TAG = "login_google_fragment_tag"; @@ -40,6 +41,7 @@ public void onActivityResult(int request, int result, Intent data) { switch (request) { case REQUEST_LOGIN: + mLoginRequested = false; if (result == RESULT_OK) { GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); @@ -58,7 +60,7 @@ public void onActivityResult(int request, int result, Intent data) { } catch (NullPointerException exception) { disconnectGoogleClient(); AppLog.e(T.NUX, "Cannot get ID token from Google login account.", exception); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); } } else { mAnalyticsListener.trackSocialButtonFailure(); @@ -66,18 +68,18 @@ public void onActivityResult(int request, int result, Intent data) { // Internal error. case GoogleSignInStatusCodes.INTERNAL_ERROR: AppLog.e(T.NUX, "Google Login Failed: internal error."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Attempted to connect with an invalid account name specified. case GoogleSignInStatusCodes.INVALID_ACCOUNT: AppLog.e(T.NUX, "Google Login Failed: invalid account name."); - showErrorDialog(getString(R.string.login_error_generic) - + getString(R.string.login_error_suffix)); + showError(getString(R.string.login_error_generic) + + getString(R.string.login_error_suffix)); break; // Network error. case GoogleSignInStatusCodes.NETWORK_ERROR: AppLog.e(T.NUX, "Google Login Failed: network error."); - showErrorDialog(getString(R.string.error_generic_network)); + showError(getString(R.string.error_generic_network)); break; // Cancelled by the user. case GoogleSignInStatusCodes.SIGN_IN_CANCELLED: @@ -86,32 +88,33 @@ public void onActivityResult(int request, int result, Intent data) { // Attempt didn't succeed with the current account. case GoogleSignInStatusCodes.SIGN_IN_FAILED: AppLog.e(T.NUX, "Google Login Failed: current account failed."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Attempted to connect, but the user is not signed in. case GoogleSignInStatusCodes.SIGN_IN_REQUIRED: AppLog.e(T.NUX, "Google Login Failed: user is not signed in."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Timeout error. case GoogleSignInStatusCodes.TIMEOUT: AppLog.e(T.NUX, "Google Login Failed: timeout error."); - showErrorDialog(getString(R.string.google_error_timeout)); + showError(getString(R.string.google_error_timeout)); break; // Unknown error. default: AppLog.e(T.NUX, "Google Login Failed: unknown error."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; } } } else if (result == RESULT_CANCELED) { mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was CANCELED."); + finishSignUp(); } else { mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was not OK or CANCELED."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); } break; @@ -120,8 +123,11 @@ public void onActivityResult(int request, int result, Intent data) { @Override protected void showAccountDialog() { - Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); - startActivityForResult(signInIntent, REQUEST_LOGIN); + if (!mLoginRequested) { + mLoginRequested = true; + Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(signInIntent, REQUEST_LOGIN); + } } @SuppressWarnings("unused") @@ -131,14 +137,14 @@ public void onAuthenticationChanged(OnAuthenticationChanged event) { if (event.isError()) { AppLog.e(T.API, "LoginGoogleFragment.onAuthenticationChanged: " + event.error.type - + " - " + event.error.message); + + " - " + event.error.message); mAnalyticsListener.trackLoginFailed(event.getClass().getSimpleName(), event.error.type.toString(), event.error.message); mAnalyticsListener.trackSocialFailure(event.getClass().getSimpleName(), event.error.type.toString(), event.error.message); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); } else { AppLog.i(T.NUX, "LoginGoogleFragment.onAuthenticationChanged: " + event.toString()); mGoogleListener.onGoogleLoginFinished(); @@ -171,16 +177,16 @@ public void onSocialChanged(OnSocialChanged event) { // WordPress account does not exist with input email address. case UNKNOWN_USER: mAnalyticsListener.trackSocialErrorUnknownUser(); - showErrorDialog(getString(R.string.login_error_email_not_found, mGoogleEmail)); + showError(getString(R.string.login_error_email_not_found, mGoogleEmail)); break; // Unknown error. case GENERIC_ERROR: - // Do nothing for now (included to show all error types) and just fall through to 'default' + // Do nothing for now (included to show all error types) and just fall through to 'default' default: - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; } - // Response does not return error when two-factor authentication is required. + // Response does not return error when two-factor authentication is required. } else if (event.requiresTwoStepAuth) { mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index e0173acf0be6..c181c3090761 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -31,6 +31,7 @@ public class SignupGoogleFragment extends GoogleFragment { private ArrayList mOldSitesIds; private ProgressDialog mProgressDialog; + private boolean mSignupRequested; private static final int REQUEST_SIGNUP = 1002; @@ -56,6 +57,7 @@ public void onActivityResult(int request, int result, Intent data) { switch (request) { case REQUEST_SIGNUP: + mSignupRequested = false; if (result == RESULT_OK) { GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); @@ -77,7 +79,7 @@ public void onActivityResult(int request, int result, Intent data) { } catch (NullPointerException exception) { disconnectGoogleClient(); AppLog.e(T.NUX, "Cannot get ID token from Google signup account.", exception); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); } } else { mAnalyticsListener.trackSignupSocialButtonFailure(); @@ -85,18 +87,18 @@ public void onActivityResult(int request, int result, Intent data) { // Internal error. case GoogleSignInStatusCodes.INTERNAL_ERROR: AppLog.e(T.NUX, "Google Signup Failed: internal error."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Attempted to connect with an invalid account name specified. case GoogleSignInStatusCodes.INVALID_ACCOUNT: AppLog.e(T.NUX, "Google Signup Failed: invalid account name."); - showErrorDialog(getString(R.string.login_error_generic) - + getString(R.string.login_error_suffix)); + showError(getString(R.string.login_error_generic) + + getString(R.string.login_error_suffix)); break; // Network error. case GoogleSignInStatusCodes.NETWORK_ERROR: AppLog.e(T.NUX, "Google Signup Failed: network error."); - showErrorDialog(getString(R.string.error_generic_network)); + showError(getString(R.string.error_generic_network)); break; // Cancelled by the user. case GoogleSignInStatusCodes.SIGN_IN_CANCELLED: @@ -105,34 +107,33 @@ public void onActivityResult(int request, int result, Intent data) { // Attempt didn't succeed with the current account. case GoogleSignInStatusCodes.SIGN_IN_FAILED: AppLog.e(T.NUX, "Google Signup Failed: current account failed."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Attempted to connect, but the user is not signed in. case GoogleSignInStatusCodes.SIGN_IN_REQUIRED: AppLog.e(T.NUX, "Google Signup Failed: user is not signed in."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; // Timeout error. case GoogleSignInStatusCodes.TIMEOUT: AppLog.e(T.NUX, "Google Signup Failed: timeout error."); - showErrorDialog(getString(R.string.google_error_timeout)); + showError(getString(R.string.google_error_timeout)); break; // Unknown error. default: AppLog.e(T.NUX, "Google Signup Failed: unknown error."); - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; } } } else if (result == RESULT_CANCELED) { mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was CANCELED."); - dismissProgressDialog(); + finishSignUp(); } else { mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was not OK or CANCELED."); - showErrorDialog(getString(R.string.login_error_generic)); - dismissProgressDialog(); + showError(getString(R.string.login_error_generic)); } break; @@ -147,8 +148,11 @@ private void dismissProgressDialog() { @Override protected void showAccountDialog() { - Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); - startActivityForResult(signInIntent, REQUEST_SIGNUP); + if (!mSignupRequested) { + mSignupRequested = true; + Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(signInIntent, REQUEST_SIGNUP); + } } // Remove scale from photo URL path string. Current URL matches /s96-c, which returns a 96 x 96 @@ -200,10 +204,10 @@ public void onSocialChanged(OnSocialChanged event) { mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); // Kill connections with FluxC and this fragment since the flow is changing to login. mDispatcher.unregister(this); - getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); + finishSignUp(); break; default: - showErrorDialog(getString(R.string.login_error_generic)); + showError(getString(R.string.login_error_generic)); break; } // Response does not return error when two-factor authentication is required. @@ -213,7 +217,7 @@ public void onSocialChanged(OnSocialChanged event) { event.nonceSms); // Kill connections with FluxC and this fragment since the flow is changing to login. mDispatcher.unregister(this); - getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); + finishSignUp(); } } } From db9fc44fc8871e9418f27cbb2858e3861011d454 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Tue, 28 Aug 2018 12:14:02 +0200 Subject: [PATCH 02/13] Fix signup/in flows --- .../android/login/GoogleFragment.java | 66 +++++++++------ .../android/login/LoginGoogleFragment.java | 43 ++++++---- .../android/login/SignupGoogleFragment.java | 82 ++++++++++++++----- 3 files changed, 134 insertions(+), 57 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java index aa057b456576..f4462d3abe15 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java @@ -19,14 +19,22 @@ import org.wordpress.android.fluxc.Dispatcher; import org.wordpress.android.fluxc.store.SiteStore; import org.wordpress.android.util.AppLog; +import org.wordpress.android.util.AppLog.T; import javax.inject.Inject; import static android.app.Activity.RESULT_OK; public class GoogleFragment extends Fragment implements ConnectionCallbacks, OnConnectionFailedListener { + private static final String STATE_SHOULD_RESOLVE_ERROR = "STATE_SHOULD_RESOLVE_ERROR"; + private static final String STATE_FINISHED = "STATE_FINISHED"; + private static final String STATE_DISPLAY_NAME = "STATE_DISPLAY_NAME"; + private static final String STATE_GOOGLE_EMAIL = "STATE_GOOGLE_EMAIL"; + private static final String STATE_GOOGLE_TOKEN_ID = "STATE_GOOGLE_TOKEN_ID"; + private static final String STATE_GOOGLE_PHOTO_URL = "STATE_GOOGLE_PHOTO_URL"; private boolean mIsResolvingError; private boolean mShouldResolveError; + private boolean mFinished; private static final String STATE_RESOLVING_ERROR = "STATE_RESOLVING_ERROR"; private static final int REQUEST_CONNECT = 1000; @@ -56,9 +64,16 @@ public interface GoogleListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - // Restore state of error resolving. - mIsResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); + mDispatcher.register(this); + if (savedInstanceState != null) { + mIsResolvingError = savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); + mShouldResolveError = savedInstanceState.getBoolean(STATE_SHOULD_RESOLVE_ERROR, false); + mFinished = savedInstanceState.getBoolean(STATE_FINISHED, false); + mDisplayName = savedInstanceState.getString(STATE_DISPLAY_NAME); + mGoogleEmail = savedInstanceState.getString(STATE_GOOGLE_EMAIL); + mIdToken = savedInstanceState.getString(STATE_GOOGLE_TOKEN_ID); + mPhotoUrl = savedInstanceState.getString(STATE_GOOGLE_PHOTO_URL); + } // Configure sign-in to request user's ID, basic profile, email address, and ID token. // ID and basic profile are included in DEFAULT_SIGN_IN. @@ -85,6 +100,12 @@ public void onCreate(Bundle savedInstanceState) { public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_RESOLVING_ERROR, mIsResolvingError); + outState.putBoolean(STATE_SHOULD_RESOLVE_ERROR, mShouldResolveError); + outState.putBoolean(STATE_FINISHED, mFinished); + outState.putString(STATE_DISPLAY_NAME, mDisplayName); + outState.putString(STATE_GOOGLE_EMAIL, mGoogleEmail); + outState.putString(STATE_GOOGLE_TOKEN_ID, mIdToken); + outState.putString(STATE_GOOGLE_PHOTO_URL, mPhotoUrl); } @Override @@ -97,34 +118,26 @@ public void onAttach(Context context) { } catch (ClassCastException exception) { throw new ClassCastException(context.toString() + " must implement GoogleListener"); } + if (mFinished) { + finishSignUp(); + } } - @Override - public void onDetach() { - super.onDetach(); + @Override public void onDestroy() { disconnectGoogleClient(); + AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: disconnecting google client"); + mDispatcher.unregister(this); + super.onDestroy(); } @Override public void onResume() { super.onResume(); // Show account dialog when Google API onConnected callback returns before fragment is attached. if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && !mIsResolvingError && !mShouldResolveError) { - showAccountDialog(); + startSignInProcess(); } } - @Override - public void onStart() { - super.onStart(); - mDispatcher.register(this); - } - - @Override - public void onStop() { - super.onStop(); - mDispatcher.unregister(this); - } - @Override public void onConnected(Bundle bundle) { // Indicates account was selected, that account has granted any required permissions, and a @@ -132,8 +145,11 @@ public void onConnected(Bundle bundle) { if (mShouldResolveError) { mShouldResolveError = false; + //noinspection StatementWithEmptyBody if (isAdded()) { - showAccountDialog(); + startSignInProcess(); + } else { + // handled in onResume } } } @@ -174,7 +190,7 @@ public void connectGoogleClient() { mShouldResolveError = true; mGoogleApiClient.connect(); } else { - showAccountDialog(); + startSignInProcess(); } } @@ -185,13 +201,17 @@ protected void disconnectGoogleClient() { } } - protected void showAccountDialog() { + protected void startSignInProcess() { // Do nothing here. This should be overridden by inheriting class. } protected void finishSignUp() { if (getActivity() != null) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: finishing signup"); getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); + } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: mFinished set to true"); + mFinished = true; } } @@ -213,7 +233,7 @@ public void onActivityResult(int request, int result, Intent data) { if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } else { - showAccountDialog(); + startSignInProcess(); } mIsResolvingError = false; diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index efe58a0bb20d..b546e763b9d4 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -35,12 +35,26 @@ public void onAttach(Context context) { super.onAttach(context); } + @Override + protected void startSignInProcess() { + if (!mLoginRequested) { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: startSignInProgress"); + mLoginRequested = true; + Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(signInIntent, REQUEST_LOGIN); + } else { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: startSignInProgress called, but is already in progress"); + } + } + @Override public void onActivityResult(int request, int result, Intent data) { super.onActivityResult(request, result, data); switch (request) { case REQUEST_LOGIN: + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - succcess"); + disconnectGoogleClient(); mLoginRequested = false; if (result == RESULT_OK) { GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); @@ -55,14 +69,17 @@ public void onActivityResult(int request, int result, Intent data) { mIdToken = account.getIdToken() != null ? account.getIdToken() : ""; } + AppLog.d(T.MAIN, + "GOOGLE SIGNIN: Google has returned a sign in result - dispatching SocialLoginAction"); PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); } catch (NullPointerException exception) { - disconnectGoogleClient(); + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - NPE"); AppLog.e(T.NUX, "Cannot get ID token from Google login account.", exception); showError(getString(R.string.login_error_generic)); } } else { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - error"); mAnalyticsListener.trackSocialButtonFailure(); switch (signInResult.getStatus().getStatusCode()) { // Internal error. @@ -108,10 +125,12 @@ public void onActivityResult(int request, int result, Intent data) { } } } else if (result == RESULT_CANCELED) { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - canceled"); mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was CANCELED."); finishSignUp(); } else { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - unknown"); mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was not OK or CANCELED."); showError(getString(R.string.login_error_generic)); @@ -121,21 +140,11 @@ public void onActivityResult(int request, int result, Intent data) { } } - @Override - protected void showAccountDialog() { - if (!mLoginRequested) { - mLoginRequested = true; - Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); - startActivityForResult(signInIntent, REQUEST_LOGIN); - } - } - @SuppressWarnings("unused") @Subscribe(threadMode = ThreadMode.MAIN) public void onAuthenticationChanged(OnAuthenticationChanged event) { - disconnectGoogleClient(); - if (event.isError()) { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onAuthenticationChanged - error"); AppLog.e(T.API, "LoginGoogleFragment.onAuthenticationChanged: " + event.error.type + " - " + event.error.message); mAnalyticsListener.trackLoginFailed(event.getClass().getSimpleName(), @@ -146,16 +155,16 @@ public void onAuthenticationChanged(OnAuthenticationChanged event) { showError(getString(R.string.login_error_generic)); } else { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onAuthenticationChanged - success"); AppLog.i(T.NUX, "LoginGoogleFragment.onAuthenticationChanged: " + event.toString()); mGoogleListener.onGoogleLoginFinished(); + finishSignUp(); } } @SuppressWarnings("unused") @Subscribe(threadMode = ThreadMode.MAIN) public void onSocialChanged(OnSocialChanged event) { - disconnectGoogleClient(); - // Response returns error for non-existing account and existing account not connected. if (event.isError()) { AppLog.e(T.API, "LoginGoogleFragment.onSocialChanged: " + event.error.type + " - " + event.error.message); @@ -171,11 +180,13 @@ public void onSocialChanged(OnSocialChanged event) { switch (event.error.type) { // WordPress account exists with input email address, but not connected. case USER_EXISTS: + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - wordpress acount exists but not connected"); mAnalyticsListener.trackSocialAccountsNeedConnecting(); mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); break; // WordPress account does not exist with input email address. case UNKNOWN_USER: + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - wordpress acount doesn't exist"); mAnalyticsListener.trackSocialErrorUnknownUser(); showError(getString(R.string.login_error_email_not_found, mGoogleEmail)); break; @@ -183,15 +194,19 @@ public void onSocialChanged(OnSocialChanged event) { case GENERIC_ERROR: // Do nothing for now (included to show all error types) and just fall through to 'default' default: + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - unknown error"); showError(getString(R.string.login_error_generic)); break; } // Response does not return error when two-factor authentication is required. } else if (event.requiresTwoStepAuth) { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - needs 2fa"); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); } else { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - success"); mGoogleListener.onGoogleLoginFinished(); } + finishSignUp(); } } diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index c181c3090761..46990df2a90c 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -3,6 +3,8 @@ import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; @@ -29,6 +31,8 @@ import static android.app.Activity.RESULT_OK; public class SignupGoogleFragment extends GoogleFragment { + private static final String OLD_SITES_IDS = "old_sites_ids"; + private static final String SIGN_UP_REQUESTED = "sign_up_requested"; private ArrayList mOldSitesIds; private ProgressDialog mProgressDialog; private boolean mSignupRequested; @@ -45,23 +49,51 @@ public void onAttach(Context context) { super.onAttach(context); } + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null) { + mOldSitesIds = savedInstanceState.getIntegerArrayList(OLD_SITES_IDS); + mSignupRequested = savedInstanceState.getBoolean(SIGN_UP_REQUESTED); + } + } + + @Override public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putIntegerArrayList(OLD_SITES_IDS, mOldSitesIds); + outState.putBoolean(SIGN_UP_REQUESTED, mSignupRequested); + } + @Override public void onDetach() { dismissProgressDialog(); super.onDetach(); } + @Override + protected void startSignInProcess() { + if (!mSignupRequested) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: startSignInProcess"); + mSignupRequested = true; + Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(signInIntent, REQUEST_SIGNUP); + } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: startSignInProcess called, but is already in progress"); + } + } + @Override public void onActivityResult(int request, int result, Intent data) { super.onActivityResult(request, result, data); switch (request) { case REQUEST_SIGNUP: + disconnectGoogleClient(); mSignupRequested = false; if (result == RESULT_OK) { GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (signInResult.isSuccess()) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - succcess"); try { GoogleSignInAccount account = signInResult.getSignInAccount(); @@ -74,14 +106,17 @@ public void onActivityResult(int request, int result, Intent data) { } PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); + AppLog.d(T.MAIN, + "GOOGLE SIGNUP: Google has returned a sign up result - dispatching SocialSignupAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialSignupAction(payload)); mOldSitesIds = SiteUtils.getCurrentSiteIds(mSiteStore, false); } catch (NullPointerException exception) { - disconnectGoogleClient(); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - NPE"); AppLog.e(T.NUX, "Cannot get ID token from Google signup account.", exception); showError(getString(R.string.login_error_generic)); } } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - error"); mAnalyticsListener.trackSignupSocialButtonFailure(); switch (signInResult.getStatus().getStatusCode()) { // Internal error. @@ -127,10 +162,12 @@ public void onActivityResult(int request, int result, Intent data) { } } } else if (result == RESULT_CANCELED) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - canceled"); mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was CANCELED."); finishSignUp(); } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - unknown"); mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was not OK or CANCELED."); showError(getString(R.string.login_error_generic)); @@ -146,15 +183,6 @@ private void dismissProgressDialog() { } } - @Override - protected void showAccountDialog() { - if (!mSignupRequested) { - mSignupRequested = true; - Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); - startActivityForResult(signInIntent, REQUEST_SIGNUP); - } - } - // Remove scale from photo URL path string. Current URL matches /s96-c, which returns a 96 x 96 // pixel image. Removing /s96-c from the string returns a 512 x 512 pixel image. Using regular // expressions may help if the photo URL scale value in the returned path changes. @@ -168,17 +196,22 @@ private String removeScaleFromGooglePhotoUrl(String photoUrl) { @Subscribe(threadMode = ThreadMode.MAIN) public void onAuthenticationChanged(OnAuthenticationChanged event) { if (event.isError()) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onAuthenticationChanged - error"); AppLog.e(T.API, "SignupGoogleFragment.onAuthenticationChanged: " + event.error.type + " - " + event.error.message); - // Continue with signup since account was created. } else if (event.createdAccount) { + AppLog.d(T.MAIN, + "GOOGLE SIGNUP: onAuthenticationChanged - createdAccount=true -> the email is already attached to" + + " an wordpress account"); mAnalyticsListener.trackCreatedAccount(event.userName, mGoogleEmail); mGoogleListener.onGoogleSignupFinished(mDisplayName, mGoogleEmail, mPhotoUrl, event.userName); // Continue with login since existing account was selected. } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onAuthenticationChanged - new wordpress account created"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.loggedInViaSocialAccount(mOldSitesIds, true); } + finishSignUp(); } @SuppressWarnings("unused") @@ -190,34 +223,43 @@ public void onSocialChanged(OnSocialChanged event) { switch (event.error.type) { // WordPress account exists with input email address, and two-factor authentication is required. case TWO_STEP_ENABLED: + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - two step authentication"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.showSignupToLoginMessage(); // Dispatch social login action to retrieve data required for two-factor authentication. PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); + AppLog.d(T.MAIN, + "GOOGLE SIGNUP: onSocialChanged - error - two step authentication - dispatching pushSocialLoginAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); break; // WordPress account exists with input email address, but not connected. case USER_EXISTS: - mAnalyticsListener.trackSignupSocialAccountsNeedConnecting(); - mAnalyticsListener.trackSignupSocialToLogin(); - mLoginListener.showSignupToLoginMessage(); - mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); - // Kill connections with FluxC and this fragment since the flow is changing to login. - mDispatcher.unregister(this); - finishSignUp(); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - user already exists"); + handleUserExists(); break; default: + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - unknown"); showError(getString(R.string.login_error_generic)); break; } // Response does not return error when two-factor authentication is required. } else if (event.requiresTwoStepAuth) { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - 2fa required"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); - // Kill connections with FluxC and this fragment since the flow is changing to login. - mDispatcher.unregister(this); finishSignUp(); + } else { + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - shouldn't happen - google sign in success"); + handleUserExists(); } } + + private void handleUserExists() { + mAnalyticsListener.trackSignupSocialAccountsNeedConnecting(); + mAnalyticsListener.trackSignupSocialToLogin(); + mLoginListener.showSignupToLoginMessage(); + mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); + finishSignUp(); + } } From 7b1e4b2ec3d057a3894fb2490ff24cbf0bacbacc Mon Sep 17 00:00:00 2001 From: malinajirka Date: Wed, 29 Aug 2018 08:54:23 +0200 Subject: [PATCH 03/13] Fix google sign in flow --- .../android/ui/accounts/LoginActivity.java | 20 ++++--------------- .../android/login/GoogleFragment.java | 9 +++++---- .../android/login/LoginEmailFragment.java | 2 +- .../android/login/LoginGoogleFragment.java | 2 +- .../android/login/LoginListener.java | 3 +-- 5 files changed, 12 insertions(+), 24 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java index b3e13f0789d7..34b81ff6d7e4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java @@ -57,6 +57,7 @@ import org.wordpress.android.ui.reader.services.update.ReaderUpdateLogic; import org.wordpress.android.ui.reader.services.update.ReaderUpdateServiceStarter; import org.wordpress.android.util.AppLog; +import org.wordpress.android.util.AppLog.T; import org.wordpress.android.util.CrashlyticsUtils; import org.wordpress.android.util.LanguageUtils; import org.wordpress.android.util.LocaleManager; @@ -253,6 +254,7 @@ private void loggedInAndFinish(ArrayList oldSitesIds, boolean doLoginUp @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + AppLog.d(T.MAIN, "LoginActivity: onActivity Result - requestCode" + requestCode); super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { @@ -369,14 +371,6 @@ public void onSignupSheetGoogleClicked() { SignupGoogleFragment signupGoogleFragment; FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - signupGoogleFragment = (SignupGoogleFragment) fragmentManager.findFragmentByTag(SignupGoogleFragment.TAG); - - if (signupGoogleFragment != null) { - fragmentTransaction.remove(signupGoogleFragment); - // REMOVE THIS BLOCK - just for testing purposes - throw new RuntimeException("fail"); - } - signupGoogleFragment = new SignupGoogleFragment(); signupGoogleFragment.setRetainInstance(true); fragmentTransaction.add(signupGoogleFragment, SignupGoogleFragment.TAG); @@ -592,16 +586,10 @@ public void helpSocialEmailScreen(String email) { } @Override - public void addGoogleLoginFragment(@NonNull Fragment parent) { + public void addGoogleLoginFragment() { LoginGoogleFragment loginGoogleFragment; - FragmentManager fragmentManager = parent.getChildFragmentManager(); + FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - loginGoogleFragment = (LoginGoogleFragment) fragmentManager.findFragmentByTag(LoginGoogleFragment.TAG); - - if (loginGoogleFragment != null) { - fragmentTransaction.remove(loginGoogleFragment); - } - loginGoogleFragment = new LoginGoogleFragment(); loginGoogleFragment.setRetainInstance(true); fragmentTransaction.add(loginGoogleFragment, LoginGoogleFragment.TAG); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java index f4462d3abe15..b8e355470da1 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java @@ -206,12 +206,13 @@ protected void startSignInProcess() { } protected void finishSignUp() { + /* This flag might get lost when the finishSignUp is called after the fragment's + onSaveInstanceState was called - however it's a very rare case, since the fragment is retained across + config changes. */ + mFinished = true; if (getActivity() != null) { AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: finishing signup"); - getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); - } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: mFinished set to true"); - mFinished = true; + getActivity().getSupportFragmentManager().beginTransaction().remove(this).commitAllowingStateLoss(); } } diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginEmailFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginEmailFragment.java index ffc2380a89ef..1547874d00a5 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginEmailFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginEmailFragment.java @@ -149,7 +149,7 @@ public void onClick(View view) { if (isAdded()) { mOldSitesIDs = SiteUtils.getCurrentSiteIds(mSiteStore, false); mIsSocialLogin = true; - mLoginListener.addGoogleLoginFragment(LoginEmailFragment.this); + mLoginListener.addGoogleLoginFragment(); } else { AppLog.e(T.NUX, "Google login could not be started. LoginEmailFragment was not attached."); showErrorDialog(getString(R.string.login_error_generic_start)); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index b546e763b9d4..c6812cdb8f3a 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -53,10 +53,10 @@ public void onActivityResult(int request, int result, Intent data) { switch (request) { case REQUEST_LOGIN: - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - succcess"); disconnectGoogleClient(); mLoginRequested = false; if (result == RESULT_OK) { + AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - succcess"); GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (signInResult.isSuccess()) { diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginListener.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginListener.java index 17bcc96b03cd..e17875f309df 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginListener.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginListener.java @@ -3,7 +3,6 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import org.wordpress.android.fluxc.network.MemorizingTrustManager; import org.wordpress.android.fluxc.store.SiteStore; @@ -25,7 +24,7 @@ interface SelfSignedSSLCallback { void loginViaWpcomUsernameInstead(); void helpEmailScreen(String email); void helpSocialEmailScreen(String email); - void addGoogleLoginFragment(@NonNull Fragment fragment); + void addGoogleLoginFragment(); // Login Request Magic Link callbacks void showMagicLinkSentScreen(String email); From a23b2f63094fa668b990841054ff98f7697a853c Mon Sep 17 00:00:00 2001 From: vojtasmrcek Date: Wed, 29 Aug 2018 10:33:51 +0200 Subject: [PATCH 04/13] Trigger 2fa when the authentication SMS has been already sent during the flow --- .../java/org/wordpress/android/login/LoginGoogleFragment.java | 2 +- .../java/org/wordpress/android/login/SignupGoogleFragment.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index c6812cdb8f3a..d61f9ee2e144 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -199,7 +199,7 @@ public void onSocialChanged(OnSocialChanged event) { break; } // Response does not return error when two-factor authentication is required. - } else if (event.requiresTwoStepAuth) { + } else if (event.requiresTwoStepAuth || "sms".equals(event.notificationSent)) { AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - needs 2fa"); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index 46990df2a90c..00ad05d0523f 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -243,7 +243,7 @@ public void onSocialChanged(OnSocialChanged event) { break; } // Response does not return error when two-factor authentication is required. - } else if (event.requiresTwoStepAuth) { + } else if (event.requiresTwoStepAuth || "sms".equals(event.notificationSent)) { AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - 2fa required"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, From 8451c7afd954686aee1cdef773bcc9ae4176c0f8 Mon Sep 17 00:00:00 2001 From: vojtasmrcek Date: Wed, 29 Aug 2018 13:29:30 +0200 Subject: [PATCH 05/13] Add a meaningful error message when the 2fa loggin is stopped because of sms throttling --- .../org/wordpress/android/login/LoginGoogleFragment.java | 5 +++++ .../org/wordpress/android/login/SignupGoogleFragment.java | 5 +++++ .../login/WordPressLoginFlow/src/main/res/values/strings.xml | 1 + 3 files changed, 11 insertions(+) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index d61f9ee2e144..10bdeaddb7a5 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -190,6 +190,11 @@ public void onSocialChanged(OnSocialChanged event) { mAnalyticsListener.trackSocialErrorUnknownUser(); showError(getString(R.string.login_error_email_not_found, mGoogleEmail)); break; + // Too many attempts on sending SMS verification code. The user has to wait before they try again + case SMS_CODE_THROTTLED: + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - sms code throttled"); + showError(getString(R.string.login_error_sms_throttled)); + break; // Unknown error. case GENERIC_ERROR: // Do nothing for now (included to show all error types) and just fall through to 'default' diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index 00ad05d0523f..7b04357b14e6 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -237,6 +237,11 @@ public void onSocialChanged(OnSocialChanged event) { AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - user already exists"); handleUserExists(); break; + // Too many attempts on sending SMS verification code. The user has to wait before they try again + case SMS_CODE_THROTTLED: + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - sms code throttled"); + showError(getString(R.string.login_error_sms_throttled)); + break; default: AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - unknown"); showError(getString(R.string.login_error_generic)); diff --git a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml index e3f673efb6a4..60c2065b506b 100644 --- a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml +++ b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml @@ -60,6 +60,7 @@ Close The Google account \'%s\' doesn\'t match any existing account on WordPress.com. There was some trouble connecting with the Google account. + Too many attempts on sending SMS verification code. Try again in a minute. Google login could not be started. \nMaybe try a different account? There was some trouble checking the email address. From b8bf0f0115a8bab0c55c557be53bcbe78064ce40 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Wed, 29 Aug 2018 13:50:46 +0200 Subject: [PATCH 06/13] Fix checkstyle --- .../org/wordpress/android/login/LoginGoogleFragment.java | 3 ++- .../org/wordpress/android/login/SignupGoogleFragment.java | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index 10bdeaddb7a5..f4226626ccfc 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -70,7 +70,8 @@ public void onActivityResult(int request, int result, Intent data) { } AppLog.d(T.MAIN, - "GOOGLE SIGNIN: Google has returned a sign in result - dispatching SocialLoginAction"); + "GOOGLE SIGNIN: Google has returned a sign in result - dispatching " + + "SocialLoginAction"); PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); } catch (NullPointerException exception) { diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index 7b04357b14e6..11542fc2fced 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -107,7 +107,8 @@ public void onActivityResult(int request, int result, Intent data) { PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); AppLog.d(T.MAIN, - "GOOGLE SIGNUP: Google has returned a sign up result - dispatching SocialSignupAction"); + "GOOGLE SIGNUP: Google has returned a sign up result - dispatching " + + "SocialSignupAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialSignupAction(payload)); mOldSitesIds = SiteUtils.getCurrentSiteIds(mSiteStore, false); } catch (NullPointerException exception) { @@ -229,7 +230,8 @@ public void onSocialChanged(OnSocialChanged event) { // Dispatch social login action to retrieve data required for two-factor authentication. PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); AppLog.d(T.MAIN, - "GOOGLE SIGNUP: onSocialChanged - error - two step authentication - dispatching pushSocialLoginAction"); + "GOOGLE SIGNUP: onSocialChanged - error - two step authentication - dispatching " + + "pushSocialLoginAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); break; // WordPress account exists with input email address, but not connected. From bd154e9989590d507b6667892c9c8d5879c98928 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Wed, 29 Aug 2018 20:43:12 +0200 Subject: [PATCH 07/13] Fix build - missing string in the base app --- WordPress/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 0591f4d47d9b..e812487dcd23 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -2066,6 +2066,7 @@ Close The Google account \'%s\' doesn\'t match any existing account on WordPress.com. There was some trouble connecting with the Google account. + Too many attempts on sending SMS verification code. Try again in a minute. Google login could not be started. \nMaybe try a different account? From 3f9560c28b45de5ed6cf761cf84cff5378dd55a6 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Thu, 30 Aug 2018 13:18:15 +0200 Subject: [PATCH 08/13] Fix log msgs --- .../org/wordpress/android/login/SignupGoogleFragment.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index 11542fc2fced..b2af358cdc7a 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -202,13 +202,12 @@ public void onAuthenticationChanged(OnAuthenticationChanged event) { "SignupGoogleFragment.onAuthenticationChanged: " + event.error.type + " - " + event.error.message); } else if (event.createdAccount) { AppLog.d(T.MAIN, - "GOOGLE SIGNUP: onAuthenticationChanged - createdAccount=true -> the email is already attached to" - + " an wordpress account"); + "GOOGLE SIGNUP: onAuthenticationChanged - new wordpress account created"); mAnalyticsListener.trackCreatedAccount(event.userName, mGoogleEmail); mGoogleListener.onGoogleSignupFinished(mDisplayName, mGoogleEmail, mPhotoUrl, event.userName); // Continue with login since existing account was selected. } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: onAuthenticationChanged - new wordpress account created"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onAuthenticationChanged - the email is already attached to an account"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.loggedInViaSocialAccount(mOldSitesIds, true); } From e6dbc86b533e4ebff06994c0c77ceb981fc84b71 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 31 Aug 2018 10:28:48 +0200 Subject: [PATCH 09/13] Refactoring --- .../android/ui/accounts/LoginActivity.java | 6 ++- .../android/login/GoogleFragment.java | 36 +++++++------ .../android/login/Login2FaFragment.java | 2 +- .../android/login/LoginGoogleFragment.java | 52 +++++++++---------- .../android/login/SignupGoogleFragment.java | 29 +++++------ 5 files changed, 65 insertions(+), 60 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java index 34b81ff6d7e4..5eba82e66790 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/LoginActivity.java @@ -749,7 +749,8 @@ public void onGoogleSignupFinished(String name, String email, String photoUrl, S finish(); } - @Override public void onGoogleSignupError(String msg) { + @Override + public void onGoogleSignupError(String msg) { BasicFragmentDialog dialog = new BasicFragmentDialog(); dialog.initialize(GOOGLE_ERROR_DIALOG_TAG, getString(R.string.error), msg, @@ -759,7 +760,8 @@ public void onGoogleSignupFinished(String name, String email, String photoUrl, S dialog.show(this.getSupportFragmentManager(), GOOGLE_ERROR_DIALOG_TAG); } - @Override public void onPositiveClicked(@NotNull String instanceTag) { + @Override + public void onPositiveClicked(@NotNull String instanceTag) { switch (instanceTag) { case GOOGLE_ERROR_DIALOG_TAG: // just dismiss the dialog diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java index b8e355470da1..cdb255b4a018 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/GoogleFragment.java @@ -34,6 +34,10 @@ public class GoogleFragment extends Fragment implements ConnectionCallbacks, OnC private static final String STATE_GOOGLE_PHOTO_URL = "STATE_GOOGLE_PHOTO_URL"; private boolean mIsResolvingError; private boolean mShouldResolveError; + /** + * This flag is used to store the information the finishFlow was called when the fragment wasn't attached to an + * activity (for example an EventBus event was received during ongoing configuration change). + */ private boolean mFinished; private static final String STATE_RESOLVING_ERROR = "STATE_RESOLVING_ERROR"; @@ -119,22 +123,24 @@ public void onAttach(Context context) { throw new ClassCastException(context.toString() + " must implement GoogleListener"); } if (mFinished) { - finishSignUp(); + finishFlow(); } } - @Override public void onDestroy() { + @Override + public void onDestroy() { disconnectGoogleClient(); - AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: disconnecting google client"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP/LOGIN: disconnecting google client"); mDispatcher.unregister(this); super.onDestroy(); } - @Override public void onResume() { + @Override + public void onResume() { super.onResume(); // Show account dialog when Google API onConnected callback returns before fragment is attached. if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && !mIsResolvingError && !mShouldResolveError) { - startSignInProcess(); + startFlow(); } } @@ -145,11 +151,9 @@ public void onConnected(Bundle bundle) { if (mShouldResolveError) { mShouldResolveError = false; - //noinspection StatementWithEmptyBody + // if the fragment is not attached to an activity, the process is started in the onResume if (isAdded()) { - startSignInProcess(); - } else { - // handled in onResume + startFlow(); } } } @@ -190,7 +194,7 @@ public void connectGoogleClient() { mShouldResolveError = true; mGoogleApiClient.connect(); } else { - startSignInProcess(); + startFlow(); } } @@ -201,23 +205,23 @@ protected void disconnectGoogleClient() { } } - protected void startSignInProcess() { + protected void startFlow() { // Do nothing here. This should be overridden by inheriting class. } - protected void finishSignUp() { - /* This flag might get lost when the finishSignUp is called after the fragment's + protected void finishFlow() { + /* This flag might get lost when the finishFlow is called after the fragment's onSaveInstanceState was called - however it's a very rare case, since the fragment is retained across config changes. */ mFinished = true; if (getActivity() != null) { - AppLog.d(T.MAIN, "GOOGLE SIGNUP/IN: finishing signup"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP/LOGIN: finishing signup/login"); getActivity().getSupportFragmentManager().beginTransaction().remove(this).commitAllowingStateLoss(); } } protected void showError(String message) { - finishSignUp(); + finishFlow(); mGoogleListener.onGoogleSignupError(message); } @@ -234,7 +238,7 @@ public void onActivityResult(int request, int result, Intent data) { if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } else { - startSignInProcess(); + startFlow(); } mIsResolvingError = false; diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/Login2FaFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/Login2FaFragment.java index 9fcfe04f30fc..54047e998469 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/Login2FaFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/Login2FaFragment.java @@ -74,8 +74,8 @@ public class Login2FaFragment extends LoginBaseFormFragment imple private static final String TWO_FACTOR_TYPE_AUTHENTICATOR = "authenticator"; private static final String TWO_FACTOR_TYPE_BACKUP = "backup"; - private static final String TWO_FACTOR_TYPE_SMS = "sms"; + public static final String TWO_FACTOR_TYPE_SMS = "sms"; public static final String TAG = "login_2fa_fragment_tag"; private static final Pattern TWO_STEP_AUTH_CODE = Pattern.compile("^[0-9]{6}"); diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index f4226626ccfc..0ff9236d6b39 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -36,14 +36,14 @@ public void onAttach(Context context) { } @Override - protected void startSignInProcess() { + protected void startFlow() { if (!mLoginRequested) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: startSignInProgress"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: startFlow"); mLoginRequested = true; - Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); - startActivityForResult(signInIntent, REQUEST_LOGIN); + Intent loginIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); + startActivityForResult(loginIntent, REQUEST_LOGIN); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: startSignInProgress called, but is already in progress"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: startFlow called, but is already in progress"); } } @@ -56,12 +56,12 @@ public void onActivityResult(int request, int result, Intent data) { disconnectGoogleClient(); mLoginRequested = false; if (result == RESULT_OK) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - succcess"); - GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); + AppLog.d(T.MAIN, "GOOGLE LOGIN: Google has returned a sign in result - succcess"); + GoogleSignInResult loginResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); - if (signInResult.isSuccess()) { + if (loginResult.isSuccess()) { try { - GoogleSignInAccount account = signInResult.getSignInAccount(); + GoogleSignInAccount account = loginResult.getSignInAccount(); if (account != null) { mGoogleEmail = account.getEmail() != null ? account.getEmail() : ""; @@ -70,19 +70,19 @@ public void onActivityResult(int request, int result, Intent data) { } AppLog.d(T.MAIN, - "GOOGLE SIGNIN: Google has returned a sign in result - dispatching " + "GOOGLE LOGIN: Google has returned a sign in result - dispatching " + "SocialLoginAction"); PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); } catch (NullPointerException exception) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - NPE"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: Google has returned a sign in result - NPE"); AppLog.e(T.NUX, "Cannot get ID token from Google login account.", exception); showError(getString(R.string.login_error_generic)); } } else { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - error"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: Google has returned a sign in result - error"); mAnalyticsListener.trackSocialButtonFailure(); - switch (signInResult.getStatus().getStatusCode()) { + switch (loginResult.getStatus().getStatusCode()) { // Internal error. case GoogleSignInStatusCodes.INTERNAL_ERROR: AppLog.e(T.NUX, "Google Login Failed: internal error."); @@ -126,12 +126,12 @@ public void onActivityResult(int request, int result, Intent data) { } } } else if (result == RESULT_CANCELED) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - canceled"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: Google has returned a sign in result - canceled"); mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was CANCELED."); - finishSignUp(); + finishFlow(); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: Google has returned a sign in result - unknown"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: Google has returned a sign in result - unknown"); mAnalyticsListener.trackSocialButtonFailure(); AppLog.e(T.NUX, "Google Login Failed: result was not OK or CANCELED."); showError(getString(R.string.login_error_generic)); @@ -145,7 +145,7 @@ public void onActivityResult(int request, int result, Intent data) { @Subscribe(threadMode = ThreadMode.MAIN) public void onAuthenticationChanged(OnAuthenticationChanged event) { if (event.isError()) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onAuthenticationChanged - error"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onAuthenticationChanged - error"); AppLog.e(T.API, "LoginGoogleFragment.onAuthenticationChanged: " + event.error.type + " - " + event.error.message); mAnalyticsListener.trackLoginFailed(event.getClass().getSimpleName(), @@ -156,10 +156,10 @@ public void onAuthenticationChanged(OnAuthenticationChanged event) { showError(getString(R.string.login_error_generic)); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onAuthenticationChanged - success"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onAuthenticationChanged - success"); AppLog.i(T.NUX, "LoginGoogleFragment.onAuthenticationChanged: " + event.toString()); mGoogleListener.onGoogleLoginFinished(); - finishSignUp(); + finishFlow(); } } @@ -181,13 +181,13 @@ public void onSocialChanged(OnSocialChanged event) { switch (event.error.type) { // WordPress account exists with input email address, but not connected. case USER_EXISTS: - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - wordpress acount exists but not connected"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - wordpress acount exists but not connected"); mAnalyticsListener.trackSocialAccountsNeedConnecting(); mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); break; // WordPress account does not exist with input email address. case UNKNOWN_USER: - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - wordpress acount doesn't exist"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - wordpress acount doesn't exist"); mAnalyticsListener.trackSocialErrorUnknownUser(); showError(getString(R.string.login_error_email_not_found, mGoogleEmail)); break; @@ -200,19 +200,19 @@ public void onSocialChanged(OnSocialChanged event) { case GENERIC_ERROR: // Do nothing for now (included to show all error types) and just fall through to 'default' default: - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - unknown error"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - unknown error"); showError(getString(R.string.login_error_generic)); break; } // Response does not return error when two-factor authentication is required. - } else if (event.requiresTwoStepAuth || "sms".equals(event.notificationSent)) { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - needs 2fa"); + } else if (event.requiresTwoStepAuth || Login2FaFragment.TWO_FACTOR_TYPE_SMS.equals(event.notificationSent)) { + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - needs 2fa"); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNIN: onSocialChanged - success"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - success"); mGoogleListener.onGoogleLoginFinished(); } - finishSignUp(); + finishFlow(); } } diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index b2af358cdc7a..5dfbb3616110 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -70,14 +70,14 @@ public void onDetach() { } @Override - protected void startSignInProcess() { + protected void startFlow() { if (!mSignupRequested) { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: startSignInProcess"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: startFlow"); mSignupRequested = true; Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, REQUEST_SIGNUP); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: startSignInProcess called, but is already in progress"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: startFlow called, but is already in progress"); } } @@ -107,8 +107,7 @@ public void onActivityResult(int request, int result, Intent data) { PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); AppLog.d(T.MAIN, - "GOOGLE SIGNUP: Google has returned a sign up result - dispatching " - + "SocialSignupAction"); + "GOOGLE SIGNUP: Google has returned a sign up result - dispatching SocialSignupAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialSignupAction(payload)); mOldSitesIds = SiteUtils.getCurrentSiteIds(mSiteStore, false); } catch (NullPointerException exception) { @@ -166,7 +165,7 @@ public void onActivityResult(int request, int result, Intent data) { AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - canceled"); mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was CANCELED."); - finishSignUp(); + finishFlow(); } else { AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - unknown"); mAnalyticsListener.trackSignupSocialButtonFailure(); @@ -211,7 +210,7 @@ public void onAuthenticationChanged(OnAuthenticationChanged event) { mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.loggedInViaSocialAccount(mOldSitesIds, true); } - finishSignUp(); + finishFlow(); } @SuppressWarnings("unused") @@ -229,14 +228,14 @@ public void onSocialChanged(OnSocialChanged event) { // Dispatch social login action to retrieve data required for two-factor authentication. PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); AppLog.d(T.MAIN, - "GOOGLE SIGNUP: onSocialChanged - error - two step authentication - dispatching " + "GOOGLE SIGNUP: onSocialChanged error - two step authentication - dispatching " + "pushSocialLoginAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialLoginAction(payload)); break; // WordPress account exists with input email address, but not connected. case USER_EXISTS: AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - user already exists"); - handleUserExists(); + loginViaSocialAccount(); break; // Too many attempts on sending SMS verification code. The user has to wait before they try again case SMS_CODE_THROTTLED: @@ -249,23 +248,23 @@ public void onSocialChanged(OnSocialChanged event) { break; } // Response does not return error when two-factor authentication is required. - } else if (event.requiresTwoStepAuth || "sms".equals(event.notificationSent)) { + } else if (event.requiresTwoStepAuth || Login2FaFragment.TWO_FACTOR_TYPE_SMS.equals(event.notificationSent)) { AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - 2fa required"); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, event.nonceSms); - finishSignUp(); + finishFlow(); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - shouldn't happen - google sign in success"); - handleUserExists(); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - google login success"); + loginViaSocialAccount(); } } - private void handleUserExists() { + private void loginViaSocialAccount() { mAnalyticsListener.trackSignupSocialAccountsNeedConnecting(); mAnalyticsListener.trackSignupSocialToLogin(); mLoginListener.showSignupToLoginMessage(); mLoginListener.loginViaSocialAccount(mGoogleEmail, mIdToken, SERVICE_TYPE_GOOGLE, true); - finishSignUp(); + finishFlow(); } } From 982431cf6b3d55a4a4d8cc59150fdf9163b19678 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 31 Aug 2018 10:32:09 +0200 Subject: [PATCH 10/13] Refactoring --- .../org/wordpress/android/login/LoginGoogleFragment.java | 6 +++--- .../org/wordpress/android/login/SignupGoogleFragment.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index 0ff9236d6b39..a88d8f9886d0 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -193,18 +193,18 @@ public void onSocialChanged(OnSocialChanged event) { break; // Too many attempts on sending SMS verification code. The user has to wait before they try again case SMS_CODE_THROTTLED: - AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - error - sms code throttled"); + AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - error - sms code throttled"); showError(getString(R.string.login_error_sms_throttled)); break; // Unknown error. case GENERIC_ERROR: - // Do nothing for now (included to show all error types) and just fall through to 'default' + // Do nothing for now (included to show all error types) and just fall through to 'default' default: AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - unknown error"); showError(getString(R.string.login_error_generic)); break; } - // Response does not return error when two-factor authentication is required. + // Response does not return error when two-factor authentication is required. } else if (event.requiresTwoStepAuth || Login2FaFragment.TWO_FACTOR_TYPE_SMS.equals(event.notificationSent)) { AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - needs 2fa"); mLoginListener.needs2faSocial(mGoogleEmail, event.userId, event.nonceAuthenticator, event.nonceBackup, diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index 5dfbb3616110..f469c40e1a74 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -247,7 +247,7 @@ public void onSocialChanged(OnSocialChanged event) { showError(getString(R.string.login_error_generic)); break; } - // Response does not return error when two-factor authentication is required. + // Response does not return error when two-factor authentication is required. } else if (event.requiresTwoStepAuth || Login2FaFragment.TWO_FACTOR_TYPE_SMS.equals(event.notificationSent)) { AppLog.d(T.MAIN, "GOOGLE SIGNUP: onSocialChanged - 2fa required"); mAnalyticsListener.trackSignupSocialToLogin(); From e880cc64c9a1f3e1bbb4ea41ea4e7c3bc9a1402c Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 31 Aug 2018 14:01:24 +0200 Subject: [PATCH 11/13] Checkstyle fix --- .../android/login/SignupGoogleFragment.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java index f469c40e1a74..91ffe71d8094 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/SignupGoogleFragment.java @@ -93,7 +93,7 @@ public void onActivityResult(int request, int result, Intent data) { GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (signInResult.isSuccess()) { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - succcess"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - succcess"); try { GoogleSignInAccount account = signInResult.getSignInAccount(); @@ -106,17 +106,16 @@ public void onActivityResult(int request, int result, Intent data) { } PushSocialPayload payload = new PushSocialPayload(mIdToken, SERVICE_TYPE_GOOGLE); - AppLog.d(T.MAIN, - "GOOGLE SIGNUP: Google has returned a sign up result - dispatching SocialSignupAction"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - dispatching SocialSignupAction"); mDispatcher.dispatch(AccountActionBuilder.newPushSocialSignupAction(payload)); mOldSitesIds = SiteUtils.getCurrentSiteIds(mSiteStore, false); } catch (NullPointerException exception) { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - NPE"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - NPE"); AppLog.e(T.NUX, "Cannot get ID token from Google signup account.", exception); showError(getString(R.string.login_error_generic)); } } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - error"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - error"); mAnalyticsListener.trackSignupSocialButtonFailure(); switch (signInResult.getStatus().getStatusCode()) { // Internal error. @@ -162,12 +161,12 @@ public void onActivityResult(int request, int result, Intent data) { } } } else if (result == RESULT_CANCELED) { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - canceled"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - canceled"); mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was CANCELED."); finishFlow(); } else { - AppLog.d(T.MAIN, "GOOGLE SIGNUP: Google has returned a sign up result - unknown"); + AppLog.d(T.MAIN, "GOOGLE SIGNUP: sign up result returned - unknown"); mAnalyticsListener.trackSignupSocialButtonFailure(); AppLog.e(T.NUX, "Google Signup Failed: result was not OK or CANCELED."); showError(getString(R.string.login_error_generic)); From fef35d7730ec69ce8c6aae2e4554c3fbbd6b4b61 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 31 Aug 2018 17:02:27 +0200 Subject: [PATCH 12/13] Fix text of sms throttled error --- WordPress/src/main/res/values/strings.xml | 2 +- libs/login/WordPressLoginFlow/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index e812487dcd23..fcf4332cdb13 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -2066,7 +2066,7 @@ Close The Google account \'%s\' doesn\'t match any existing account on WordPress.com. There was some trouble connecting with the Google account. - Too many attempts on sending SMS verification code. Try again in a minute. + We\'ve made too many attempts to send an SMS verification code — take a break, and request a new one in a minute. Google login could not be started. \nMaybe try a different account? diff --git a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml index 60c2065b506b..5db50b373d2e 100644 --- a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml +++ b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml @@ -60,7 +60,7 @@ Close The Google account \'%s\' doesn\'t match any existing account on WordPress.com. There was some trouble connecting with the Google account. - Too many attempts on sending SMS verification code. Try again in a minute. + We\'ve made too many attempts to send an SMS verification code — take a break, and request a new one in a minute. Google login could not be started. \nMaybe try a different account? There was some trouble checking the email address. From 992e5d724b236d0c72261f8995f3200a6cf0406c Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 31 Aug 2018 17:06:03 +0200 Subject: [PATCH 13/13] Fix text of email not found error --- WordPress/src/main/res/values/strings.xml | 2 +- .../java/org/wordpress/android/login/LoginGoogleFragment.java | 2 +- libs/login/WordPressLoginFlow/src/main/res/values/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index fcf4332cdb13..b665ed9d2d9a 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -2064,7 +2064,7 @@ My sites Log in with Google. Close - The Google account \'%s\' doesn\'t match any existing account on WordPress.com. + There\'s no WordPress.com account matching this Google account. There was some trouble connecting with the Google account. We\'ve made too many attempts to send an SMS verification code — take a break, and request a new one in a minute. Google login could not be started. diff --git a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java index a88d8f9886d0..112bef05a8a5 100644 --- a/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java +++ b/libs/login/WordPressLoginFlow/src/main/java/org/wordpress/android/login/LoginGoogleFragment.java @@ -189,7 +189,7 @@ public void onSocialChanged(OnSocialChanged event) { case UNKNOWN_USER: AppLog.d(T.MAIN, "GOOGLE LOGIN: onSocialChanged - wordpress acount doesn't exist"); mAnalyticsListener.trackSocialErrorUnknownUser(); - showError(getString(R.string.login_error_email_not_found, mGoogleEmail)); + showError(getString(R.string.login_error_email_not_found_v2)); break; // Too many attempts on sending SMS verification code. The user has to wait before they try again case SMS_CODE_THROTTLED: diff --git a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml index 5db50b373d2e..8a6fdfa79215 100644 --- a/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml +++ b/libs/login/WordPressLoginFlow/src/main/res/values/strings.xml @@ -58,7 +58,7 @@ Logged in as Log in with Google. Close - The Google account \'%s\' doesn\'t match any existing account on WordPress.com. + There\'s no WordPress.com account matching this Google account. There was some trouble connecting with the Google account. We\'ve made too many attempts to send an SMS verification code — take a break, and request a new one in a minute. Google login could not be started.