package org.wordpress.android.ui.accounts;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
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.fluxc.model.SiteModel;
import org.wordpress.android.fluxc.store.SiteStore;
import org.wordpress.android.ui.ActivityId;
import org.wordpress.android.ui.accounts.SmartLockHelper.Callback;
import org.wordpress.android.ui.accounts.login.MagicLinkRequestFragment;
import org.wordpress.android.ui.accounts.login.MagicLinkSentFragment;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import javax.inject.Inject;
public class SignInActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener,
MagicLinkRequestFragment.OnMagicLinkFragmentInteraction, JetpackCallbacks,
SignInFragment.OnMagicLinkRequestInteraction, MagicLinkSentFragment.OnMagicLinkSentInteraction {
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 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_PREFILL_URL = "EXTRA_PREFILL_URL";
public static final String EXTRA_INHIBIT_MAGIC_LOGIN = "INHIBIT_MAGIC_LOGIN";
public static final String MAGIC_LOGIN = "magic-login";
public static final String TOKEN_PARAMETER = "token";
private SmartLockHelper mSmartLockHelper;
private ProgressDialog mProgressDialog;
private SiteModel mJetpackSite;
@Inject SiteStore mSiteStore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((WordPress) getApplication()).component().inject(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.welcome_activity);
String action = getIntent().getAction();
Uri data = getIntent().getData();
if (Intent.ACTION_VIEW.equals(action) && data != null) {
if (data.getBooleanQueryParameter("selfhosted", false)) {
getIntent().putExtra(SignInActivity.EXTRA_START_FRAGMENT, SignInActivity.ADD_SELF_HOSTED_BLOG);
if (data.getQueryParameter("url") != null) {
getIntent().putExtra(EXTRA_PREFILL_URL, data.getQueryParameter("url"));
}
}
}
if (savedInstanceState == null) {
addSignInFragment();
}
mSmartLockHelper = new SmartLockHelper(this);
mSmartLockHelper.initSmartLockForPasswords();
ActivityId.trackLastActivity(ActivityId.LOGIN);
}
@Override
protected void onResume() {
super.onResume();
actionMode(getIntent().getExtras());
if (hasMagicLinkLoginIntent()) {
AnalyticsTracker.track(AnalyticsTracker.Stat.LOGIN_MAGIC_LINK_OPENED);
attemptLoginWithToken(getIntent().getData());
}
}
@Override
protected void onPause() {
super.onPause();
cancelProgressDialog();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
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");
}
} else if (requestCode == SMART_LOCK_READ) {
if (resultCode == RESULT_OK) {
AppLog.d(T.NUX, "Credentials retrieved");
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
SignInFragment signInFragment = (SignInFragment) getSupportFragmentManager().findFragmentByTag(SignInFragment.TAG);
if (signInFragment != null) {
signInFragment.onCredentialRetrieved(credential);
}
} else {
AppLog.e(T.NUX, "Credential read failed");
}
}
}
private void cancelProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.cancel();
}
}
private void attemptLoginWithToken(Uri uri) {
getSignInFragment().setToken(uri.getQueryParameter(TOKEN_PARAMETER));
SignInFragment signInFragment = getSignInFragment();
slideInFragment(signInFragment, false);
mProgressDialog = ProgressDialog
.show(this, "", getString(R.string.logging_in), true, true, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
getSignInFragment().setToken("");
}
});
mProgressDialog.show();
}
private boolean hasMagicLinkLoginIntent() {
String action = getIntent().getAction();
Uri uri = getIntent().getData();
return Intent.ACTION_VIEW.equals(action) && uri != null && uri.getHost().contains(MAGIC_LOGIN);
}
protected void actionMode(Bundle extras) {
int actionMode = SIGN_IN_REQUEST;
String prefillUrl = "";
if (extras != null) {
actionMode = extras.getInt(EXTRA_START_FRAGMENT, -1);
if (extras.containsKey(EXTRA_JETPACK_SITE_AUTH)) {
mJetpackSite = mSiteStore.getSiteByLocalId(extras.getInt(EXTRA_JETPACK_SITE_AUTH));
if (mJetpackSite != null) {
String customMessage = extras.getString(EXTRA_JETPACK_MESSAGE_AUTH, null);
getSignInFragment().setBlogAndCustomMessageForJetpackAuth(mJetpackSite, customMessage);
}
} else if (extras.containsKey(EXTRA_IS_AUTH_ERROR)) {
getSignInFragment().showAuthErrorMessage();
}
prefillUrl = extras.getString(EXTRA_PREFILL_URL, "");
}
switch (actionMode) {
case ADD_SELF_HOSTED_BLOG:
getSignInFragment().forceSelfHostedMode(prefillUrl);
break;
default:
break;
}
}
public SignInFragment getSignInFragment() {
SignInFragment signInFragment =
(SignInFragment) getSupportFragmentManager().findFragmentByTag(SignInFragment.TAG);
if (signInFragment == null) {
return new SignInFragment();
} else {
return signInFragment;
}
}
public SmartLockHelper getSmartLockHelper() {
return mSmartLockHelper;
}
private void popBackStackToSignInFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStackImmediate();
}
getSupportFragmentManager().popBackStack();
}
protected void addSignInFragment() {
SignInFragment signInFragment = new SignInFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, signInFragment, SignInFragment.TAG);
fragmentTransaction.commit();
}
private void slideInFragment(Fragment fragment) {
slideInFragment(fragment, true);
}
private void slideInFragment(Fragment fragment, boolean shouldAddToBackStack) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.activity_slide_in_from_right, R.anim.activity_slide_out_to_left,
R.anim.activity_slide_in_from_left, R.anim.activity_slide_out_to_right);
fragmentTransaction.replace(R.id.fragment_container, fragment);
if (shouldAddToBackStack) {
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commitAllowingStateLoss();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
AppLog.d(T.NUX, "Connection result: " + connectionResult);
}
@Override
public void onConnected(Bundle bundle) {
AppLog.d(T.NUX, "Google API client connected");
SignInFragment signInFragment =
(SignInFragment) getSupportFragmentManager().findFragmentByTag(SignInFragment.TAG);
// Autofill only if signInFragment is there and if it can be autofilled (ie. username and password fields are
// empty).
if (signInFragment != null && signInFragment.canAutofillUsernameAndPassword()) {
mSmartLockHelper.smartLockAutoFill(new Callback() {
@Override
public void onCredentialRetrieved(Credential credential) {
SignInFragment signInFragment =
(SignInFragment) getSupportFragmentManager().findFragmentByTag(SignInFragment.TAG);
if (signInFragment != null) {
signInFragment.onCredentialRetrieved(credential);
}
}
});
}
}
@Override
public void onConnectionSuspended(int i) {
AppLog.d(T.NUX, "Google API client connection suspended");
}
@Override
public void onMagicLinkSent() {
MagicLinkSentFragment magicLinkSentFragment = new MagicLinkSentFragment();
slideInFragment(magicLinkSentFragment);
}
@Override
public void onEnterPasswordRequested() {
AnalyticsTracker.track(AnalyticsTracker.Stat.LOGIN_MAGIC_LINK_EXITED);
getSignInFragment().setIsMagicLinkEnabled(false);
popBackStackToSignInFragment();
}
@Override
public void onMagicLinkRequestSuccess(String email) {
MagicLinkRequestFragment magicLinkRequestFragment = MagicLinkRequestFragment.newInstance(email);
slideInFragment(magicLinkRequestFragment);
}
@Override
public boolean isJetpackAuth() {
return mJetpackSite != null;
}
@Override
public SiteModel getJetpackSite() {
return mJetpackSite;
}
}