diff --git a/app/build.gradle b/app/build.gradle
index 17a12e940..f077dd862 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -46,6 +46,9 @@ dependencies {
compile 'pub.devrel:easypermissions:0.2.1'
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
+ debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
+ releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
+ testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
}
apply plugin: 'com.google.gms.google-services'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 09e0ee7fc..124bf4d2b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+ android:theme="@style/Theme.AppCompat.NoActionBar"/>
+ android:theme="@style/Theme.AppCompat.NoActionBar"/>
-
-
-
-
delete(@NonNull Activity activity) {
CredentialsApiHelper credentialHelper = CredentialsApiHelper.getInstance(gacHelper);
// Get all SmartLock credentials associated with the user
- List credentials = SmartLockUtil.credentialsFromFirebaseUser(firebaseUser);
+ List credentials = SmartLockBase.credentialsFromFirebaseUser(firebaseUser);
// For each Credential in the list, create a task to delete it.
List> credentialTasks = new ArrayList<>();
@@ -571,7 +569,8 @@ public SignInIntentBuilder setProviders(@NonNull List idpConfigs) {
for (IdpConfig idpConfig : idpConfigs) {
if (configuredProviders.contains(idpConfig.getProviderId())) {
throw new IllegalArgumentException("Each provider can only be set once. "
- + idpConfig.getProviderId() + " was set twice.");
+ + idpConfig.getProviderId()
+ + " was set twice.");
}
configuredProviders.add(idpConfig.getProviderId());
mProviders.add(idpConfig);
@@ -613,24 +612,6 @@ public SignInIntentBuilder setIsSmartLockEnabled(boolean enabled) {
return this;
}
- public Intent build() {
- Context context = mApp.getApplicationContext();
- return build(context);
- }
-
- @VisibleForTesting
- public Intent build(Context context) {
- return ChooseAccountActivity.createIntent(
- context,
- new FlowParameters(
- mApp.getName(),
- new ArrayList<>(mProviders),
- mTheme,
- mLogo,
- mTosUrl,
- mIsSmartLockEnabled));
- }
-
private boolean isIdpAlreadyConfigured(@NonNull String providerId) {
for (IdpConfig config : mProviders) {
if (config.getProviderId().equals(providerId)) {
@@ -639,5 +620,19 @@ private boolean isIdpAlreadyConfigured(@NonNull String providerId) {
}
return false;
}
+
+ public Intent build() {
+ return KickoffActivity.createIntent(mApp.getApplicationContext(), getFlowParams());
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ public FlowParameters getFlowParams() {
+ return new FlowParameters(mApp.getName(),
+ new ArrayList<>(mProviders),
+ mTheme,
+ mLogo,
+ mTosUrl,
+ mIsSmartLockEnabled);
+ }
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/KickoffActivity.java b/auth/src/main/java/com/firebase/ui/auth/KickoffActivity.java
new file mode 100644
index 000000000..d09fd514b
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/KickoffActivity.java
@@ -0,0 +1,41 @@
+package com.firebase.ui.auth;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.firebase.ui.auth.ui.ActivityHelper;
+import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.ExtraConstants;
+import com.firebase.ui.auth.ui.FlowParameters;
+import com.firebase.ui.auth.util.signincontainer.SignInDelegate;
+
+public class KickoffActivity extends AppCompatBase {
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ super.onCreate(savedInstance);
+ if (savedInstance == null) {
+ SignInDelegate.delegate(this, mActivityHelper.getFlowParams());
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ // It doesn't matter what we put here, we just don't want outState to be empty
+ outState.putBoolean(ExtraConstants.HAS_EXISTING_INSTANCE, true);
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ SignInDelegate delegate = SignInDelegate.getInstance(this);
+ if (delegate != null) {
+ delegate.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ public static Intent createIntent(Context context, FlowParameters flowParams) {
+ return ActivityHelper.createBaseIntent(context, KickoffActivity.class, flowParams);
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/AuthCredentialHelper.java b/auth/src/main/java/com/firebase/ui/auth/provider/AuthCredentialHelper.java
similarity index 88%
rename from auth/src/main/java/com/firebase/ui/auth/ui/AuthCredentialHelper.java
rename to auth/src/main/java/com/firebase/ui/auth/provider/AuthCredentialHelper.java
index c60568e2c..d65af6450 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/AuthCredentialHelper.java
+++ b/auth/src/main/java/com/firebase/ui/auth/provider/AuthCredentialHelper.java
@@ -12,14 +12,11 @@
* limitations under the License.
*/
-package com.firebase.ui.auth.ui;
+package com.firebase.ui.auth.provider;
import android.support.annotation.Nullable;
-import com.firebase.ui.auth.provider.FacebookProvider;
-import com.firebase.ui.auth.provider.GoogleProvider;
import com.firebase.ui.auth.IdpResponse;
-import com.firebase.ui.auth.provider.TwitterProvider;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.GoogleAuthProvider;
diff --git a/auth/src/main/java/com/firebase/ui/auth/provider/GoogleProvider.java b/auth/src/main/java/com/firebase/ui/auth/provider/GoogleProvider.java
index 4acbfe8fb..3ddc5d08b 100644
--- a/auth/src/main/java/com/firebase/ui/auth/provider/GoogleProvider.java
+++ b/auth/src/main/java/com/firebase/ui/auth/provider/GoogleProvider.java
@@ -29,6 +29,7 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.R;
+import com.firebase.ui.auth.util.GoogleApiConstants;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
@@ -43,7 +44,6 @@ public class GoogleProvider implements
IdpProvider, OnClickListener, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "GoogleProvider";
- private static final int AUTO_MANAGE_ID = 1;
private static final int RC_SIGN_IN = 20;
private static final String ERROR_KEY = "error";
private GoogleApiClient mGoogleApiClient;
@@ -56,12 +56,12 @@ public GoogleProvider(FragmentActivity activity, IdpConfig idpConfig) {
public GoogleProvider(FragmentActivity activity, IdpConfig idpConfig, @Nullable String email) {
mActivity = activity;
- String mClientId = activity.getString(R.string.default_web_client_id);
+ String clientId = activity.getString(R.string.default_web_client_id);
GoogleSignInOptions.Builder builder =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
- .requestIdToken(mClientId);
+ .requestIdToken(clientId);
if (activity.getResources().getIdentifier(
"google_permissions", "array", activity.getPackageName()) != 0) {
@@ -80,7 +80,7 @@ public GoogleProvider(FragmentActivity activity, IdpConfig idpConfig, @Nullable
}
mGoogleApiClient = new GoogleApiClient.Builder(activity)
- .enableAutoManage(activity, AUTO_MANAGE_ID, this)
+ .enableAutoManage(activity, GoogleApiConstants.AUTO_MANAGE_ID0, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, builder.build())
.build();
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/ActivityBase.java b/auth/src/main/java/com/firebase/ui/auth/ui/ActivityBase.java
deleted file mode 100644
index ccad5f1a1..000000000
--- a/auth/src/main/java/com/firebase/ui/auth/ui/ActivityBase.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2016 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.firebase.ui.auth.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class ActivityBase extends Activity {
- protected ActivityHelper mActivityHelper;
-
- @Override
- protected void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
- mActivityHelper = new ActivityHelper(this, getIntent());
- mActivityHelper.configureTheme();
- }
-
- public void finish(int resultCode, Intent intent) {
- mActivityHelper.finish(resultCode, intent);
- }
-}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/ActivityHelper.java b/auth/src/main/java/com/firebase/ui/auth/ui/ActivityHelper.java
index 13c491eb2..f3b9c9cf8 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/ActivityHelper.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/ActivityHelper.java
@@ -14,57 +14,19 @@
package com.firebase.ui.auth.ui;
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import com.firebase.ui.auth.IdpResponse;
-import com.firebase.ui.auth.util.SmartLock;
-import com.google.android.gms.auth.api.Auth;
-import com.google.android.gms.auth.api.credentials.CredentialsApi;
-import com.google.firebase.FirebaseApp;
-import com.google.firebase.auth.FirebaseAuth;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.firebase.auth.FirebaseUser;
-import static android.app.Activity.RESULT_OK;
-import static com.firebase.ui.auth.util.Preconditions.checkNotNull;
+public class ActivityHelper extends BaseHelper {
+ private AppCompatBase mActivity;
-public class ActivityHelper {
- private ProgressDialog mProgressDialog;
- private Activity mActivity;
- private final FlowParameters mFlowParams;
-
- public ActivityHelper(Activity activity, Intent intent) {
+ public ActivityHelper(AppCompatBase activity, Intent intent) {
+ super(activity, (FlowParameters) intent.getParcelableExtra(ExtraConstants.EXTRA_FLOW_PARAMS));
mActivity = activity;
- mFlowParams = intent.getParcelableExtra(ExtraConstants.EXTRA_FLOW_PARAMS);
- }
-
- public void configureTheme() {
- mActivity.setTheme(mFlowParams.themeId);
- }
-
- public void dismissDialog() {
- if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
- mProgressDialog = null;
- }
- }
-
- public FlowParameters getFlowParams() {
- return mFlowParams;
- }
-
- public void showLoadingDialog(String message) {
- dismissDialog();
- mProgressDialog = ProgressDialog.show(mActivity, "", message, true);
- }
-
- public void showLoadingDialog(@StringRes int stringResource) {
- showLoadingDialog(mActivity.getString(stringResource));
}
public void startActivityForResult(Intent intent, int requestCode) {
@@ -72,80 +34,17 @@ public void startActivityForResult(Intent intent, int requestCode) {
}
public void finish(int resultCode, Intent intent) {
- mActivity.setResult(resultCode, intent);
- mActivity.finish();
- }
-
- public Context getApplicationContext() {
- return mActivity.getApplicationContext();
- }
-
- public String getAppName() {
- return mFlowParams.appName;
- }
-
- public FirebaseApp getFirebaseApp() {
- return FirebaseApp.getInstance(mFlowParams.appName);
- }
-
- public FirebaseAuth getFirebaseAuth() {
- return FirebaseAuth.getInstance(getFirebaseApp());
- }
-
- public CredentialsApi getCredentialsApi() {
- return Auth.CredentialsApi;
- }
-
- public FirebaseUser getCurrentUser() {
- return getFirebaseAuth().getCurrentUser();
- }
-
- public static Intent createBaseIntent(
- @NonNull Context context,
- @NonNull Class extends Activity> target,
- @NonNull FlowParameters flowParams) {
- return new Intent(
- checkNotNull(context, "context cannot be null"),
- checkNotNull(target, "target activity cannot be null"))
- .putExtra(ExtraConstants.EXTRA_FLOW_PARAMS,
- checkNotNull(flowParams, "flowParams cannot be null"));
- }
-
- public SmartLock getSmartLockInstance(AppCompatBase activity, String tag) {
- return SmartLock.getInstance(activity, tag);
+ finishActivity(mActivity, resultCode, intent);
}
- public void saveCredentialsOrFinish(
- @Nullable SmartLock smartLock,
- AppCompatBase activity,
- FirebaseUser firebaseUser,
- @NonNull IdpResponse response) {
- saveCredentialsOrFinish(smartLock, activity, firebaseUser, null, response);
+ public SaveSmartLock getSaveSmartLockInstance() {
+ return getSaveSmartLockInstance(mActivity);
}
public void saveCredentialsOrFinish(
- @Nullable SmartLock smartLock,
- AppCompatBase activity,
+ @Nullable SaveSmartLock saveSmartLock,
FirebaseUser firebaseUser,
@NonNull String password) {
- saveCredentialsOrFinish(smartLock, activity, firebaseUser, password, null);
- }
-
- private void saveCredentialsOrFinish(
- @Nullable SmartLock smartLock,
- AppCompatBase activity,
- FirebaseUser firebaseUser,
- @Nullable String password,
- @Nullable IdpResponse response) {
- if (smartLock == null) {
- activity.finish(RESULT_OK, new Intent());
- } else {
- smartLock.saveCredentialsOrFinish(
- activity,
- this,
- firebaseUser,
- password,
- response);
- }
+ saveCredentialsOrFinish(saveSmartLock, mActivity, firebaseUser, password, null);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/BaseDialog.java b/auth/src/main/java/com/firebase/ui/auth/ui/BaseDialog.java
new file mode 100644
index 000000000..a28aedd20
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/BaseDialog.java
@@ -0,0 +1,26 @@
+package com.firebase.ui.auth.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.DialogFragment;
+
+public class BaseDialog extends DialogFragment {
+ protected FragmentHelper mHelper;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mHelper = new FragmentHelper(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mHelper.dismissDialog();
+ }
+
+ public void finish(int resultCode, Intent resultIntent) {
+ mHelper.finish(resultCode, resultIntent);
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/BaseFragment.java b/auth/src/main/java/com/firebase/ui/auth/ui/BaseFragment.java
new file mode 100644
index 000000000..eb3bd4541
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/BaseFragment.java
@@ -0,0 +1,26 @@
+package com.firebase.ui.auth.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+
+public class BaseFragment extends Fragment {
+ protected FragmentHelper mHelper;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mHelper = new FragmentHelper(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mHelper.dismissDialog();
+ }
+
+ public void finish(int resultCode, Intent resultIntent) {
+ mHelper.finish(resultCode, resultIntent);
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/BaseHelper.java b/auth/src/main/java/com/firebase/ui/auth/ui/BaseHelper.java
new file mode 100644
index 000000000..c2d53be7a
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/BaseHelper.java
@@ -0,0 +1,128 @@
+package com.firebase.ui.auth.ui;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.v4.app.FragmentActivity;
+
+import com.firebase.ui.auth.IdpResponse;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
+import com.google.android.gms.auth.api.Auth;
+import com.google.android.gms.auth.api.credentials.CredentialsApi;
+import com.google.firebase.FirebaseApp;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+
+import static android.app.Activity.RESULT_OK;
+import static com.firebase.ui.auth.util.Preconditions.checkNotNull;
+
+public class BaseHelper {
+ protected Context mContext;
+ private final FlowParameters mFlowParams;
+ private ProgressDialog mProgressDialog;
+
+ public BaseHelper(Context context, FlowParameters parameters) {
+ mContext = context;
+ mFlowParams = parameters;
+ }
+
+ public void configureTheme() {
+ mContext.setTheme(mFlowParams.themeId);
+ }
+
+ public FlowParameters getFlowParams() {
+ return mFlowParams;
+ }
+
+ public void finishActivity(Activity activity, int resultCode, Intent intent) {
+ activity.setResult(resultCode, intent);
+ activity.finish();
+ }
+
+ public void showLoadingDialog(String message) {
+ dismissDialog();
+ mProgressDialog = ProgressDialog.show(mContext, "", message, true);
+ }
+
+ public void showLoadingDialog(@StringRes int stringResource) {
+ showLoadingDialog(mContext.getString(stringResource));
+ }
+
+ public void dismissDialog() {
+ if (mProgressDialog != null) {
+ mProgressDialog.dismiss();
+ mProgressDialog = null;
+ }
+ }
+
+ public boolean isProgressDialogShowing() {
+ return mProgressDialog != null && mProgressDialog.isShowing();
+ }
+
+ public Context getApplicationContext() {
+ return mContext.getApplicationContext();
+ }
+
+ public String getAppName() {
+ return mFlowParams.appName;
+ }
+
+ public FirebaseApp getFirebaseApp() {
+ return FirebaseApp.getInstance(mFlowParams.appName);
+ }
+
+ public FirebaseAuth getFirebaseAuth() {
+ return FirebaseAuth.getInstance(getFirebaseApp());
+ }
+
+ public CredentialsApi getCredentialsApi() {
+ return Auth.CredentialsApi;
+ }
+
+ public FirebaseUser getCurrentUser() {
+ return getFirebaseAuth().getCurrentUser();
+ }
+
+ public static Intent createBaseIntent(
+ @NonNull Context context,
+ @NonNull Class extends Activity> target,
+ @NonNull FlowParameters flowParams) {
+ return new Intent(
+ checkNotNull(context, "context cannot be null"),
+ checkNotNull(target, "target activity cannot be null"))
+ .putExtra(ExtraConstants.EXTRA_FLOW_PARAMS,
+ checkNotNull(flowParams, "flowParams cannot be null"));
+ }
+
+ public SaveSmartLock getSaveSmartLockInstance(FragmentActivity activity) {
+ return SaveSmartLock.getInstance(activity, getFlowParams());
+ }
+
+ public void saveCredentialsOrFinish(
+ @Nullable SaveSmartLock saveSmartLock,
+ Activity activity,
+ FirebaseUser firebaseUser,
+ @NonNull IdpResponse response) {
+ saveCredentialsOrFinish(saveSmartLock, activity, firebaseUser, null, response);
+ }
+
+ public void saveCredentialsOrFinish(
+ @Nullable SaveSmartLock saveSmartLock,
+ Activity activity,
+ FirebaseUser firebaseUser,
+ @Nullable String password,
+ @Nullable IdpResponse response) {
+ if (saveSmartLock == null) {
+ finishActivity(activity, RESULT_OK, new Intent());
+ } else {
+ saveSmartLock.saveCredentialsOrFinish(
+ firebaseUser,
+ password,
+ response);
+ }
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/ChooseAccountActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/ChooseAccountActivity.java
deleted file mode 100644
index 73af3dcbf..000000000
--- a/auth/src/main/java/com/firebase/ui/auth/ui/ChooseAccountActivity.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright 2016 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.firebase.ui.auth.ui;
-
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.firebase.ui.auth.AuthUI.IdpConfig;
-import com.firebase.ui.auth.BuildConfig;
-import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
-import com.firebase.ui.auth.ui.idp.IdpSignInContainerActivity;
-import com.firebase.ui.auth.util.CredentialsAPI;
-import com.firebase.ui.auth.util.CredentialsApiHelper;
-import com.firebase.ui.auth.util.EmailFlowUtil;
-import com.firebase.ui.auth.util.PlayServicesHelper;
-import com.google.android.gms.auth.api.credentials.Credential;
-import com.google.android.gms.auth.api.credentials.CredentialsApi;
-import com.google.android.gms.auth.api.credentials.IdentityProviders;
-import com.google.android.gms.common.api.Status;
-import com.google.android.gms.tasks.OnCompleteListener;
-import com.google.android.gms.tasks.OnFailureListener;
-import com.google.android.gms.tasks.OnSuccessListener;
-import com.google.android.gms.tasks.Task;
-import com.google.firebase.auth.AuthResult;
-import com.google.firebase.auth.EmailAuthProvider;
-import com.google.firebase.auth.FacebookAuthProvider;
-import com.google.firebase.auth.FirebaseAuthInvalidUserException;
-import com.google.firebase.auth.GoogleAuthProvider;
-import com.google.firebase.auth.TwitterAuthProvider;
-
-import java.util.List;
-
-import static com.firebase.ui.auth.ui.ResultCodes.RESULT_NO_NETWORK;
-
-/**
- * Attempts to acquire a credential from Smart Lock for Passwords to sign in
- * an existing account. If this succeeds, an attempt is made to sign the user in
- * with this credential. If it does not, the
- * {@link AuthMethodPickerActivity authentication method picker activity}
- * is started, unless only email is supported, in which case the
- * {@link com.firebase.ui.auth.ui.email.SignInNoPasswordActivity email sign-in flow}
- * is started.
- */
-public class ChooseAccountActivity extends ActivityBase {
- private static final String TAG = "ChooseAccountActivity";
-
- private static final int RC_CREDENTIALS_READ = 2;
- private static final int RC_IDP_SIGNIN = 3;
- private static final int RC_AUTH_METHOD_PICKER = 4;
- private static final int RC_EMAIL_FLOW = 5;
- private static final int RC_PLAY_SERVICES = 6;
-
- private CredentialsAPI mCredentialsApi;
- private PlayServicesHelper mPlayServicesHelper;
-
- @Override
- protected void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
-
- if (!hasNetworkConnection()) {
- Log.d(TAG, "No network connection");
- finish(RESULT_NO_NETWORK, new Intent());
- return;
- }
-
- // Make Google Play Services available at the correct version, if possible
- mPlayServicesHelper = PlayServicesHelper.getInstance(this);
- boolean madeAvailable = mPlayServicesHelper
- .makePlayServicesAvailable(this, RC_PLAY_SERVICES,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialogInterface) {
- Log.w(TAG, "playServices:dialog.onCancel()");
- finish(RESULT_CANCELED, new Intent());
- }
- });
-
- if (!madeAvailable) {
- Log.w(TAG, "playServices: could not make available.");
- finish(RESULT_CANCELED, new Intent());
- return;
- }
-
- mCredentialsApi = new CredentialsAPI(this, new CredentialsAPI.CallbackInterface() {
- @Override
- public void onAsyncTaskFinished() {
- onCredentialsApiConnected(mCredentialsApi, mActivityHelper);
- }
- });
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- if (mCredentialsApi != null) {
- mCredentialsApi.onStart();
- }
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (mCredentialsApi != null) {
- mCredentialsApi.onStop();
- }
- }
-
- /**
- * Check if there is an active or soon-to-be-active network connection.
- */
- private boolean hasNetworkConnection() {
- ConnectivityManager manager =
- (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
-
- return manager != null
- && manager.getActiveNetworkInfo() != null
- && manager.getActiveNetworkInfo().isConnectedOrConnecting();
- }
-
- /**
- * Called when the Credentials API connects.
- */
- public void onCredentialsApiConnected(
- CredentialsAPI credentialsApi,
- ActivityHelper activityHelper) {
- String email = credentialsApi.getEmailFromCredential();
- String password = credentialsApi.getPasswordFromCredential();
- String accountType = credentialsApi.getAccountTypeFromCredential();
-
- FlowParameters flowParams = activityHelper.getFlowParams();
-
- if (flowParams.smartLockEnabled
- && mPlayServicesHelper.isPlayServicesAvailable()
- && credentialsApi.isCredentialsAvailable()) {
-
- // Attempt auto-sign in using SmartLock
- if (credentialsApi.isAutoSignInAvailable()) {
- credentialsApi.googleSilentSignIn();
- if (!TextUtils.isEmpty(password)) {
- // Sign in with the email/password retrieved from SmartLock
- signInWithEmailAndPassword(activityHelper, email, password);
- } else {
- // log in with id/provider
- redirectToIdpSignIn(email, accountType);
- }
- } else if (credentialsApi.isSignInResolutionNeeded()) {
- // resolve credential
- credentialsApi.resolveSavedEmails(this);
- } else {
- startAuthMethodChoice(activityHelper);
- }
- } else {
- startAuthMethodChoice(activityHelper);
- }
- }
-
- private void startAuthMethodChoice(ActivityHelper activityHelper) {
- List idpConfigs = activityHelper.getFlowParams().providerInfo;
-
- // If the only provider is Email, immediately launch the email flow. Otherwise, launch
- // the auth method picker screen.
- if (idpConfigs.size() == 1
- && idpConfigs.get(0).getProviderId().equals(EmailAuthProvider.PROVIDER_ID)) {
- startActivityForResult(
- EmailFlowUtil.createIntent(
- this,
- activityHelper.getFlowParams()),
- RC_EMAIL_FLOW);
- } else {
- startActivityForResult(
- AuthMethodPickerActivity.createIntent(
- this,
- activityHelper.getFlowParams()),
- RC_AUTH_METHOD_PICKER);
- }
- }
-
- private void logInWithCredential(
- final String email,
- final String password,
- final String accountType) {
-
- if (email != null
- && mCredentialsApi.isCredentialsAvailable()
- && !mCredentialsApi.isSignInResolutionNeeded()) {
- if (password != null && !password.isEmpty()) {
- // email/password combination
- signInWithEmailAndPassword(mActivityHelper, email, password);
- } else {
- // identifier/provider combination
- redirectToIdpSignIn(email, accountType);
- }
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
- }
-
- switch (requestCode) {
- case RC_CREDENTIALS_READ:
- if (resultCode == RESULT_OK) {
- // credential selected from SmartLock, log in with that credential
- Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
- mCredentialsApi.handleCredential(credential);
- mCredentialsApi.resolveSignIn();
- logInWithCredential(
- mCredentialsApi.getEmailFromCredential(),
- mCredentialsApi.getPasswordFromCredential(),
- mCredentialsApi.getAccountTypeFromCredential()
- );
- } else if (resultCode == RESULT_CANCELED
- || resultCode == CredentialsApi.ACTIVITY_RESULT_OTHER_ACCOUNT) {
- // Smart lock selector cancelled, go to the AuthMethodPicker screen
- startAuthMethodChoice(mActivityHelper);
- } else if (resultCode == RESULT_FIRST_USER) {
- // TODO: (serikb) figure out flow
- }
- break;
- case RC_IDP_SIGNIN:
- case RC_AUTH_METHOD_PICKER:
- case RC_EMAIL_FLOW:
- finish(resultCode, data);
- break;
- case RC_PLAY_SERVICES:
- if (resultCode != RESULT_OK) {
- finish(resultCode, new Intent());
- }
- break;
- }
- }
-
- /**
- * Begin sign in process with email and password from a SmartLock credential.
- * On success, finish with {@link #RESULT_OK}.
- * On failure, delete the credential from SmartLock (if applicable) and then launch the
- * auth method picker flow.
- */
- private void signInWithEmailAndPassword(ActivityHelper helper, String email, String password) {
- helper.getFirebaseAuth()
- .signInWithEmailAndPassword(email, password)
- .addOnFailureListener(new TaskFailureLogger(
- TAG, "Error signing in with email and password"))
- .addOnSuccessListener(new OnSuccessListener() {
- @Override
- public void onSuccess(AuthResult authResult) {
- finish(RESULT_OK, new Intent());
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(@NonNull Exception e) {
- if (e instanceof FirebaseAuthInvalidUserException) {
- // In this case the credential saved in SmartLock was not
- // a valid credential, we should delete it from SmartLock
- // before continuing.
- deleteCredentialAndRedirect();
- } else {
- startAuthMethodChoice(mActivityHelper);
- }
- }
- });
- }
-
- /**
- * Delete the last credential retrieved from SmartLock and then redirect to the
- * auth method choice flow.
- */
- private void deleteCredentialAndRedirect() {
- if (mCredentialsApi.getCredential() == null) {
- Log.w(TAG, "deleteCredentialAndRedirect: null credential");
- startAuthMethodChoice(mActivityHelper);
- return;
- }
-
- CredentialsApiHelper credentialsApiHelper = CredentialsApiHelper.getInstance(this);
- credentialsApiHelper.delete(mCredentialsApi.getCredential())
- .addOnCompleteListener(this, new OnCompleteListener() {
- @Override
- public void onComplete(@NonNull Task task) {
- if (!task.isSuccessful()) {
- Log.w(TAG, "deleteCredential:failure", task.getException());
- }
- startAuthMethodChoice(mActivityHelper);
- }
- });
- }
-
- protected void redirectToIdpSignIn(String email, String accountType) {
- Intent nextIntent;
- switch (accountType) {
- case IdentityProviders.GOOGLE:
- nextIntent = IdpSignInContainerActivity.createIntent(
- this,
- mActivityHelper.getFlowParams(),
- GoogleAuthProvider.PROVIDER_ID,
- email);
- break;
- case IdentityProviders.FACEBOOK:
- nextIntent = IdpSignInContainerActivity.createIntent(
- this,
- mActivityHelper.getFlowParams(),
- FacebookAuthProvider.PROVIDER_ID,
- email);
- break;
- case IdentityProviders.TWITTER:
- nextIntent = IdpSignInContainerActivity.createIntent(
- this,
- mActivityHelper.getFlowParams(),
- TwitterAuthProvider.PROVIDER_ID,
- email);
- break;
- default:
- Log.w(TAG, "unknown provider: " + accountType);
- nextIntent = AuthMethodPickerActivity.createIntent(
- this,
- mActivityHelper.getFlowParams());
- }
- this.startActivityForResult(nextIntent, RC_IDP_SIGNIN);
- }
-
- public static Intent createIntent(
- Context context,
- FlowParameters flowParams) {
- return ActivityHelper.createBaseIntent(context, ChooseAccountActivity.class, flowParams);
- }
-}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/ExtraConstants.java b/auth/src/main/java/com/firebase/ui/auth/ui/ExtraConstants.java
index d79df3a51..6d144eed1 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/ExtraConstants.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/ExtraConstants.java
@@ -23,4 +23,5 @@ public class ExtraConstants {
public static final String EXTRA_FLOW_PARAMS = "extra_flow_params";
public static final String EXTRA_IDP_RESPONSE = "extra_idp_response";
public static final String EXTRA_PROVIDER = "extra_provider";
+ public static final String HAS_EXISTING_INSTANCE = "has_existing_instance";
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/FragmentHelper.java b/auth/src/main/java/com/firebase/ui/auth/ui/FragmentHelper.java
new file mode 100644
index 000000000..6868b38af
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/FragmentHelper.java
@@ -0,0 +1,31 @@
+package com.firebase.ui.auth.ui;
+
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+public class FragmentHelper extends BaseHelper {
+ private Fragment mFragment;
+
+ public FragmentHelper(Fragment fragment) {
+ super(fragment.getContext(), (FlowParameters) fragment.getArguments()
+ .getParcelable(ExtraConstants.EXTRA_FLOW_PARAMS));
+ mFragment = fragment;
+ }
+
+ public void finish(int resultCode, Intent intent) {
+ finishActivity(mFragment.getActivity(), resultCode, intent);
+ }
+
+ public static Bundle getFlowParamsBundle(FlowParameters params) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(ExtraConstants.EXTRA_FLOW_PARAMS, params);
+ return bundle;
+ }
+
+ public void startIntentSenderForResult(IntentSender sender, int requestCode)
+ throws IntentSender.SendIntentException {
+ mFragment.startIntentSenderForResult(sender, requestCode, null, 0, 0, 0, null);
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackIdpPrompt.java b/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackIdpPrompt.java
index 99c8205a7..1ee5564eb 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackIdpPrompt.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackIdpPrompt.java
@@ -28,14 +28,14 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.R;
+import com.firebase.ui.auth.provider.AuthCredentialHelper;
import com.firebase.ui.auth.provider.FacebookProvider;
import com.firebase.ui.auth.provider.GoogleProvider;
import com.firebase.ui.auth.provider.IdpProvider;
import com.firebase.ui.auth.provider.IdpProvider.IdpCallback;
import com.firebase.ui.auth.provider.TwitterProvider;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
-import com.firebase.ui.auth.ui.AuthCredentialHelper;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
@@ -176,7 +176,6 @@ public void onComplete(@NonNull Task task) {
TAG, "Error signing in with previous credential"))
.addOnCompleteListener(new FinishListener(newIdpResponse));
} else {
- mActivityHelper.dismissDialog();
finish(Activity.RESULT_OK, new Intent().putExtra(
ExtraConstants.EXTRA_IDP_RESPONSE, newIdpResponse));
}
@@ -198,7 +197,7 @@ public static Intent createIntent(
String providerId,
IdpResponse idpResponse,
String email) {
- return ActivityHelper.createBaseIntent(context, WelcomeBackIdpPrompt.class, flowParams)
+ return BaseHelper.createBaseIntent(context, WelcomeBackIdpPrompt.class, flowParams)
.putExtra(ExtraConstants.EXTRA_PROVIDER, providerId)
.putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, idpResponse)
.putExtra(ExtraConstants.EXTRA_EMAIL, email);
@@ -212,7 +211,6 @@ private class FinishListener implements OnCompleteListener {
}
public void onComplete(@NonNull Task task) {
- mActivityHelper.dismissDialog();
finish(Activity.RESULT_OK,
new Intent().putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, mIdpResponse));
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackPasswordPrompt.java b/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackPasswordPrompt.java
index f4bce28be..655b420c8 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackPasswordPrompt.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackPasswordPrompt.java
@@ -31,15 +31,15 @@
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
+import com.firebase.ui.auth.provider.AuthCredentialHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
-import com.firebase.ui.auth.ui.AuthCredentialHelper;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
import com.firebase.ui.auth.ui.email.PasswordToggler;
import com.firebase.ui.auth.ui.email.RecoverPasswordActivity;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthCredential;
@@ -58,14 +58,13 @@ public class WelcomeBackPasswordPrompt extends AppCompatBase implements View.OnC
private TextInputLayout mPasswordLayout;
private EditText mPasswordField;
private IdpResponse mIdpResponse;
- @Nullable
- private SmartLock mSmartLock;
+ @Nullable private SaveSmartLock mSaveSmartLock;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome_back_password_prompt_layout);
- mSmartLock = SmartLock.getInstance(WelcomeBackPasswordPrompt.this, TAG);
+ mSaveSmartLock = mActivityHelper.getSaveSmartLockInstance();
mPasswordLayout = (TextInputLayout) findViewById(R.id.password_layout);
mPasswordField = (EditText) findViewById(R.id.password);
@@ -83,8 +82,6 @@ protected void onCreate(Bundle savedInstanceState) {
TextView bodyTextView = ((TextView) findViewById(R.id.welcome_back_password_body));
bodyTextView.setText(spannableStringBuilder);
- ((TextInputLayout) findViewById(R.id.password_layout)).setPasswordVisibilityToggleEnabled(false);
-
// Click listeners
findViewById(R.id.button_done).setOnClickListener(this);
findViewById(R.id.toggle_visibility).setOnClickListener(new PasswordToggler(mPasswordField));
@@ -98,7 +95,6 @@ public void onClick(View view) {
mActivityHelper.showLoadingDialog(R.string.progress_dialog_signing_in);
next(mEmail, mPasswordField.getText().toString());
} else if (id == R.id.trouble_signing_in) {
- mActivityHelper.dismissDialog();
startActivity(RecoverPasswordActivity.createIntent(
getApplicationContext(),
mActivityHelper.getFlowParams(),
@@ -141,8 +137,7 @@ public void onSuccess(AuthResult authResult) {
@Override
public void onSuccess(AuthResult authResult) {
mActivityHelper.saveCredentialsOrFinish(
- mSmartLock,
- WelcomeBackPasswordPrompt.this,
+ mSaveSmartLock,
authResult.getUser(),
password);
}
@@ -163,7 +158,7 @@ public static Intent createIntent(
Context context,
FlowParameters flowParams,
IdpResponse response) {
- return ActivityHelper.createBaseIntent(context, WelcomeBackPasswordPrompt.class, flowParams)
+ return BaseHelper.createBaseIntent(context, WelcomeBackPasswordPrompt.class, flowParams)
.putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, response);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/AcquireEmailHelper.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/AcquireEmailHelper.java
index ae0bec73d..a46bf8aa9 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/AcquireEmailHelper.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/AcquireEmailHelper.java
@@ -16,6 +16,7 @@
import android.content.Intent;
import android.support.annotation.NonNull;
+import android.text.TextUtils;
import com.firebase.ui.auth.R;
import com.firebase.ui.auth.ui.ActivityHelper;
@@ -50,7 +51,7 @@ public AcquireEmailHelper(ActivityHelper activityHelper) {
public void checkAccountExists(final String email) {
FirebaseAuth firebaseAuth = mActivityHelper.getFirebaseAuth();
mActivityHelper.showLoadingDialog(R.string.progress_dialog_loading);
- if (email != null && !email.isEmpty()) {
+ if (!TextUtils.isEmpty(email)) {
firebaseAuth
.fetchProvidersForEmail(email)
.addOnFailureListener(
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/ConfirmRecoverPasswordActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/ConfirmRecoverPasswordActivity.java
deleted file mode 100644
index bf6923705..000000000
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/ConfirmRecoverPasswordActivity.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2016 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.firebase.ui.auth.ui.email;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.TextView;
-
-import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
-import com.firebase.ui.auth.ui.ExtraConstants;
-import com.firebase.ui.auth.ui.FlowParameters;
-
-/**
- * Dialog activity to confirm successful email sending in {@link RecoverPasswordActivity}.
- */
-public class ConfirmRecoverPasswordActivity extends AppCompatActivity
- implements View.OnClickListener {
-
- private ActivityHelper mActivityHelper;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mActivityHelper = new ActivityHelper(this, getIntent());
- // intentionally do not configure the theme on this activity, it is a dialog
-
- setContentView(R.layout.confirm_recovery_layout);
- String email = getIntent().getStringExtra(ExtraConstants.EXTRA_EMAIL);
-
- String text = String.format(
- getResources().getString(R.string.confirm_recovery_body),
- email);
- ((TextView) findViewById(R.id.body_text)).setText(text);
-
- findViewById(R.id.button_done).setOnClickListener(this);
- }
-
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.button_done) {
- finish(RESULT_OK, new Intent());
- }
- }
-
- public static Intent createIntent(
- Context context,
- FlowParameters flowParams,
- String email) {
- return ActivityHelper.createBaseIntent(context,
- ConfirmRecoverPasswordActivity.class,
- flowParams)
- .putExtra(ExtraConstants.EXTRA_EMAIL, email);
- }
-
- private void finish(int resultCode, Intent intent) {
- mActivityHelper.finish(resultCode, intent);
- }
-}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/EmailHintContainerActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/EmailHintContainerActivity.java
index ce31a5462..4ce1ea1bd 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/EmailHintContainerActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/EmailHintContainerActivity.java
@@ -19,11 +19,10 @@
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
-
import android.util.Log;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.util.FirebaseAuthWrapper;
import com.firebase.ui.auth.util.FirebaseAuthWrapperFactory;
@@ -77,7 +76,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
public static Intent createIntent(
Context context,
FlowParameters flowParams) {
- return ActivityHelper.createBaseIntent(
+ return BaseHelper.createBaseIntent(
context,
EmailHintContainerActivity.class,
flowParams);
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoverPasswordActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoverPasswordActivity.java
index 5979d0a0d..f7e04cf75 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoverPasswordActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoverPasswordActivity.java
@@ -23,8 +23,8 @@
import android.widget.EditText;
import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
@@ -39,7 +39,6 @@
*/
public class RecoverPasswordActivity extends AppCompatBase implements View.OnClickListener {
private static final String TAG = "RecoverPasswordActivity";
- private static final int RC_CONFIRM = 3;
private EditText mEmailEditText;
private EmailFieldValidator mEmailFieldValidator;
@@ -70,12 +69,7 @@ private void next(final String email) {
@Override
public void onSuccess(Void aVoid) {
mActivityHelper.dismissDialog();
-
- Intent confirmIntent = ConfirmRecoverPasswordActivity.createIntent(
- RecoverPasswordActivity.this,
- mActivityHelper.getFlowParams(),
- email);
- startActivityForResult(confirmIntent, RC_CONFIRM);
+ RecoveryEmailSentDialog.show(email, getSupportFragmentManager());
}
})
.addOnFailureListener(this, new OnFailureListener() {
@@ -91,12 +85,6 @@ public void onFailure(@NonNull Exception e) {
});
}
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == RC_CONFIRM) {
- finish(RESULT_OK, new Intent());
- }
- }
-
@Override
public void onClick(View view) {
@@ -110,7 +98,7 @@ public void onClick(View view) {
}
public static Intent createIntent(Context context, FlowParameters flowParams, String email) {
- return ActivityHelper.createBaseIntent(context, RecoverPasswordActivity.class, flowParams)
+ return BaseHelper.createBaseIntent(context, RecoverPasswordActivity.class, flowParams)
.putExtra(ExtraConstants.EXTRA_EMAIL, email);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoveryEmailSentDialog.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoveryEmailSentDialog.java
new file mode 100644
index 000000000..8ea407aee
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/RecoveryEmailSentDialog.java
@@ -0,0 +1,43 @@
+package com.firebase.ui.auth.ui.email;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.app.AlertDialog;
+
+import com.firebase.ui.auth.R;
+import com.firebase.ui.auth.ui.BaseDialog;
+import com.firebase.ui.auth.ui.ExtraConstants;
+
+public class RecoveryEmailSentDialog extends BaseDialog {
+ private static final String TAG = "RecoveryEmailSentDialog";
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getContext(), R.style.FirebaseUI_Dialog)
+ .setTitle(R.string.title_confirm_recover_password_activity)
+ .setMessage(String.format(getString(R.string.confirm_recovery_body),
+ getArguments().getString(ExtraConstants.EXTRA_EMAIL)))
+ .setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface anInterface) {
+ finish(Activity.RESULT_OK, new Intent());
+ }
+ })
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
+ }
+
+ public static void show(String email, FragmentManager manager) {
+ RecoveryEmailSentDialog result = new RecoveryEmailSentDialog();
+ Bundle bundle = new Bundle();
+ bundle.putString(ExtraConstants.EXTRA_EMAIL, email);
+ result.setArguments(bundle);
+ result.show(manager, TAG);
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailActivity.java
index 39231268b..84f85b781 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailActivity.java
@@ -32,15 +32,15 @@
import android.widget.TextView;
import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
import com.firebase.ui.auth.ui.email.field_validators.EmailFieldValidator;
import com.firebase.ui.auth.ui.email.field_validators.PasswordFieldValidator;
import com.firebase.ui.auth.ui.email.field_validators.RequiredFieldValidator;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
@@ -66,14 +66,14 @@ public class RegisterEmailActivity extends AppCompatBase implements View.OnClick
private PasswordFieldValidator mPasswordFieldValidator;
private RequiredFieldValidator mNameValidator;
@Nullable
- private SmartLock mSmartLock;
+ private SaveSmartLock mSaveSmartLock;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register_email_layout);
- mSmartLock = mActivityHelper.getSmartLockInstance(this, TAG);
+ mSaveSmartLock = mActivityHelper.getSaveSmartLockInstance();
String email = getIntent().getStringExtra(ExtraConstants.EXTRA_EMAIL);
mEmailEditText = (EditText) findViewById(R.id.email);
@@ -85,7 +85,6 @@ protected void onCreate(Bundle savedInstanceState) {
getResources().getValue(R.dimen.slightly_visible_icon, slightlyVisibleIcon, true);
mPasswordEditText = (EditText) findViewById(R.id.password);
- ((TextInputLayout) findViewById(R.id.password_layout)).setPasswordVisibilityToggleEnabled(false);
ImageView togglePasswordImage = (ImageView) findViewById(R.id.toggle_visibility);
mPasswordEditText.setOnFocusChangeListener(new ImageFocusTransparencyChanger(
@@ -161,8 +160,7 @@ public void onComplete(@NonNull Task task) {
// the account creation succeeded and we want to save
// the credential to SmartLock (if enabled).
mActivityHelper.saveCredentialsOrFinish(
- mSmartLock,
- RegisterEmailActivity.this,
+ mSaveSmartLock,
firebaseUser,
password);
}
@@ -218,7 +216,7 @@ public static Intent createIntent(
Context context,
FlowParameters flowParams,
String email) {
- return ActivityHelper.createBaseIntent(context, RegisterEmailActivity.class, flowParams)
+ return BaseHelper.createBaseIntent(context, RegisterEmailActivity.class, flowParams)
.putExtra(ExtraConstants.EXTRA_EMAIL, email);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInActivity.java
index 2e07ddfe5..864ece2f8 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInActivity.java
@@ -28,14 +28,14 @@
import android.widget.TextView;
import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
import com.firebase.ui.auth.ui.email.field_validators.EmailFieldValidator;
import com.firebase.ui.auth.ui.email.field_validators.RequiredFieldValidator;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthResult;
@@ -51,14 +51,14 @@ public class SignInActivity extends AppCompatBase implements View.OnClickListene
private EmailFieldValidator mEmailValidator;
private RequiredFieldValidator mPasswordValidator;
@Nullable
- private SmartLock mSmartLock;
+ private SaveSmartLock mSaveSmartLock;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sign_in_layout);
- mSmartLock = mActivityHelper.getSmartLockInstance(this, TAG);
+ mSaveSmartLock = mActivityHelper.getSaveSmartLockInstance();
String email = getIntent().getStringExtra(ExtraConstants.EXTRA_EMAIL);
@@ -71,7 +71,6 @@ protected void onCreate(Bundle savedInstanceState) {
getResources().getValue(R.dimen.slightly_visible_icon, slightlyVisibleIcon, true);
mPasswordEditText = (EditText) findViewById(R.id.password);
- ((TextInputLayout) findViewById(R.id.password_layout)).setPasswordVisibilityToggleEnabled(false);
ImageView togglePasswordImage = (ImageView) findViewById(R.id.toggle_visibility);
mPasswordEditText.setOnFocusChangeListener(new ImageFocusTransparencyChanger(
@@ -103,8 +102,7 @@ private void signIn(final String email, final String password) {
public void onSuccess(AuthResult authResult) {
// Save credential in SmartLock (if enabled)
mActivityHelper.saveCredentialsOrFinish(
- mSmartLock,
- SignInActivity.this,
+ mSaveSmartLock,
authResult.getUser(),
password);
}
@@ -118,7 +116,6 @@ public void onFailure(@NonNull Exception e) {
TextInputLayout passwordInput =
(TextInputLayout) findViewById(R.id.password_layout);
passwordInput.setError(getString(R.string.login_error));
- mActivityHelper.dismissDialog();
}
});
}
@@ -144,7 +141,7 @@ public static Intent createIntent(
Context context,
FlowParameters flowParams,
String email) {
- return ActivityHelper.createBaseIntent(context, SignInActivity.class, flowParams)
+ return BaseHelper.createBaseIntent(context, SignInActivity.class, flowParams)
.putExtra(ExtraConstants.EXTRA_EMAIL, email);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInNoPasswordActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInNoPasswordActivity.java
index 3be643054..66f83c208 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInNoPasswordActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/email/SignInNoPasswordActivity.java
@@ -24,8 +24,8 @@
import android.widget.EditText;
import com.firebase.ui.auth.R;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.email.field_validators.EmailFieldValidator;
@@ -76,7 +76,7 @@ public static Intent createIntent(
Context context,
FlowParameters flowParams,
String email) {
- return ActivityHelper.createBaseIntent(context, SignInNoPasswordActivity.class, flowParams)
+ return BaseHelper.createBaseIntent(context, SignInNoPasswordActivity.class, flowParams)
.putExtra(ExtraConstants.EXTRA_EMAIL, email);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.java b/auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.java
index 2de463aaa..11ca44ce3 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.java
@@ -28,19 +28,19 @@
import com.firebase.ui.auth.BuildConfig;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.R;
+import com.firebase.ui.auth.provider.AuthCredentialHelper;
import com.firebase.ui.auth.provider.FacebookProvider;
import com.firebase.ui.auth.provider.GoogleProvider;
import com.firebase.ui.auth.provider.IdpProvider;
import com.firebase.ui.auth.provider.IdpProvider.IdpCallback;
import com.firebase.ui.auth.provider.TwitterProvider;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.AppCompatBase;
-import com.firebase.ui.auth.ui.AuthCredentialHelper;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.TaskFailureLogger;
import com.firebase.ui.auth.ui.email.EmailHintContainerActivity;
import com.firebase.ui.auth.util.EmailFlowUtil;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
@@ -52,7 +52,7 @@
/**
* Presents the list of authentication options for this app to the user. If an
- * identity provider option is selected, a {@link IdpSignInContainerActivity container activity}
+ * identity provider option is selected, a {@link CredentialSignInHandler}
* is launched to manage the IDP-specific sign-in flow. If email authentication is chosen,
* the {@link EmailHintContainerActivity root email flow activity} is started.
*
@@ -65,15 +65,15 @@ public class AuthMethodPickerActivity extends AppCompatBase
private static final String TAG = "AuthMethodPicker";
private static final int RC_EMAIL_FLOW = 2;
private static final int RC_ACCOUNT_LINK = 3;
+
private ArrayList mIdpProviders;
- @Nullable
- private SmartLock mSmartLock;
+ @Nullable private SaveSmartLock mSaveSmartLock;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.auth_method_picker_layout);
- mSmartLock = mActivityHelper.getSmartLockInstance(this, TAG);
+ mSaveSmartLock = mActivityHelper.getSaveSmartLockInstance();
findViewById(R.id.email_provider).setOnClickListener(this);
populateIdpList(mActivityHelper.getFlowParams().providerInfo);
@@ -173,7 +173,7 @@ public void onSuccess(final IdpResponse response) {
.addOnCompleteListener(new CredentialSignInHandler(
AuthMethodPickerActivity.this,
mActivityHelper,
- mSmartLock,
+ mSaveSmartLock,
RC_ACCOUNT_LINK,
response));
}
@@ -209,6 +209,6 @@ protected void onDestroy() {
public static Intent createIntent(
Context context,
FlowParameters flowParams) {
- return ActivityHelper.createBaseIntent(context, AuthMethodPickerActivity.class, flowParams);
+ return BaseHelper.createBaseIntent(context, AuthMethodPickerActivity.class, flowParams);
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/idp/CredentialSignInHandler.java b/auth/src/main/java/com/firebase/ui/auth/ui/idp/CredentialSignInHandler.java
index bedd21c53..e6404dcc7 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/idp/CredentialSignInHandler.java
+++ b/auth/src/main/java/com/firebase/ui/auth/ui/idp/CredentialSignInHandler.java
@@ -14,17 +14,17 @@
package com.firebase.ui.auth.ui.idp;
+import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.firebase.ui.auth.IdpResponse;
-import com.firebase.ui.auth.ui.ActivityHelper;
-import com.firebase.ui.auth.ui.AppCompatBase;
+import com.firebase.ui.auth.ui.BaseHelper;
import com.firebase.ui.auth.ui.TaskFailureLogger;
import com.firebase.ui.auth.ui.account_link.WelcomeBackIdpPrompt;
import com.firebase.ui.auth.ui.account_link.WelcomeBackPasswordPrompt;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
@@ -39,20 +39,20 @@
public class CredentialSignInHandler implements OnCompleteListener {
private final static String TAG = "CredentialSignInHandler";
- private AppCompatBase mActivity;
- private ActivityHelper mActivityHelper;
- @Nullable private SmartLock mSmartLock;
+ private Activity mActivity;
+ private BaseHelper mHelper;
+ @Nullable private SaveSmartLock mSmartLock;
private IdpResponse mResponse;
private int mAccountLinkResultCode;
public CredentialSignInHandler(
- AppCompatBase activity,
- ActivityHelper activityHelper,
- @Nullable SmartLock smartLock,
+ Activity activity,
+ BaseHelper helper,
+ @Nullable SaveSmartLock smartLock,
int accountLinkResultCode,
IdpResponse response) {
mActivity = activity;
- mActivityHelper = activityHelper;
+ mHelper = helper;
mSmartLock = smartLock;
mResponse = response;
mAccountLinkResultCode = accountLinkResultCode;
@@ -62,7 +62,7 @@ public CredentialSignInHandler(
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
FirebaseUser firebaseUser = task.getResult().getUser();
- mActivityHelper.saveCredentialsOrFinish(
+ mHelper.saveCredentialsOrFinish(
mSmartLock,
mActivity,
firebaseUser,
@@ -70,7 +70,7 @@ public void onComplete(@NonNull Task task) {
} else {
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
final String email = mResponse.getEmail();
- FirebaseAuth firebaseAuth = mActivityHelper.getFirebaseAuth();
+ FirebaseAuth firebaseAuth = mHelper.getFirebaseAuth();
firebaseAuth.fetchProvidersForEmail(email)
.addOnFailureListener(new TaskFailureLogger(
TAG, "Error fetching providers for email"))
@@ -84,7 +84,7 @@ public void onFailure(@NonNull Exception e) {
}
});
} else {
- mActivityHelper.dismissDialog();
+ mHelper.dismissDialog();
Log.e(TAG, "Unexpected exception when signing in with credential",
task.getException());
}
@@ -100,23 +100,23 @@ public StartWelcomeBackFlow(String email) {
@Override
public void onSuccess(@NonNull ProviderQueryResult result) {
- mActivityHelper.dismissDialog();
+ mHelper.dismissDialog();
String provider = result.getProviders().get(0);
if (provider.equals(EmailAuthProvider.PROVIDER_ID)) {
// Start email welcome back flow
mActivity.startActivityForResult(
WelcomeBackPasswordPrompt.createIntent(
- mActivityHelper.getApplicationContext(),
- mActivityHelper.getFlowParams(),
+ mHelper.getApplicationContext(),
+ mHelper.getFlowParams(),
mResponse
), mAccountLinkResultCode);
} else {
// Start IDP welcome back flow
mActivity.startActivityForResult(
WelcomeBackIdpPrompt.createIntent(
- mActivityHelper.getApplicationContext(),
- mActivityHelper.getFlowParams(),
+ mHelper.getApplicationContext(),
+ mHelper.getFlowParams(),
result.getProviders().get(0),
mResponse,
mEmail
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/CredentialsAPI.java b/auth/src/main/java/com/firebase/ui/auth/util/CredentialsAPI.java
deleted file mode 100644
index 8cec9fa25..000000000
--- a/auth/src/main/java/com/firebase/ui/auth/util/CredentialsAPI.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2016 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.firebase.ui.auth.util;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.IntentSender;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
-import android.widget.Toast;
-
-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.auth.api.credentials.IdentityProviders;
-import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
-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.ResultCallback;
-import com.google.android.gms.common.api.Status;
-
-public class CredentialsAPI implements
- GoogleApiClient.ConnectionCallbacks,
- GoogleApiClient.OnConnectionFailedListener {
- private static final int RC_CREDENTIALS_READ = 2;
- private static final String TAG = "CredentialsAPI";
-
- private GoogleApiClient mGoogleApiClient;
- private boolean mAutoSignInAvailable;
- private boolean mSignInResolutionNeeded;
- private Activity mActivity;
- private CredentialRequestResult mCredentialRequestResult;
- private ProgressDialog mProgressDialog;
- private Credential mCredential;
- private final CallbackInterface mCallback;
- private PlayServicesHelper mPlayServicesHelper;
-
- public interface CallbackInterface {
- void onAsyncTaskFinished();
- }
-
- public CredentialsAPI(Activity activity, CallbackInterface callback) {
- mAutoSignInAvailable = false;
- mSignInResolutionNeeded = false;
- mActivity = activity;
- mCallback = callback;
- mPlayServicesHelper = PlayServicesHelper.getInstance(mActivity);
-
- initGoogleApiClient(null);
- requestCredentials(true /* shouldResolve */, false /* onlyPasswords */);
- }
-
- public boolean isPlayServicesAvailable() {
- return mPlayServicesHelper.isPlayServicesAvailable();
- }
-
- public boolean isCredentialsAvailable() {
- // TODO: (serikb) find the way to check if Credentials is available on top of play services
- return true;
- }
-
- public boolean isAutoSignInAvailable() {
- return mAutoSignInAvailable;
- }
-
- public boolean isSignInResolutionNeeded() {
- return mSignInResolutionNeeded;
- }
-
- public void resolveSignIn() {
- mSignInResolutionNeeded = false;
- }
-
- public void resolveSavedEmails(Activity activity) {
- if (mCredentialRequestResult == null || mCredentialRequestResult.getStatus() == null) {
- return;
- }
- Status status = mCredentialRequestResult.getStatus();
- if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
- try {
- status.startResolutionForResult(activity, RC_CREDENTIALS_READ);
- } catch (IntentSender.SendIntentException e) {
- Log.e(TAG, "Failed to send Credentials intent.", e);
- }
- }
- }
-
- public Credential getCredential() {
- return mCredential;
- }
-
- public String getEmailFromCredential() {
- if (mCredential == null) {
- return null;
- }
- return mCredential.getId();
- }
-
- public String getAccountTypeFromCredential() {
- if (mCredential == null) {
- return null;
- }
- return mCredential.getAccountType();
- }
-
- public String getPasswordFromCredential() {
- if (mCredential == null) {
- return null;
- }
- return mCredential.getPassword();
- }
-
- @Override
- public void onConnected(@Nullable Bundle bundle) {}
-
- @Override
- public void onConnectionSuspended(int cause) {}
-
- private void initGoogleApiClient(String accountName) {
- GoogleSignInOptions.Builder gsoBuilder = new GoogleSignInOptions
- .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
- .requestEmail();
-
- if (accountName != null) {
- gsoBuilder.setAccountName(accountName);
- }
-
- GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mActivity)
- .addConnectionCallbacks(this)
- .addApi(Auth.CREDENTIALS_API)
- .addApi(Auth.GOOGLE_SIGN_IN_API, gsoBuilder.build());
-
- mGoogleApiClient = builder.build();
- }
-
- public void googleSilentSignIn() {
- // Try silent sign-in with Google Sign In API
- Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
- }
-
- public void handleCredential(Credential credential) {
- mCredential = credential;
-
- if (IdentityProviders.GOOGLE.equals(credential.getAccountType())) {
- // Google account, rebuild GoogleApiClient to set account name and then try
- initGoogleApiClient(credential.getId());
- googleSilentSignIn();
- } else {
- // Email/password account
- String status = String.format("Signed in as %s", credential.getId());
- Log.d(TAG, status);
- }
- }
-
- public void requestCredentials(final boolean shouldResolve, boolean onlyPasswords) {
- if (!mPlayServicesHelper.isPlayServicesAvailable()) {
- // TODO(samstern): it would probably be better to not actually call the method
- // in this case.
- return;
- }
-
- CredentialRequest.Builder crBuilder = new CredentialRequest.Builder()
- .setPasswordLoginSupported(true);
-
- if (!onlyPasswords) {
- crBuilder.setAccountTypes(
- IdentityProviders.GOOGLE,
- IdentityProviders.TWITTER,
- IdentityProviders.FACEBOOK);
- }
-
- showProgress();
- Auth.CredentialsApi.request(mGoogleApiClient, crBuilder.build())
- .setResultCallback(
- new ResultCallback() {
- @Override
- public void onResult(CredentialRequestResult credentialRequestResult) {
- mCredentialRequestResult = credentialRequestResult;
- Status status = credentialRequestResult.getStatus();
-
- if (status.isSuccess()) {
- // Auto sign-in success
- mAutoSignInAvailable = true;
- handleCredential(credentialRequestResult.getCredential());
- } else if (status.getStatusCode() ==
- CommonStatusCodes.RESOLUTION_REQUIRED && shouldResolve) {
- mSignInResolutionNeeded = true;
- // Getting credential needs to show some UI, start resolution
- }
- hideProgress();
- mCallback.onAsyncTaskFinished();
- }
- });
- }
-
- private void showProgress() {
- if (mProgressDialog == null || !mProgressDialog.isShowing()) {
- mProgressDialog = new ProgressDialog(mActivity);
- mProgressDialog.setIndeterminate(true);
- mProgressDialog.setMessage(
- mActivity.getString(com.firebase.ui.auth.R.string.progress_dialog_loading));
- }
- mProgressDialog.show();
- }
-
- private void hideProgress() {
- if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
- }
- }
-
- public void onStart() {
- if (mGoogleApiClient != null) {
- mGoogleApiClient.connect();
- }
- }
-
- public void onStop() {
- if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
- mGoogleApiClient.disconnect();
- }
-
- hideProgress();
- }
-
- @Override
- public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
- Log.w(TAG, "onConnectionFailed:" + connectionResult);
- Toast.makeText(mActivity, "An error has occurred.", Toast.LENGTH_SHORT).show();
- }
-
- public boolean isGoogleApiClient() {
- return mGoogleApiClient != null;
- }
-
- public GoogleApiClient getGoogleApiClient() {
- return mGoogleApiClient;
- }
-
- public void signOut() {
- disableAutoSignIn();
- Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
- new ResultCallback() {
- @Override
- public void onResult(Status status) {
- mCallback.onAsyncTaskFinished();
- }
- });
- }
-
- public void disableAutoSignIn() {
- Auth.CredentialsApi.disableAutoSignIn(mGoogleApiClient);
- }
-}
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/FirebaseAuthWrapperImpl.java b/auth/src/main/java/com/firebase/ui/auth/util/FirebaseAuthWrapperImpl.java
index 4e09de2f8..6ad48c846 100644
--- a/auth/src/main/java/com/firebase/ui/auth/util/FirebaseAuthWrapperImpl.java
+++ b/auth/src/main/java/com/firebase/ui/auth/util/FirebaseAuthWrapperImpl.java
@@ -160,7 +160,7 @@ public PendingIntent getEmailHintIntent(FragmentActivity fragmentActivity) {
GoogleApiClient client = new GoogleApiClient.Builder(fragmentActivity)
.addConnectionCallbacks(this)
.addApi(Auth.CREDENTIALS_API)
- .enableAutoManage(fragmentActivity, new OnConnectionFailedListener() {
+ .enableAutoManage(fragmentActivity, GoogleApiConstants.AUTO_MANAGE_ID3, new OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e(TAG, "Client connection failed: " + connectionResult.getErrorMessage());
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/GoogleApiConstants.java b/auth/src/main/java/com/firebase/ui/auth/util/GoogleApiConstants.java
new file mode 100644
index 000000000..9426b6ff3
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/util/GoogleApiConstants.java
@@ -0,0 +1,8 @@
+package com.firebase.ui.auth.util;
+
+public class GoogleApiConstants {
+ public static final int AUTO_MANAGE_ID0 = 0;
+ public static final int AUTO_MANAGE_ID1 = 1;
+ public static final int AUTO_MANAGE_ID2 = 2;
+ public static final int AUTO_MANAGE_ID3 = 3;
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/ui/idp/IdpSignInContainerActivity.java b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/IdpSignInContainer.java
similarity index 53%
rename from auth/src/main/java/com/firebase/ui/auth/ui/idp/IdpSignInContainerActivity.java
rename to auth/src/main/java/com/firebase/ui/auth/util/signincontainer/IdpSignInContainer.java
index cf9403b3f..c9acaac46 100644
--- a/auth/src/main/java/com/firebase/ui/auth/ui/idp/IdpSignInContainerActivity.java
+++ b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/IdpSignInContainer.java
@@ -12,27 +12,31 @@
* limitations under the License.
*/
-package com.firebase.ui.auth.ui.idp;
+package com.firebase.ui.auth.util.signincontainer;
-import android.content.Context;
+import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.util.Log;
-import com.firebase.ui.auth.AuthUI.IdpConfig;
+import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.IdpResponse;
+import com.firebase.ui.auth.provider.AuthCredentialHelper;
import com.firebase.ui.auth.provider.FacebookProvider;
import com.firebase.ui.auth.provider.GoogleProvider;
import com.firebase.ui.auth.provider.IdpProvider;
import com.firebase.ui.auth.provider.IdpProvider.IdpCallback;
import com.firebase.ui.auth.provider.TwitterProvider;
-import com.firebase.ui.auth.ui.ActivityHelper;
-import com.firebase.ui.auth.ui.AppCompatBase;
-import com.firebase.ui.auth.ui.AuthCredentialHelper;
+import com.firebase.ui.auth.ui.BaseFragment;
import com.firebase.ui.auth.ui.ExtraConstants;
import com.firebase.ui.auth.ui.FlowParameters;
+import com.firebase.ui.auth.ui.FragmentHelper;
import com.firebase.ui.auth.ui.TaskFailureLogger;
-import com.firebase.ui.auth.util.SmartLock;
+import com.firebase.ui.auth.ui.idp.CredentialSignInHandler;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
@@ -41,25 +45,22 @@
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.TwitterAuthProvider;
-public class IdpSignInContainerActivity extends AppCompatBase implements IdpCallback {
+public class IdpSignInContainer extends BaseFragment implements IdpCallback {
private static final String TAG = "IDPSignInContainer";
private static final int RC_WELCOME_BACK_IDP = 4;
private IdpProvider mIdpProvider;
- private String mProvider;
- private String mEmail;
- @Nullable
- private SmartLock mSmartLock;
+ @Nullable private SaveSmartLock mSaveSmartLock;
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mSmartLock = mActivityHelper.getSmartLockInstance(this, TAG);
- String provider = getIntent().getStringExtra(ExtraConstants.EXTRA_PROVIDER);
- String email = getIntent().getStringExtra(ExtraConstants.EXTRA_EMAIL);
- IdpConfig providerConfig = null;
- for (IdpConfig config : mActivityHelper.getFlowParams().providerInfo) {
+ mSaveSmartLock = mHelper.getSaveSmartLockInstance(getActivity());
+ String email = getArguments().getString(ExtraConstants.EXTRA_EMAIL);
+ String provider = getArguments().getString(ExtraConstants.EXTRA_PROVIDER);
+ AuthUI.IdpConfig providerConfig = null;
+ for (AuthUI.IdpConfig config : mHelper.getFlowParams().providerInfo) {
if (config.getProviderId().equalsIgnoreCase(provider)) {
providerConfig = config;
break;
@@ -68,20 +69,20 @@ protected void onCreate(Bundle savedInstanceState) {
if (providerConfig == null) {
// we don't have a provider to handle this
- finish(RESULT_CANCELED, new Intent());
+ finish(Activity.RESULT_CANCELED, new Intent());
return;
}
if (provider.equalsIgnoreCase(FacebookAuthProvider.PROVIDER_ID)) {
- mIdpProvider = new FacebookProvider(this, providerConfig);
+ mIdpProvider = new FacebookProvider(getContext(), providerConfig);
} else if (provider.equalsIgnoreCase(GoogleAuthProvider.PROVIDER_ID)) {
- mIdpProvider = new GoogleProvider(this, providerConfig, email);
+ mIdpProvider = new GoogleProvider(getActivity(), providerConfig, email);
} else if (provider.equalsIgnoreCase(TwitterAuthProvider.PROVIDER_ID)) {
- mIdpProvider = new TwitterProvider(this);
+ mIdpProvider = new TwitterProvider(getContext());
}
mIdpProvider.setAuthenticationCallback(this);
- mIdpProvider.startLogin(this);
+ mIdpProvider.startLogin(getActivity());
}
@Override
@@ -89,22 +90,22 @@ public void onSuccess(final IdpResponse response) {
Intent data = new Intent();
data.putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, response);
AuthCredential credential = AuthCredentialHelper.getAuthCredential(response);
- final FirebaseAuth firebaseAuth = mActivityHelper.getFirebaseAuth();
+ final FirebaseAuth firebaseAuth = mHelper.getFirebaseAuth();
Task authResultTask = firebaseAuth.signInWithCredential(credential);
authResultTask
.addOnFailureListener(
new TaskFailureLogger(TAG, "Failure authenticating with credential"))
.addOnCompleteListener(new CredentialSignInHandler(
- IdpSignInContainerActivity.this,
- mActivityHelper,
- mSmartLock,
+ getActivity(),
+ mHelper,
+ mSaveSmartLock,
RC_WELCOME_BACK_IDP,
response));
}
@Override
public void onFailure(Bundle extra) {
- finish(RESULT_CANCELED, new Intent());
+ finish(Activity.RESULT_CANCELED, new Intent());
}
@Override
@@ -117,16 +118,34 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
- public static Intent createIntent(
- Context context,
- FlowParameters flowParams,
- String provider,
- String email) {
- return ActivityHelper.createBaseIntent(
- context,
- IdpSignInContainerActivity.class,
- flowParams)
- .putExtra(ExtraConstants.EXTRA_PROVIDER, provider)
- .putExtra(ExtraConstants.EXTRA_EMAIL, email);
+ public static void signIn(FragmentActivity activity,
+ FlowParameters parameters,
+ String email,
+ String provider) {
+ FragmentManager fm = activity.getSupportFragmentManager();
+ Fragment fragment = fm.findFragmentByTag(TAG);
+ if (fragment == null || !(fragment instanceof IdpSignInContainer)) {
+ IdpSignInContainer result = new IdpSignInContainer();
+
+ Bundle bundle = FragmentHelper.getFlowParamsBundle(parameters);
+ bundle.putString(ExtraConstants.EXTRA_EMAIL, email);
+ bundle.putString(ExtraConstants.EXTRA_PROVIDER, provider);
+ result.setArguments(bundle);
+
+ try {
+ fm.beginTransaction().add(result, TAG).disallowAddToBackStack().commit();
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Cannot add fragment", e);
+ }
+ }
+ }
+
+ public static IdpSignInContainer getInstance(FragmentActivity activity) {
+ Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag(TAG);
+ if (fragment != null && fragment instanceof IdpSignInContainer) {
+ return (IdpSignInContainer) fragment;
+ } else {
+ return null;
+ }
}
}
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/SmartLock.java b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SaveSmartLock.java
similarity index 60%
rename from auth/src/main/java/com/firebase/ui/auth/util/SmartLock.java
rename to auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SaveSmartLock.java
index 605828a4a..baea249d6 100644
--- a/auth/src/main/java/com/firebase/ui/auth/util/SmartLock.java
+++ b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SaveSmartLock.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package com.firebase.ui.auth.util;
+package com.firebase.ui.auth.util.signincontainer;
import android.app.PendingIntent;
import android.content.Intent;
@@ -22,46 +22,42 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
import android.util.Log;
+import android.widget.Toast;
-import com.firebase.ui.auth.BuildConfig;
import com.firebase.ui.auth.IdpResponse;
-import com.firebase.ui.auth.ui.ActivityHelper;
import com.firebase.ui.auth.ui.ExtraConstants;
+import com.firebase.ui.auth.ui.FlowParameters;
+import com.firebase.ui.auth.ui.FragmentHelper;
+import com.firebase.ui.auth.util.GoogleApiConstants;
+import com.firebase.ui.auth.util.PlayServicesHelper;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
-import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.Builder;
-import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.firebase.auth.FirebaseUser;
import static android.app.Activity.RESULT_OK;
-public class SmartLock extends Fragment
- implements GoogleApiClient.ConnectionCallbacks,
- GoogleApiClient.OnConnectionFailedListener,
- ResultCallback {
- private static final String TAG = "SmartLockFragment";
+public class SaveSmartLock extends SmartLockBase {
+ private static final String TAG = "SaveSmartLock";
private static final int RC_SAVE = 100;
private static final int RC_UPDATE_SERVICE = 28;
- private ActivityHelper mActivityHelper;
private String mName;
private String mEmail;
private String mPassword;
private String mProfilePictureUri;
private IdpResponse mResponse;
- private GoogleApiClient mCredentialsApiClient;
@Override
- public void onConnected(@Nullable Bundle bundle) {
- if (mEmail == null) {
+ public void onConnected(Bundle bundle) {
+ if (TextUtils.isEmpty(mEmail)) {
Log.e(TAG, "Unable to save null credential!");
finish();
return;
@@ -73,7 +69,7 @@ public void onConnected(@Nullable Bundle bundle) {
// only password OR provider can be set, not both
if (mResponse != null) {
String translatedProvider =
- SmartLockUtil.providerIdToAccountType(mResponse.getProviderType());
+ providerIdToAccountType(mResponse.getProviderType());
if (translatedProvider != null) {
builder.setAccountType(translatedProvider);
} else {
@@ -92,24 +88,15 @@ public void onConnected(@Nullable Bundle bundle) {
builder.setProfilePictureUri(Uri.parse(mProfilePictureUri));
}
- mActivityHelper.getCredentialsApi()
- .save(mCredentialsApiClient, builder.build())
+ mHelper.getCredentialsApi()
+ .save(mGoogleApiClient, builder.build())
.setResultCallback(this);
}
- @Override
- public void onConnectionSuspended(int i) {
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "Connection suspended with code " + i);
- }
- }
-
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "connection failed with " + connectionResult.getErrorMessage()
- + " and code: " + connectionResult.getErrorCode());
- }
+ Toast.makeText(getActivity(), "An error has occurred.", Toast.LENGTH_SHORT).show();
+
PendingIntent resolution =
GoogleApiAvailability
.getInstance()
@@ -117,20 +104,13 @@ public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
connectionResult.getErrorCode(),
RC_UPDATE_SERVICE);
try {
- startIntentSenderForResult(resolution.getIntentSender(),
- RC_UPDATE_SERVICE,
- null,
- 0,
- 0,
- 0,
- null);
+ mHelper.startIntentSenderForResult(resolution.getIntentSender(), RC_UPDATE_SERVICE);
} catch (IntentSender.SendIntentException e) {
- e.printStackTrace();
+ Log.e(TAG, "STATUS: Failed to send resolution.", e);
finish();
}
}
-
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
@@ -140,13 +120,8 @@ public void onResult(@NonNull Status status) {
// Try to resolve the save request. This will prompt the user if
// the credential is new.
try {
- startIntentSenderForResult(status.getResolution().getIntentSender(),
- RC_SAVE,
- null,
- 0,
- 0,
- 0,
- null);
+ mHelper.startIntentSenderForResult(status.getResolution().getIntentSender(),
+ RC_SAVE);
} catch (IntentSender.SendIntentException e) {
// Could not resolve the request
Log.e(TAG, "STATUS: Failed to send resolution.", e);
@@ -164,21 +139,16 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SAVE) {
- if (resultCode == RESULT_OK) {
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "SAVE: OK");
- }
- finish();
- } else {
+ if (resultCode != RESULT_OK) {
Log.e(TAG, "SAVE: Canceled by user");
- finish();
}
+ finish();
} else if (requestCode == RC_UPDATE_SERVICE) {
if (resultCode == RESULT_OK) {
Credential credential = new Credential.Builder(mEmail).setPassword(mPassword)
.build();
- mActivityHelper.getCredentialsApi()
- .save(mCredentialsApiClient, credential)
+ mHelper.getCredentialsApi()
+ .save(mGoogleApiClient, credential)
.setResultCallback(this);
} else {
Log.e(TAG, "SAVE: Canceled by user");
@@ -189,24 +159,30 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
private void finish() {
Intent resultIntent = new Intent().putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, mResponse);
- mActivityHelper.finish(RESULT_OK, resultIntent);
+ finish(RESULT_OK, resultIntent);
}
/**
* If SmartLock is enabled and Google Play Services is available, save the credentials.
* Otherwise, finish the calling Activity with RESULT_OK.
*
- * @param activity the calling Activity.
+ * Note: saveCredentialsOrFinish cannot be called immediately after getInstance because
+ * onCreate has not yet been called.
+ *
* @param firebaseUser Firebase user to save in Credential.
* @param password (optional) password for email credential.
* @param response (optional) an {@link IdpResponse} representing the result of signing in.
*/
- public void saveCredentialsOrFinish(AppCompatActivity activity,
- ActivityHelper helper,
- FirebaseUser firebaseUser,
+ public void saveCredentialsOrFinish(FirebaseUser firebaseUser,
@Nullable String password,
@Nullable IdpResponse response) {
- mActivityHelper = helper;
+ if (!mHelper.getFlowParams().smartLockEnabled
+ || !PlayServicesHelper.getInstance(getContext()).isPlayServicesAvailable()
+ || getActivity().isFinishing()) {
+ finish();
+ return;
+ }
+
mName = firebaseUser.getDisplayName();
mEmail = firebaseUser.getEmail();
mPassword = password;
@@ -214,57 +190,32 @@ public void saveCredentialsOrFinish(AppCompatActivity activity,
mProfilePictureUri = firebaseUser.getPhotoUrl() != null ? firebaseUser.getPhotoUrl()
.toString() : null;
- // If SmartLock is disabled, finish the Activity
- if (!helper.getFlowParams().smartLockEnabled) {
- finish();
- return;
- }
-
- // If Play Services is not available, finish the Activity
- if (!PlayServicesHelper.getInstance(activity).isPlayServicesAvailable()) {
- finish();
- return;
- }
-
- if (!FirebaseAuthWrapperFactory
- .getFirebaseAuthWrapper(helper.getFlowParams().appName)
- .isPlayServicesAvailable(activity)) {
- finish();
- return;
- }
-
- if (activity.isFinishing()) {
- finish();
- return;
- }
-
- mCredentialsApiClient = new Builder(activity)
+ mGoogleApiClient = new Builder(getContext().getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Auth.CREDENTIALS_API)
- .enableAutoManage(activity, this)
+ .enableAutoManage(getActivity(), GoogleApiConstants.AUTO_MANAGE_ID2, this)
.build();
- mCredentialsApiClient.connect();
+ mGoogleApiClient.connect();
}
@Nullable
- public static SmartLock getInstance(AppCompatActivity activity, String tag) {
- SmartLock result;
+ public static SaveSmartLock getInstance(FragmentActivity activity, FlowParameters parameters) {
+ SaveSmartLock result;
FragmentManager fm = activity.getSupportFragmentManager();
- FragmentTransaction ft = fm.beginTransaction();
-
- Fragment fragment = fm.findFragmentByTag(tag);
- if (fragment == null || !(fragment instanceof SmartLock)) {
- result = new SmartLock();
+ Fragment fragment = fm.findFragmentByTag(TAG);
+ if (fragment == null || !(fragment instanceof SaveSmartLock)) {
+ result = new SaveSmartLock();
+ result.setArguments(FragmentHelper.getFlowParamsBundle(parameters));
try {
- ft.add(result, tag).disallowAddToBackStack().commit();
+ fm.beginTransaction().add(result, TAG).disallowAddToBackStack().commit();
} catch (IllegalStateException e) {
Log.e(TAG, "Cannot add fragment", e);
return null;
}
} else {
- result = (SmartLock) fragment;
+ result = (SaveSmartLock) fragment;
}
return result;
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SignInDelegate.java b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SignInDelegate.java
new file mode 100644
index 000000000..ed3799aa3
--- /dev/null
+++ b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SignInDelegate.java
@@ -0,0 +1,381 @@
+package com.firebase.ui.auth.util.signincontainer;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.net.ConnectivityManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.firebase.ui.auth.AuthUI;
+import com.firebase.ui.auth.R;
+import com.firebase.ui.auth.ui.ExtraConstants;
+import com.firebase.ui.auth.ui.FlowParameters;
+import com.firebase.ui.auth.ui.FragmentHelper;
+import com.firebase.ui.auth.ui.TaskFailureLogger;
+import com.firebase.ui.auth.ui.email.SignInNoPasswordActivity;
+import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
+import com.firebase.ui.auth.util.CredentialsApiHelper;
+import com.firebase.ui.auth.util.EmailFlowUtil;
+import com.firebase.ui.auth.util.GoogleApiConstants;
+import com.firebase.ui.auth.util.PlayServicesHelper;
+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.auth.api.credentials.IdentityProviders;
+import com.google.android.gms.common.api.CommonStatusCodes;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.Status;
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.OnFailureListener;
+import com.google.android.gms.tasks.OnSuccessListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.auth.AuthResult;
+import com.google.firebase.auth.EmailAuthProvider;
+import com.google.firebase.auth.FacebookAuthProvider;
+import com.google.firebase.auth.FirebaseAuthInvalidUserException;
+import com.google.firebase.auth.GoogleAuthProvider;
+import com.google.firebase.auth.TwitterAuthProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.app.Activity.RESULT_CANCELED;
+import static android.app.Activity.RESULT_OK;
+import static com.firebase.ui.auth.ui.ResultCodes.RESULT_NO_NETWORK;
+
+/**
+ * Attempts to acquire a credential from Smart Lock for Passwords to sign in
+ * an existing account. If this succeeds, an attempt is made to sign the user in
+ * with this credential. If it does not, the
+ * {@link AuthMethodPickerActivity authentication method picker activity}
+ * is started, unless only email is supported, in which case the
+ * {@link SignInNoPasswordActivity email sign-in flow}
+ * is started.
+ */
+public class SignInDelegate extends SmartLockBase {
+ private static final String TAG = "SignInDelegate";
+ private static final int RC_CREDENTIALS_READ = 2;
+ private static final int RC_IDP_SIGNIN = 3;
+ private static final int RC_AUTH_METHOD_PICKER = 4;
+ private static final int RC_EMAIL_FLOW = 5;
+ private static final int RC_PLAY_SERVICES = 6;
+
+ private Credential mCredential;
+
+ @Override
+ public void onCreate(Bundle savedInstance) {
+ super.onCreate(savedInstance);
+ if (savedInstance != null) {
+ // We already have a running instance of this fragment
+ return;
+ }
+
+ if (!hasNetworkConnection()) {
+ Log.d(TAG, "No network connection");
+ finish(RESULT_NO_NETWORK, new Intent());
+ return;
+ }
+
+ // Make Google Play Services available at the correct version, if possible
+ boolean madeAvailable =
+ PlayServicesHelper
+ .getInstance(getActivity())
+ .makePlayServicesAvailable(getActivity(), RC_PLAY_SERVICES,
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialogInterface) {
+ Log.w(TAG,
+ "playServices:dialog.onCancel()");
+ finish(RESULT_CANCELED, new Intent());
+ }
+ });
+
+ if (!madeAvailable
+ || !PlayServicesHelper.getInstance(getActivity()).isPlayServicesAvailable()) {
+ Log.w(TAG, "playServices: could not make available.");
+ finish(RESULT_CANCELED, new Intent());
+ return;
+ }
+
+ if (mHelper.getFlowParams().smartLockEnabled) {
+ mHelper.showLoadingDialog(R.string.progress_dialog_loading);
+
+ mGoogleApiClient = new GoogleApiClient.Builder(getContext().getApplicationContext())
+ .addConnectionCallbacks(this)
+ .addApi(Auth.CREDENTIALS_API)
+ .enableAutoManage(getActivity(), GoogleApiConstants.AUTO_MANAGE_ID1, this)
+ .build();
+ mGoogleApiClient.connect();
+
+ mHelper.getCredentialsApi()
+ .request(mGoogleApiClient,
+ new CredentialRequest.Builder()
+ .setPasswordLoginSupported(true)
+ .setAccountTypes(getSupportedAccountTypes().toArray(new String[0]))
+ .build())
+ .setResultCallback(this);
+ } else {
+ startAuthMethodChoice();
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ // It doesn't matter what we put here, we just don't want outState to be empty
+ outState.putBoolean(ExtraConstants.HAS_EXISTING_INSTANCE, true);
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onResult(@NonNull CredentialRequestResult result) {
+ Status status = result.getStatus();
+
+ if (status.isSuccess()) {
+ // Auto sign-in success
+ handleCredential(result.getCredential());
+ return;
+ } else if (status.hasResolution()) {
+ try {
+ if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
+ mHelper.startIntentSenderForResult(
+ status.getResolution().getIntentSender(),
+ RC_CREDENTIALS_READ);
+ return;
+ } else if (!getSupportedAccountTypes().isEmpty()) {
+ mHelper.startIntentSenderForResult(
+ status.getResolution().getIntentSender(),
+ RC_CREDENTIALS_READ);
+ return;
+ }
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "Failed to send Credentials intent.", e);
+ }
+ }
+ startAuthMethodChoice();
+ }
+
+ @Override
+ public void onConnected(@Nullable Bundle bundle) {
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ switch (requestCode) {
+ case RC_CREDENTIALS_READ:
+ if (resultCode == RESULT_OK) {
+ // credential selected from SmartLock, log in with that credential
+ Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
+ handleCredential(credential);
+ } else {
+ // Smart lock selector cancelled, go to the AuthMethodPicker screen
+ startAuthMethodChoice();
+ }
+ break;
+ case RC_IDP_SIGNIN:
+ case RC_AUTH_METHOD_PICKER:
+ case RC_EMAIL_FLOW:
+ finish(resultCode, data);
+ break;
+ case RC_PLAY_SERVICES:
+ if (resultCode != RESULT_OK) finish(resultCode, data);
+ break;
+ default:
+ IdpSignInContainer signInContainer = IdpSignInContainer.getInstance(getActivity());
+ if (signInContainer != null) {
+ signInContainer.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+ }
+
+ private List getSupportedAccountTypes() {
+ List accounts = new ArrayList<>();
+ for (AuthUI.IdpConfig idpConfig : mHelper.getFlowParams().providerInfo) {
+ String providerId = idpConfig.getProviderId();
+ if (providerId.equals(GoogleAuthProvider.PROVIDER_ID)
+ || providerId.equals(FacebookAuthProvider.PROVIDER_ID)
+ || providerId.equals(TwitterAuthProvider.PROVIDER_ID)) {
+ accounts.add(providerIdToAccountType(providerId));
+ }
+ }
+ return accounts;
+ }
+
+ private String getEmailFromCredential() {
+ if (mCredential == null) {
+ return null;
+ }
+ return mCredential.getId();
+ }
+
+ private String getAccountTypeFromCredential() {
+ if (mCredential == null) {
+ return null;
+ }
+ return mCredential.getAccountType();
+ }
+
+ private String getPasswordFromCredential() {
+ if (mCredential == null) {
+ return null;
+ }
+ return mCredential.getPassword();
+ }
+
+ private void handleCredential(Credential credential) {
+ mCredential = credential;
+ String email = getEmailFromCredential();
+ String password = getPasswordFromCredential();
+ if (!TextUtils.isEmpty(email)) {
+ if (TextUtils.isEmpty(password)) {
+ // log in with id/provider
+ redirectToIdpSignIn(email, getAccountTypeFromCredential());
+ } else {
+ // Sign in with the email/password retrieved from SmartLock
+ signInWithEmailAndPassword(email, password);
+ }
+ }
+ }
+
+ private void startAuthMethodChoice() {
+ List idpConfigs = mHelper.getFlowParams().providerInfo;
+
+ // If the only provider is Email, immediately launch the email flow. Otherwise, launch
+ // the auth method picker screen.
+ if (idpConfigs.size() == 1) {
+ if (idpConfigs.get(0).getProviderId().equals(EmailAuthProvider.PROVIDER_ID)) {
+ startActivityForResult(
+ EmailFlowUtil.createIntent(
+ getContext(),
+ mHelper.getFlowParams()),
+ RC_EMAIL_FLOW);
+ } else {
+ redirectToIdpSignIn(null,
+ providerIdToAccountType(idpConfigs.get(0).getProviderId()));
+ }
+ } else {
+ startActivityForResult(
+ AuthMethodPickerActivity.createIntent(
+ getContext(),
+ mHelper.getFlowParams()),
+ RC_AUTH_METHOD_PICKER);
+ }
+ mHelper.dismissDialog();
+ }
+
+ /**
+ * Begin sign in process with email and password from a SmartLock credential.
+ * On success, finish with {@code RESULT_OK}.
+ * On failure, delete the credential from SmartLock (if applicable) and then launch the
+ * auth method picker flow.
+ */
+ private void signInWithEmailAndPassword(String email, String password) {
+ mHelper.getFirebaseAuth()
+ .signInWithEmailAndPassword(email, password)
+ .addOnFailureListener(new TaskFailureLogger(
+ TAG, "Error signing in with email and password"))
+ .addOnSuccessListener(new OnSuccessListener() {
+ @Override
+ public void onSuccess(AuthResult authResult) {
+ finish(RESULT_OK, new Intent());
+ }
+ })
+ .addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ if (e instanceof FirebaseAuthInvalidUserException) {
+ // In this case the credential saved in SmartLock was not
+ // a valid credential, we should delete it from SmartLock
+ // before continuing.
+ deleteCredentialAndRedirect();
+ } else {
+ startAuthMethodChoice();
+ }
+ }
+ });
+ }
+
+ /**
+ * Delete the last credential retrieved from SmartLock and then redirect to the
+ * auth method choice flow.
+ */
+ private void deleteCredentialAndRedirect() {
+ if (mCredential == null) {
+ Log.w(TAG, "deleteCredentialAndRedirect: null credential");
+ startAuthMethodChoice();
+ return;
+ }
+
+ CredentialsApiHelper credentialsApiHelper = CredentialsApiHelper.getInstance(getActivity());
+ credentialsApiHelper.delete(mCredential)
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ if (!task.isSuccessful()) {
+ Log.w(TAG, "deleteCredential:failure", task.getException());
+ }
+ startAuthMethodChoice();
+ }
+ });
+ }
+
+ private void redirectToIdpSignIn(String email, String accountType) {
+ if (accountType != null && (accountType.equals(IdentityProviders.GOOGLE)
+ || accountType.equals(IdentityProviders.FACEBOOK)
+ || accountType.equals(IdentityProviders.TWITTER))) {
+ IdpSignInContainer.signIn(
+ getActivity(),
+ mHelper.getFlowParams(),
+ email,
+ accountTypeToProviderId(accountType));
+ } else {
+ Log.w(TAG, "unknown provider: " + accountType);
+ startActivityForResult(
+ AuthMethodPickerActivity.createIntent(
+ getContext(),
+ mHelper.getFlowParams()),
+ RC_IDP_SIGNIN);
+ mHelper.dismissDialog();
+ }
+ }
+
+ /**
+ * Check if there is an active or soon-to-be-active network connection.
+ */
+ private boolean hasNetworkConnection() {
+ ConnectivityManager manager =
+ (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ return manager != null
+ && manager.getActiveNetworkInfo() != null
+ && manager.getActiveNetworkInfo().isConnectedOrConnecting();
+ }
+
+ public static void delegate(FragmentActivity activity, FlowParameters params) {
+ FragmentManager fm = activity.getSupportFragmentManager();
+ Fragment fragment = fm.findFragmentByTag(TAG);
+ if (fragment == null || !(fragment instanceof SignInDelegate)) {
+ SignInDelegate result = new SignInDelegate();
+ result.setArguments(FragmentHelper.getFlowParamsBundle(params));
+ fm.beginTransaction().add(result, TAG).disallowAddToBackStack().commit();
+ }
+ }
+
+ public static SignInDelegate getInstance(FragmentActivity activity) {
+ Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag(TAG);
+ if (fragment != null && fragment instanceof SignInDelegate) {
+ return (SignInDelegate) fragment;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/auth/src/main/java/com/firebase/ui/auth/util/SmartLockUtil.java b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SmartLockBase.java
similarity index 52%
rename from auth/src/main/java/com/firebase/ui/auth/util/SmartLockUtil.java
rename to auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SmartLockBase.java
index 4fd61de00..fc302b68e 100644
--- a/auth/src/main/java/com/firebase/ui/auth/util/SmartLockUtil.java
+++ b/auth/src/main/java/com/firebase/ui/auth/util/signincontainer/SmartLockBase.java
@@ -1,11 +1,19 @@
-package com.firebase.ui.auth.util;
+package com.firebase.ui.auth.util.signincontainer;
+import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.Toast;
+import com.firebase.ui.auth.ui.BaseFragment;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.IdentityProviders;
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.Result;
+import com.google.android.gms.common.api.ResultCallback;
import com.google.firebase.auth.EmailAuthProvider;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseUser;
@@ -17,11 +25,58 @@
import java.util.Collections;
import java.util.List;
-/**
- * Helper class to deal with Smartlock Flows.
- */
-public class SmartLockUtil {
- private static final String TAG = "SmartLockUtil";
+public abstract class SmartLockBase extends BaseFragment implements
+ GoogleApiClient.ConnectionCallbacks,
+ ResultCallback,
+ GoogleApiClient.OnConnectionFailedListener {
+ private static final String TAG = "SmartLockBase";
+
+ protected GoogleApiClient mGoogleApiClient;
+ private boolean mWasProgressDialogShowing = false;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mWasProgressDialogShowing) {
+ mHelper.showLoadingDialog(com.firebase.ui.auth.R.string.progress_dialog_loading);
+ mWasProgressDialogShowing = false;
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mWasProgressDialogShowing = mHelper.isProgressDialogShowing();
+ mHelper.dismissDialog();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ cleanup();
+ }
+
+ public void cleanup() {
+ if (mGoogleApiClient != null) {
+ mGoogleApiClient.disconnect();
+ }
+ }
+
+ @Override
+ public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
+ Toast.makeText(getContext(), "An error has occurred.", Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Just wait
+ }
/**
* Translate a Firebase Auth provider ID (such as {@link GoogleAuthProvider#PROVIDER_ID}) to
@@ -38,9 +93,22 @@ public static String providerIdToAccountType(@NonNull String providerId) {
case EmailAuthProvider.PROVIDER_ID:
// The account type for email/password creds is null
return null;
+ default:
+ return null;
}
+ }
- return null;
+ public static String accountTypeToProviderId(@NonNull String accountType) {
+ switch (accountType) {
+ case IdentityProviders.GOOGLE:
+ return GoogleAuthProvider.PROVIDER_ID;
+ case IdentityProviders.FACEBOOK:
+ return FacebookAuthProvider.PROVIDER_ID;
+ case IdentityProviders.TWITTER:
+ return TwitterAuthProvider.PROVIDER_ID;
+ default:
+ return null;
+ }
}
/**
diff --git a/auth/src/main/res/layout/confirm_recovery_layout.xml b/auth/src/main/res/layout/confirm_recovery_layout.xml
deleted file mode 100644
index aa6013808..000000000
--- a/auth/src/main/res/layout/confirm_recovery_layout.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/auth/src/main/res/values/styles.xml b/auth/src/main/res/values/styles.xml
index 826f0db1d..68c21be5f 100644
--- a/auth/src/main/res/values/styles.xml
+++ b/auth/src/main/res/values/styles.xml
@@ -15,12 +15,7 @@
- @color/authui_colorAccent
-
+
-
-