From 8acc64479a724ed312e8601ffc914dc269ed3e80 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 11 Feb 2016 12:21:39 +0100 Subject: [PATCH 1/8] first step - Smart Lock for Passwords integration into our sign in process --- WordPress/build.gradle | 1 + .../android/ui/ActivityLauncher.java | 7 +- .../android/ui/accounts/SignInActivity.java | 41 ++++--- .../android/ui/accounts/SignInFragment.java | 107 +++++++++++++++++- .../wordpress/android/ui/main/MeFragment.java | 2 +- .../android/ui/main/WPMainActivity.java | 8 +- .../NotificationsListFragment.java | 2 +- .../android/ui/stats/StatsActivity.java | 4 +- .../util/AuthenticationDialogUtils.java | 2 +- 9 files changed, 147 insertions(+), 27 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index d33a3f1481c0..4b730000cb02 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -77,6 +77,7 @@ dependencies { compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.android.support:design:23.1.1' compile 'com.google.android.gms:play-services-gcm:8.3.0' + compile 'com.google.android.gms:play-services-auth:8.3.0' compile 'com.github.chrisbanes.photoview:library:1.2.4' compile 'com.helpshift:android-aar:4.2.0-support' compile 'de.greenrobot:eventbus:2.4.0' diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java index 09a0cf0c3b94..c8eee8c8e678 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java @@ -225,8 +225,11 @@ public static void newBlogForResult(Activity activity) { activity.startActivityForResult(intent, RequestCodes.CREATE_BLOG); } - public static void showSignInForResult(Activity activity) { + public static void showSignInForResult(Activity activity, boolean disableAutoSignIn) { Intent intent = new Intent(activity, SignInActivity.class); + if (disableAutoSignIn) { + intent.putExtra(SignInActivity.EXTRA_DISABLE_AUTO_SIGNIN, true); + } activity.startActivityForResult(intent, RequestCodes.ADD_ACCOUNT); } @@ -257,7 +260,7 @@ public static void viewStatsSinglePostDetails(Context context, PostModel post) { public static void addSelfHostedSiteForResult(Activity activity) { Intent intent = new Intent(activity, SignInActivity.class); - intent.putExtra(SignInActivity.START_FRAGMENT_KEY, SignInActivity.ADD_SELF_HOSTED_BLOG); + intent.putExtra(SignInActivity.EXTRA_START_FRAGMENT, SignInActivity.ADD_SELF_HOSTED_BLOG); activity.startActivityForResult(intent, RequestCodes.ADD_ACCOUNT); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java index bf91585a8668..d0e96bf65bce 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java @@ -1,25 +1,31 @@ package org.wordpress.android.ui.accounts; -import android.app.Activity; import android.app.FragmentManager; import android.content.Intent; import android.os.Bundle; +import android.support.v4.app.FragmentActivity; import android.view.Window; import org.wordpress.android.R; import org.wordpress.android.WordPress; import org.wordpress.android.models.Blog; import org.wordpress.android.ui.ActivityId; +import org.wordpress.android.util.AppLog; +import org.wordpress.android.util.AppLog.T; -public class SignInActivity extends Activity { +public class SignInActivity extends FragmentActivity { public static final int SIGN_IN_REQUEST = 1; public static final int REQUEST_CODE = 5000; public static final int ADD_SELF_HOSTED_BLOG = 2; public static final int SHOW_CERT_DETAILS = 4; - public static String START_FRAGMENT_KEY = "start-fragment"; - public static final String ARG_JETPACK_SITE_AUTH = "ARG_JETPACK_SITE_AUTH"; - public static final String ARG_JETPACK_MESSAGE_AUTH = "ARG_JETPACK_MESSAGE_AUTH"; - public static final String ARG_IS_AUTH_ERROR = "ARG_IS_AUTH_ERROR"; + public static final int SMART_LOCK_SAVE = 5; + public static final int SMART_LOCK_READ = 6; + + public static final String EXTRA_START_FRAGMENT = "start-fragment"; + public static final String EXTRA_JETPACK_SITE_AUTH = "EXTRA_JETPACK_SITE_AUTH"; + public static final String EXTRA_JETPACK_MESSAGE_AUTH = "EXTRA_JETPACK_MESSAGE_AUTH"; + public static final String EXTRA_IS_AUTH_ERROR = "EXTRA_IS_AUTH_ERROR"; + public static final String EXTRA_DISABLE_AUTO_SIGNIN = "EXTRA_DISABLE_AUTO_SIGNIN"; private SignInFragment mSignInFragment; @@ -31,22 +37,20 @@ protected void onCreate(Bundle savedInstanceState) { FragmentManager fragmentManager = getFragmentManager(); mSignInFragment = (SignInFragment) fragmentManager.findFragmentById(R.id.sign_in_fragment); actionMode(getIntent().getExtras()); - ActivityId.trackLastActivity(ActivityId.LOGIN); } private void actionMode(Bundle extras) { int actionMode = SIGN_IN_REQUEST; if (extras != null) { - actionMode = extras.getInt(START_FRAGMENT_KEY, -1); - - if (extras.containsKey(ARG_JETPACK_SITE_AUTH)) { - Blog jetpackBlog = WordPress.getBlog(extras.getInt(ARG_JETPACK_SITE_AUTH)); + actionMode = extras.getInt(EXTRA_START_FRAGMENT, -1); + if (extras.containsKey(EXTRA_JETPACK_SITE_AUTH)) { + Blog jetpackBlog = WordPress.getBlog(extras.getInt(EXTRA_JETPACK_SITE_AUTH)); if (jetpackBlog != null) { - String customMessage = extras.getString(ARG_JETPACK_MESSAGE_AUTH, null); + String customMessage = extras.getString(EXTRA_JETPACK_MESSAGE_AUTH, null); mSignInFragment.setBlogAndCustomMessageForJetpackAuth(jetpackBlog, customMessage); } - } else if (extras.containsKey(ARG_IS_AUTH_ERROR)) { + } else if (extras.containsKey(EXTRA_IS_AUTH_ERROR)) { mSignInFragment.showAuthErrorMessage(); } } @@ -57,8 +61,9 @@ private void actionMode(Bundle extras) { default: break; } - - + if (extras == null || !extras.containsKey(EXTRA_DISABLE_AUTO_SIGNIN)) { + mSignInFragment.smartLockAutoSignIn(); + } } @Override @@ -67,6 +72,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SHOW_CERT_DETAILS) { mSignInFragment.askForSslTrust(); + } else if (requestCode == SMART_LOCK_SAVE) { + if (resultCode == RESULT_OK) { + AppLog.d(T.NUX, "Credentials saved"); + } else { + AppLog.d(T.NUX, "Credentials save cancelled"); + } } else if (resultCode == RESULT_OK && data != null) { String username = data.getStringExtra("username"); String password = data.getStringExtra("password"); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java index cad3791e7778..19e1074d8ec0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentSender; import android.content.res.Configuration; import android.net.Uri; import android.os.AsyncTask; @@ -28,6 +29,17 @@ import android.widget.RelativeLayout; import android.widget.TextView; +import com.google.android.gms.auth.api.Auth; +import com.google.android.gms.auth.api.credentials.Credential; +import com.google.android.gms.auth.api.credentials.CredentialRequest; +import com.google.android.gms.auth.api.credentials.CredentialRequestResult; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.CommonStatusCodes; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; +import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.common.api.Status; import com.wordpress.rest.RestRequest; import org.json.JSONException; @@ -70,7 +82,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SignInFragment extends AbstractFragment implements TextWatcher { +public class SignInFragment extends AbstractFragment implements TextWatcher, ConnectionCallbacks, + OnConnectionFailedListener { private static final String DOT_COM_BASE_URL = "https://wordpress.com"; private static final String FORGOT_PASSWORD_RELATIVE_URL = "/wp-login.php?action=lostpassword"; private static final int WPCOM_ERRONEOUS_LOGIN_THRESHOLD = 3; @@ -115,6 +128,8 @@ public class SignInFragment extends AbstractFragment implements TextWatcher { private String mHttpPassword; private Blog mJetpackBlog; + private GoogleApiClient mCredentialsClient; + public SignInFragment() { mEmailChecker = new EmailChecker(); } @@ -201,6 +216,7 @@ public void onClick(View v) { initPasswordVisibilityButton(rootView, mPasswordEditText); initInfoButtons(rootView); moveBottomButtons(); + initSmartLockForPasswords(); return rootView; } @@ -250,6 +266,60 @@ public void onClick(View v) { mInfoButtonSecondary.setOnClickListener(infoButtonListener); } + private void initSmartLockForPasswords() { + mCredentialsClient = new GoogleApiClient.Builder(getActivity()) + .addConnectionCallbacks(this) + .enableAutoManage((SignInActivity) getActivity(), this) + .addApi(Auth.CREDENTIALS_API) + .build(); + } + + public void smartLockAutoSignIn() { + CredentialRequest credentialRequest = new CredentialRequest.Builder() + .setSupportsPasswordLogin(true) + .build(); + Auth.CredentialsApi.request(mCredentialsClient, credentialRequest).setResultCallback( + new ResultCallback() { + @Override + public void onResult(CredentialRequestResult result) { + Status status = result.getStatus(); + if (status.isSuccess()) { + Credential credential = result.getCredential(); + AppLog.d(T.NUX, "Retrieved username from SmartLock: " + credential.getId()); + signInDotComUser(credential.getId(), credential.getPassword()); + } else { + if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) { + try { + // Prompt the user to choose a saved credential + status.startResolutionForResult(getActivity(), SignInActivity.SMART_LOCK_READ); + } catch (IntentSender.SendIntentException e) { + AppLog.d(T.NUX, "SmartLock: Failed to send resolution for credential " + + "request"); + } + } else { + // The user must create an account or sign in manually. + AppLog.d(T.NUX, "SmartLock: Unsuccessful credential request."); + } + } + } + }); + } + + @Override + public void onConnectionFailed(ConnectionResult connectionResult) { + AppLog.d(T.NUX, "Connection result: " + connectionResult); + } + + @Override + public void onConnected(Bundle bundle) { + AppLog.d(T.NUX, "Google API client connected"); + } + + @Override + public void onConnectionSuspended(int i) { + AppLog.d(T.NUX, "Google API client connection suspended"); + } + private void setSecondaryButtonVisible(boolean visible) { mInfoButtonSecondary.setVisibility(visible ? View.VISIBLE : View.GONE); mInfoButton.setVisibility(visible ? View.GONE : View.VISIBLE); @@ -537,12 +607,43 @@ private boolean hasHardwareKeyboard() { return (getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS); } + private void saveCrendentialsInSmartLock() { + Credential credential = new Credential.Builder(mUsername).setPassword(mPassword).build(); + Auth.CredentialsApi.save(mCredentialsClient, credential).setResultCallback( + new ResultCallback() { + @Override + public void onResult(Status status) { + if (!status.isSuccess() && status.hasResolution()) { + try { + // This prompt the user to resolve the save request + status.startResolutionForResult(getActivity(), SignInActivity.SMART_LOCK_SAVE); + } catch (IntentSender.SendIntentException e) { + // Could not resolve the request + } + } + } + }); + } + + private void deleteCredentialsInSmartLock() { + Credential credential = new Credential.Builder(mUsername).setPassword(mPassword).build(); + Auth.CredentialsApi.delete(mCredentialsClient, credential).setResultCallback( + new ResultCallback() { + @Override + public void onResult(Status status) { + AppLog.i(T.NUX, status.isSuccess() ? "SmartLock: credentials deleted for username: " + mUsername + : "SmartLock: Credentials not deleted for username: " + mUsername ); + } + }); + } + private void signInAndFetchBlogListWPCom() { LoginWPCom login = new LoginWPCom(mUsername, mPassword, mTwoStepCode, mShouldSendTwoStepSMS, mJetpackBlog); login.execute(new LoginAbstract.Callback() { @Override public void onSuccess() { mShouldSendTwoStepSMS = false; + saveCrendentialsInSmartLock(); // Finish this activity if we've authenticated to a Jetpack site if (isJetpackAuth() && getActivity() != null) { @@ -559,6 +660,10 @@ public void onSuccess() { public void onError(int errorMessageId, boolean twoStepCodeRequired, boolean httpAuthRequired, boolean erroneousSslCertificate) { mFetchBlogListCallback.onError(errorMessageId, twoStepCodeRequired, httpAuthRequired, erroneousSslCertificate, ""); mShouldSendTwoStepSMS = false; + // Delete credentials only if login failed with an incorrect username/password error + if (errorMessageId == R.string.username_or_password_incorrect) { + deleteCredentialsInSmartLock(); + } } }); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java index a5ecc0d600f6..df7d9eaa1eb3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java @@ -99,7 +99,7 @@ public void onClick(View v) { if (AccountHelper.isSignedInWordPressDotCom()) { signOutWordPressComWithConfirmation(); } else { - ActivityLauncher.showSignInForResult(getActivity()); + ActivityLauncher.showSignInForResult(getActivity(), false); } } }); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java index 9fd6f4c3274c..b1c202006574 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java @@ -171,7 +171,7 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse } } } else { - ActivityLauncher.showSignInForResult(this); + ActivityLauncher.showSignInForResult(this, false); } } } @@ -368,7 +368,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { break; case RequestCodes.REAUTHENTICATE: if (resultCode == RESULT_CANCELED) { - ActivityLauncher.showSignInForResult(this); + ActivityLauncher.showSignInForResult(this, false); } else { // Register for Cloud messaging startService(new Intent(this, GCMRegistrationIntentService.class)); @@ -388,7 +388,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == SiteSettingsFragment.RESULT_BLOG_REMOVED) { // user removed the current (self-hosted) blog from blog settings if (!AccountHelper.isSignedIn()) { - ActivityLauncher.showSignInForResult(this); + ActivityLauncher.showSignInForResult(this, true); } else { MySiteFragment mySiteFragment = getMySiteFragment(); if (mySiteFragment != null) { @@ -442,7 +442,7 @@ public void onEventMainThread(UserSignedOutWordPressCom event) { @SuppressWarnings("unused") public void onEventMainThread(UserSignedOutCompletely event) { - ActivityLauncher.showSignInForResult(this); + ActivityLauncher.showSignInForResult(this, true); } @SuppressWarnings("unused") diff --git a/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java index da123893c147..d38701291b86 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java @@ -370,7 +370,7 @@ private void performActionForActiveFilter() { if (mFilterRadioGroup == null || !isAdded()) return; if (!AccountHelper.isSignedInWordPressDotCom()) { - ActivityLauncher.showSignInForResult(getActivity()); + ActivityLauncher.showSignInForResult(getActivity(), false); return; } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java index 9fe0a8ac8755..bb2898426f79 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java @@ -516,9 +516,9 @@ private boolean updateTimeframeAndDateAndStartRefreshInFragment(FragmentManager private void startWPComLoginActivity() { mResultCode = RESULT_CANCELED; Intent signInIntent = new Intent(this, SignInActivity.class); - signInIntent.putExtra(SignInActivity.ARG_JETPACK_SITE_AUTH, mLocalBlogID); + signInIntent.putExtra(SignInActivity.EXTRA_JETPACK_SITE_AUTH, mLocalBlogID); signInIntent.putExtra( - SignInActivity.ARG_JETPACK_MESSAGE_AUTH, + SignInActivity.EXTRA_JETPACK_MESSAGE_AUTH, getString(R.string.stats_sign_in_jetpack_different_com_account) ); startActivityForResult(signInIntent, SignInActivity.REQUEST_CODE); diff --git a/WordPress/src/main/java/org/wordpress/android/util/AuthenticationDialogUtils.java b/WordPress/src/main/java/org/wordpress/android/util/AuthenticationDialogUtils.java index a029f546bfbe..5c952f0587ba 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/AuthenticationDialogUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/util/AuthenticationDialogUtils.java @@ -80,7 +80,7 @@ public static void showAuthErrorView(Activity activity, int titleResId, int mess // WP.com errors will show the sign in activity if (WordPress.getCurrentBlog() == null || (WordPress.getCurrentBlog() != null && WordPress.getCurrentBlog().isDotcomFlag())) { Intent signInIntent = new Intent(activity, SignInActivity.class); - signInIntent.putExtra(SignInActivity.ARG_IS_AUTH_ERROR, true); + signInIntent.putExtra(SignInActivity.EXTRA_IS_AUTH_ERROR, true); signInIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); activity.startActivityForResult(signInIntent, SignInActivity.REQUEST_CODE); return; From 136fe1db7dbc331850a43a5739f308a9c8c33c80 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 18 Feb 2016 12:24:45 +0100 Subject: [PATCH 2/8] fix retrieval when multi selection is enabled --- .../wordpress/android/ui/accounts/SignInActivity.java | 10 ++++++++++ .../wordpress/android/ui/accounts/SignInFragment.java | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java index d0e96bf65bce..548228e704de 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java @@ -6,6 +6,8 @@ import android.support.v4.app.FragmentActivity; import android.view.Window; +import com.google.android.gms.auth.api.credentials.Credential; + import org.wordpress.android.R; import org.wordpress.android.WordPress; import org.wordpress.android.models.Blog; @@ -78,6 +80,14 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } else { AppLog.d(T.NUX, "Credentials save cancelled"); } + } else if (requestCode == SMART_LOCK_READ) { + if (resultCode == RESULT_OK) { + AppLog.d(T.NUX, "Credentials retrieved"); + Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY); + mSignInFragment.onCredentialRetrieved(credential); + } else { + AppLog.e(T.NUX, "Credential read failed"); + } } else if (resultCode == RESULT_OK && data != null) { String username = data.getStringExtra("username"); String password = data.getStringExtra("password"); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java index 19e1074d8ec0..d688f5c73a8e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java @@ -285,8 +285,7 @@ public void onResult(CredentialRequestResult result) { Status status = result.getStatus(); if (status.isSuccess()) { Credential credential = result.getCredential(); - AppLog.d(T.NUX, "Retrieved username from SmartLock: " + credential.getId()); - signInDotComUser(credential.getId(), credential.getPassword()); + onCredentialRetrieved(credential); } else { if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) { try { @@ -305,6 +304,11 @@ public void onResult(CredentialRequestResult result) { }); } + public void onCredentialRetrieved(Credential credential) { + AppLog.d(T.NUX, "Retrieved username from SmartLock: " + credential.getId()); + signInDotComUser(credential.getId(), credential.getPassword()); + } + @Override public void onConnectionFailed(ConnectionResult connectionResult) { AppLog.d(T.NUX, "Connection result: " + connectionResult); From 74d5f78f78e4bd1eb33481167b152b34c3952eaa Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 24 Mar 2016 15:18:23 +0100 Subject: [PATCH 3/8] Fix after merge problem --- .../java/org/wordpress/android/ui/main/WPMainActivity.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java index b6e71c7284de..2dc4f65f9dc9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java @@ -38,7 +38,6 @@ import org.wordpress.android.ui.notifications.utils.SimperiumUtils; import org.wordpress.android.ui.posts.PromoDialog; import org.wordpress.android.ui.prefs.AppPrefs; -import org.wordpress.android.ui.prefs.AccountSettingsFragment; import org.wordpress.android.ui.prefs.AppSettingsFragment; import org.wordpress.android.ui.prefs.SiteSettingsFragment; import org.wordpress.android.ui.reader.ReaderPostListFragment; @@ -57,9 +56,6 @@ import org.wordpress.android.util.ToastUtils; import org.wordpress.android.widgets.WPViewPager; -import java.util.List; -import java.util.Map; - import de.greenrobot.event.EventBus; /** @@ -535,7 +531,7 @@ private void updateConnectionBar(boolean isConnected) { private void handleBlogRemoved() { if (!AccountHelper.isSignedIn()) { - ActivityLauncher.showSignInForResult(this); + ActivityLauncher.showSignInForResult(this, true); } else { Blog blog = WordPress.getCurrentBlog(); MySiteFragment mySiteFragment = getMySiteFragment(); From 927504536d8141b502d00e4fd8187c871c6a6159 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 24 Mar 2016 15:18:59 +0100 Subject: [PATCH 4/8] Only auto fill username and password --- .../java/org/wordpress/android/ui/accounts/SignInFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java index 93518931399e..a296006c6068 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java @@ -331,7 +331,8 @@ public void onResult(CredentialRequestResult result) { public void onCredentialRetrieved(Credential credential) { AppLog.d(T.NUX, "Retrieved username from SmartLock: " + credential.getId()); - signInDotComUser(credential.getId(), credential.getPassword()); + mUsernameEditText.setText(credential.getId()); + mPasswordEditText.setText(credential.getPassword()); } @Override From 0720053ed898ea0843ca6d6d5e0735e0fb1f549c Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Tue, 29 Mar 2016 18:45:48 +0200 Subject: [PATCH 5/8] Add missing event in Mixpanel analytics --- .../wordpress/android/analytics/AnalyticsTrackerMixpanel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java index 1192b39724ca..8dade7503d95 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java @@ -786,6 +786,10 @@ private AnalyticsTrackerMixpanelInstructionsForStat instructionsForStat( instructions = AnalyticsTrackerMixpanelInstructionsForStat. mixpanelInstructionsForEventName("Login - Failed To Guess XMLRPC"); break; + case LOGIN_INSERTED_INVALID_URL: + instructions = AnalyticsTrackerMixpanelInstructionsForStat. + mixpanelInstructionsForEventName("Login - Inserted Invalid URL"); + break; case PUSH_AUTHENTICATION_APPROVED: instructions = AnalyticsTrackerMixpanelInstructionsForStat. mixpanelInstructionsForEventName("Push Authentication - Approved"); From 66979d008ed80a246a56bc4e2516927c4cc4d6d0 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 30 Mar 2016 08:38:42 +0200 Subject: [PATCH 6/8] track credential filled / updated --- .../org/wordpress/android/ui/accounts/SignInActivity.java | 5 ++++- .../org/wordpress/android/ui/accounts/SignInFragment.java | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java index 548228e704de..c161b4b72f13 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java @@ -10,6 +10,8 @@ import org.wordpress.android.R; import org.wordpress.android.WordPress; +import org.wordpress.android.analytics.AnalyticsTracker; +import org.wordpress.android.analytics.AnalyticsTracker.Stat; import org.wordpress.android.models.Blog; import org.wordpress.android.ui.ActivityId; import org.wordpress.android.util.AppLog; @@ -64,7 +66,7 @@ private void actionMode(Bundle extras) { break; } if (extras == null || !extras.containsKey(EXTRA_DISABLE_AUTO_SIGNIN)) { - mSignInFragment.smartLockAutoSignIn(); + mSignInFragment.smartLockAutoFill(); } } @@ -76,6 +78,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { mSignInFragment.askForSslTrust(); } else if (requestCode == SMART_LOCK_SAVE) { if (resultCode == RESULT_OK) { + AnalyticsTracker.track(Stat.LOGIN_AUTOFILL_CREDENTIALS_UPDATED); AppLog.d(T.NUX, "Credentials saved"); } else { AppLog.d(T.NUX, "Credentials save cancelled"); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java index a296006c6068..c44d8e9c0f63 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInFragment.java @@ -299,7 +299,7 @@ private void initSmartLockForPasswords() { .build(); } - public void smartLockAutoSignIn() { + public void smartLockAutoFill() { CredentialRequest credentialRequest = new CredentialRequest.Builder() .setSupportsPasswordLogin(true) .build(); @@ -331,6 +331,7 @@ public void onResult(CredentialRequestResult result) { public void onCredentialRetrieved(Credential credential) { AppLog.d(T.NUX, "Retrieved username from SmartLock: " + credential.getId()); + AnalyticsTracker.track(Stat.LOGIN_AUTOFILL_CREDENTIALS_FILLED); mUsernameEditText.setText(credential.getId()); mPasswordEditText.setText(credential.getPassword()); } From e5be9c3d687cfb6d8f1c72f56d987ab0f3a9843a Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 30 Mar 2016 08:39:17 +0200 Subject: [PATCH 7/8] New events LOGIN_AUTOFILL_CREDENTIALS_FILLED/UPDATED --- .../org/wordpress/android/analytics/AnalyticsTracker.java | 2 ++ .../android/analytics/AnalyticsTrackerMixpanel.java | 8 ++++++++ .../android/analytics/AnalyticsTrackerNosara.java | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java index eb7bf1e0fc5e..e0fe841562c4 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java @@ -118,6 +118,8 @@ public enum Stat { LOGIN_FAILED, LOGIN_FAILED_TO_GUESS_XMLRPC, LOGIN_INSERTED_INVALID_URL, + LOGIN_AUTOFILL_CREDENTIALS_FILLED, + LOGIN_AUTOFILL_CREDENTIALS_UPDATED, PUSH_AUTHENTICATION_APPROVED, PUSH_AUTHENTICATION_EXPIRED, PUSH_AUTHENTICATION_FAILED, diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java index 8dade7503d95..7ad12caf9624 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerMixpanel.java @@ -790,6 +790,14 @@ private AnalyticsTrackerMixpanelInstructionsForStat instructionsForStat( instructions = AnalyticsTrackerMixpanelInstructionsForStat. mixpanelInstructionsForEventName("Login - Inserted Invalid URL"); break; + case LOGIN_AUTOFILL_CREDENTIALS_FILLED: + instructions = AnalyticsTrackerMixpanelInstructionsForStat. + mixpanelInstructionsForEventName("Login - Auto Fill Credentials Filled"); + break; + case LOGIN_AUTOFILL_CREDENTIALS_UPDATED: + instructions = AnalyticsTrackerMixpanelInstructionsForStat. + mixpanelInstructionsForEventName("Login - Auto Fill Credentials Updated"); + break; case PUSH_AUTHENTICATION_APPROVED: instructions = AnalyticsTrackerMixpanelInstructionsForStat. mixpanelInstructionsForEventName("Push Authentication - Approved"); diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java index 49895df4ea87..fc89ec0eae1e 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java @@ -369,6 +369,12 @@ public void track(AnalyticsTracker.Stat stat, Map properties) { case LOGIN_INSERTED_INVALID_URL: eventName = "login_inserted_invalid_url"; break; + case LOGIN_AUTOFILL_CREDENTIALS_FILLED: + eventName = "login_autofill_credentials_filled"; + break; + case LOGIN_AUTOFILL_CREDENTIALS_UPDATED: + eventName = "login_autofill_credentials_updated"; + break; case PUSH_AUTHENTICATION_APPROVED: eventName = "push_authentication_approved"; break; From 628379eb00b11f8687e4955979a707ca0b080785 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 30 Mar 2016 17:27:30 +0200 Subject: [PATCH 8/8] enable auto fill in all cases --- .../java/org/wordpress/android/ui/ActivityLauncher.java | 5 +---- .../org/wordpress/android/ui/accounts/SignInActivity.java | 5 +---- .../java/org/wordpress/android/ui/main/MeFragment.java | 2 +- .../org/wordpress/android/ui/main/WPMainActivity.java | 8 ++++---- .../ui/notifications/NotificationsListFragment.java | 2 +- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java index 2349270f9684..94deaea448b4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityLauncher.java @@ -238,11 +238,8 @@ public static void newBlogForResult(Activity activity) { activity.startActivityForResult(intent, RequestCodes.CREATE_BLOG); } - public static void showSignInForResult(Activity activity, boolean disableAutoSignIn) { + public static void showSignInForResult(Activity activity) { Intent intent = new Intent(activity, SignInActivity.class); - if (disableAutoSignIn) { - intent.putExtra(SignInActivity.EXTRA_DISABLE_AUTO_SIGNIN, true); - } activity.startActivityForResult(intent, RequestCodes.ADD_ACCOUNT); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java index c161b4b72f13..dc1191561d52 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/SignInActivity.java @@ -29,7 +29,6 @@ public class SignInActivity extends FragmentActivity { public static final String EXTRA_JETPACK_SITE_AUTH = "EXTRA_JETPACK_SITE_AUTH"; public static final String EXTRA_JETPACK_MESSAGE_AUTH = "EXTRA_JETPACK_MESSAGE_AUTH"; public static final String EXTRA_IS_AUTH_ERROR = "EXTRA_IS_AUTH_ERROR"; - public static final String EXTRA_DISABLE_AUTO_SIGNIN = "EXTRA_DISABLE_AUTO_SIGNIN"; private SignInFragment mSignInFragment; @@ -65,9 +64,7 @@ private void actionMode(Bundle extras) { default: break; } - if (extras == null || !extras.containsKey(EXTRA_DISABLE_AUTO_SIGNIN)) { - mSignInFragment.smartLockAutoFill(); - } + mSignInFragment.smartLockAutoFill(); } @Override diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java index 5843854d240b..03b8f4aa6f84 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/MeFragment.java @@ -109,7 +109,7 @@ public void onClick(View v) { if (AccountHelper.isSignedInWordPressDotCom()) { signOutWordPressComWithConfirmation(); } else { - ActivityLauncher.showSignInForResult(getActivity(), false); + ActivityLauncher.showSignInForResult(getActivity()); } } }); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java index 2dc4f65f9dc9..a3f943c494f3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java @@ -190,7 +190,7 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse } } } else { - ActivityLauncher.showSignInForResult(this, false); + ActivityLauncher.showSignInForResult(this); } } } @@ -413,7 +413,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { break; case RequestCodes.REAUTHENTICATE: if (resultCode == RESULT_CANCELED) { - ActivityLauncher.showSignInForResult(this, false); + ActivityLauncher.showSignInForResult(this); } else { // Register for Cloud messaging startService(new Intent(this, GCMRegistrationIntentService.class)); @@ -479,7 +479,7 @@ public void onEventMainThread(UserSignedOutWordPressCom event) { @SuppressWarnings("unused") public void onEventMainThread(UserSignedOutCompletely event) { - ActivityLauncher.showSignInForResult(this, true); + ActivityLauncher.showSignInForResult(this); } @SuppressWarnings("unused") @@ -531,7 +531,7 @@ private void updateConnectionBar(boolean isConnected) { private void handleBlogRemoved() { if (!AccountHelper.isSignedIn()) { - ActivityLauncher.showSignInForResult(this, true); + ActivityLauncher.showSignInForResult(this); } else { Blog blog = WordPress.getCurrentBlog(); MySiteFragment mySiteFragment = getMySiteFragment(); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java index d38701291b86..da123893c147 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/notifications/NotificationsListFragment.java @@ -370,7 +370,7 @@ private void performActionForActiveFilter() { if (mFilterRadioGroup == null || !isAdded()) return; if (!AccountHelper.isSignedInWordPressDotCom()) { - ActivityLauncher.showSignInForResult(getActivity(), false); + ActivityLauncher.showSignInForResult(getActivity()); return; }