Skip to content

Commit 17f9243

Browse files
authored
Merge pull request #253 from samtstern/master
Add option to disable SmartLock
2 parents de4e22b + 0977088 commit 17f9243

File tree

18 files changed

+233
-87
lines changed

18 files changed

+233
-87
lines changed

app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ public class AuthUiActivity extends AppCompatActivity {
9090
@BindView(R.id.no_logo)
9191
RadioButton mNoLogo;
9292

93+
@BindView(R.id.smartlock_enabled)
94+
CheckBox mEnableSmartLock;
9395

9496
@Override
9597
public void onCreate(Bundle savedInstanceState) {
@@ -129,6 +131,7 @@ public void signIn(View view) {
129131
.setLogo(getSelectedLogo())
130132
.setProviders(getSelectedProviders())
131133
.setTosUrl(getSelectedTosUrl())
134+
.setIsSmartLockEnabled(mEnableSmartLock.isChecked())
132135
.build(),
133136
RC_SIGN_IN);
134137
}

app/src/main/res/layout/auth_ui_layout.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:layout_marginLeft="24dp"
1313
android:layout_marginRight="24dp"
1414
android:layout_marginTop="16dp"
15+
android:paddingBottom="32dp"
1516
android:orientation="vertical">
1617

1718
<TextView
@@ -126,7 +127,6 @@
126127
android:text="@string/logo_header" />
127128

128129
<RadioGroup
129-
android:layout_marginBottom="20dp"
130130
android:layout_width="wrap_content"
131131
android:layout_height="wrap_content"
132132
android:orientation="vertical">
@@ -150,6 +150,22 @@
150150
android:layout_height="wrap_content"
151151
android:text="@string/no_logo_label" />
152152
</RadioGroup>
153+
154+
<TextView
155+
style="@style/Base.TextAppearance.AppCompat.Subhead"
156+
android:layout_width="wrap_content"
157+
android:layout_height="wrap_content"
158+
android:layout_marginBottom="8dp"
159+
android:layout_marginTop="16dp"
160+
android:text="@string/other_options_header" />
161+
162+
<CheckBox
163+
android:id="@+id/smartlock_enabled"
164+
android:layout_width="wrap_content"
165+
android:layout_height="wrap_content"
166+
android:checked="true"
167+
android:text="@string/enable_smartlock" />
168+
153169
</LinearLayout>
154170

155171
</ScrollView>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@
4040
<string name="profile_picture_content_desc">Profile picture</string>
4141
<string name="default_theme">Default theme</string>
4242
<string name="configuration_required">Configuration is required - see README.md</string>
43+
<string name="other_options_header">Other Options:</string>
44+
<string name="enable_smartlock">Enable SmartLock for Passwords</string>
4345
</resources>

auth/README.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ startActivityForResult(
130130
RC_SIGN_IN);
131131
```
132132

133-
If Google Sign-in and Facebook Sign-in are also required, then this can be
134-
replaced with:
133+
You can enable sign-in providers like Google Sign-In or Facebook Log In by calling the
134+
`setProviders` method:
135135

136136
```
137137
startActivityForResult(
@@ -145,7 +145,7 @@ startActivityForResult(
145145
RC_SIGN_IN);
146146
```
147147

148-
Finally, if a terms of service URL and a custom theme are required:
148+
If a terms of service URL and a custom theme are required:
149149

150150
```
151151
startActivityForResult(
@@ -158,6 +158,33 @@ startActivityForResult(
158158
RC_SIGN_IN);
159159
```
160160

161+
By default, FirebaseUI uses [Smart Lock for Passwords](https://developers.google.com/identity/smartlock-passwords/android/)
162+
to store the user's credentials and automatically sign users into your app on subsequent attempts.
163+
Using SmartLock is recommended to provide the best user experience, but in some cases you may want
164+
to disable SmartLock for testing or development. To disable SmartLock, you can use the
165+
`setIsSmartLockEnabled` method when building your sign-in Intent:
166+
167+
```
168+
startActivityForResult(
169+
AuthUI.getInstance()
170+
.createSignInIntentBuilder()
171+
.setIsSmartLockEnabled(false)
172+
.build(),
173+
RC_SIGN_IN);
174+
```
175+
176+
It is often desirable to disable SmartLock in development but enable it in production. To achieve
177+
this, you can use the `BuildConfig.DEBUG` flag to control SmartLock:
178+
179+
```
180+
startActivityForResult(
181+
AuthUI.getInstance()
182+
.createSignInIntentBuilder()
183+
.setIsSmartLockEnabled(!BuildConfig.DEBUG)
184+
.build(),
185+
RC_SIGN_IN);
186+
```
187+
161188
#### Handling the sign-in response
162189

163190
The authentication flow provides only two response codes:
@@ -308,4 +335,4 @@ to your application like this:
308335
```
309336

310337
Note that if you do not include at least the `email` and `public_profile` scopes, FirebaseUI
311-
will not work properly.
338+
will not work properly.

auth/src/main/java/com/firebase/ui/auth/AuthUI.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ public final class SignInIntentBuilder {
350350
private int mTheme = getDefaultTheme();
351351
private List<String> mProviders = Collections.singletonList(EMAIL_PROVIDER);
352352
private String mTosUrl;
353+
private boolean mIsSmartLockEnabled = true;
353354

354355
private SignInIntentBuilder() {}
355356

@@ -405,6 +406,14 @@ public SignInIntentBuilder setProviders(@NonNull String... providers) {
405406
return this;
406407
}
407408

409+
/**
410+
* Enables or disables the use of Smart Lock for Passwords in the sign in flow.
411+
*/
412+
public SignInIntentBuilder setIsSmartLockEnabled(boolean enabled) {
413+
mIsSmartLockEnabled = enabled;
414+
return this;
415+
}
416+
408417
public Intent build() {
409418
Context context = mApp.getApplicationContext();
410419
List<IDPProviderParcel> providerInfo =
@@ -416,7 +425,8 @@ public Intent build() {
416425
providerInfo,
417426
mTheme,
418427
mLogo,
419-
mTosUrl));
428+
mTosUrl,
429+
mIsSmartLockEnabled));
420430
}
421431
}
422432
}

auth/src/main/java/com/firebase/ui/auth/ui/AcquireEmailHelper.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,9 @@ private void startEmailHandler(String email, List<String> providers) {
7878
mActivityHelper.getFlowParams(),
7979
email);
8080
mActivityHelper.startActivityForResult(registerIntent, RC_REGISTER_ACCOUNT);
81-
return;
8281
} else {
8382
// account does exist
84-
for (String provider: providers) {
83+
for (String provider : providers) {
8584
if (provider.equalsIgnoreCase(EmailAuthProvider.PROVIDER_ID)) {
8685
Intent signInIntent = SignInActivity.createIntent(
8786
mActivityHelper.getApplicationContext(),
@@ -90,6 +89,7 @@ private void startEmailHandler(String email, List<String> providers) {
9089
mActivityHelper.startActivityForResult(signInIntent, RC_SIGN_IN);
9190
return;
9291
}
92+
9393
Intent intent = WelcomeBackIDPPrompt.createIntent(
9494
mActivityHelper.getApplicationContext(),
9595
mActivityHelper.getFlowParams(),
@@ -104,7 +104,6 @@ private void startEmailHandler(String email, List<String> providers) {
104104
mActivityHelper.getApplicationContext(), SignInActivity.class);
105105
signInIntent.putExtra(ExtraConstants.EXTRA_EMAIL, email);
106106
mActivityHelper.startActivityForResult(signInIntent, RC_SIGN_IN);
107-
return;
108107
}
109108
}
110109

auth/src/main/java/com/firebase/ui/auth/ui/ChooseAccountActivity.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
import android.content.Intent;
2121
import android.os.Bundle;
2222
import android.support.annotation.NonNull;
23+
import android.text.TextUtils;
2324
import android.util.Log;
2425

2526
import com.firebase.ui.auth.BuildConfig;
2627
import com.firebase.ui.auth.provider.IDPProviderParcel;
27-
import com.firebase.ui.auth.ui.email.EmailHintContainerActivity;
2828
import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
2929
import com.firebase.ui.auth.ui.idp.IDPSignInContainerActivity;
3030
import com.firebase.ui.auth.util.CredentialsAPI;
31+
import com.firebase.ui.auth.util.EmailFlowUtil;
3132
import com.firebase.ui.auth.util.PlayServicesHelper;
3233
import com.google.android.gms.auth.api.credentials.Credential;
3334
import com.google.android.gms.auth.api.credentials.IdentityProviders;
@@ -115,13 +116,16 @@ public void onCredentialsApiConnected(
115116
String password = credentialsApi.getPasswordFromCredential();
116117
String accountType = credentialsApi.getAccountTypeFromCredential();
117118

118-
if (PlayServicesHelper.isPlayServicesAvailable(this)
119+
FlowParameters flowParams = activityHelper.getFlowParams();
120+
121+
if (flowParams.smartLockEnabled
122+
&& PlayServicesHelper.isPlayServicesAvailable(this)
119123
&& credentialsApi.isCredentialsAvailable()) {
120124

121125
if (credentialsApi.isAutoSignInAvailable()) {
122126
credentialsApi.googleSilentSignIn();
123127
// TODO: (serikb) authenticate Firebase user and continue to application
124-
if (password != null && !password.isEmpty()) {
128+
if (!TextUtils.isEmpty(password)) {
125129
// login with username/password
126130
activityHelper
127131
.getFirebaseAuth()
@@ -151,11 +155,11 @@ public void onSuccess(AuthResult authResult) {
151155

152156
private void startAuthMethodChoice(ActivityHelper activityHelper) {
153157
List<IDPProviderParcel> providers = activityHelper.getFlowParams().providerInfo;
158+
154159
if (providers.size() == 1
155160
&& providers.get(0).getProviderType().equals(EmailAuthProvider.PROVIDER_ID)) {
156-
157161
startActivityForResult(
158-
EmailHintContainerActivity.createIntent(
162+
EmailFlowUtil.createIntent(
159163
this,
160164
activityHelper.getFlowParams()),
161165
RC_EMAIL_FLOW);

auth/src/main/java/com/firebase/ui/auth/ui/FlowParameters.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,21 @@ public class FlowParameters implements Parcelable {
4646
@Nullable
4747
public final String termsOfServiceUrl;
4848

49+
public final boolean smartLockEnabled;
50+
4951
public FlowParameters(
5052
@NonNull String appName,
5153
@NonNull List<IDPProviderParcel> providerInfo,
5254
@StyleRes int themeId,
5355
@DrawableRes int logoId,
54-
@Nullable String termsOfServiceUrl) {
56+
@Nullable String termsOfServiceUrl,
57+
boolean smartLockEnabled) {
5558
this.appName = Preconditions.checkNotNull(appName, "appName cannot be null");
5659
this.providerInfo = Preconditions.checkNotNull(providerInfo, "providerInfo cannot be null");
5760
this.themeId = themeId;
5861
this.logoId = logoId;
5962
this.termsOfServiceUrl = termsOfServiceUrl;
63+
this.smartLockEnabled = smartLockEnabled;
6064
}
6165

6266
@Override
@@ -66,6 +70,7 @@ public void writeToParcel(Parcel dest, int flags) {
6670
dest.writeInt(themeId);
6771
dest.writeInt(logoId);
6872
dest.writeString(termsOfServiceUrl);
73+
dest.writeInt(smartLockEnabled ? 1 : 0);
6974
}
7075

7176
@Override
@@ -82,7 +87,11 @@ public FlowParameters createFromParcel(Parcel in) {
8287
int themeId = in.readInt();
8388
int logoId = in.readInt();
8489
String termsOfServiceUrl = in.readString();
85-
return new FlowParameters(appName, providerInfo, themeId, logoId, termsOfServiceUrl);
90+
int smartLockEnabledInt = in.readInt();
91+
boolean smartLockEnabled = (smartLockEnabledInt != 0);
92+
93+
return new FlowParameters(
94+
appName, providerInfo, themeId, logoId, termsOfServiceUrl, smartLockEnabled);
8695
}
8796

8897
@Override

auth/src/main/java/com/firebase/ui/auth/ui/account_link/SaveCredentialsActivity.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.google.android.gms.common.api.ResultCallback;
4141
import com.google.android.gms.common.api.Status;
4242
import com.google.firebase.auth.FacebookAuthProvider;
43+
import com.google.firebase.auth.FirebaseUser;
4344
import com.google.firebase.auth.GoogleAuthProvider;
4445

4546
public class SaveCredentialsActivity extends AppCompatBase
@@ -60,11 +61,13 @@ public class SaveCredentialsActivity extends AppCompatBase
6061
protected void onCreate(Bundle savedInstanceState) {
6162
super.onCreate(savedInstanceState);
6263
setContentView(R.layout.save_credentials_layout);
64+
6365
if (!FirebaseAuthWrapperFactory.getFirebaseAuthWrapper(mActivityHelper.getAppName())
6466
.isPlayServicesAvailable(this)) {
6567
finish(RESULT_FIRST_USER, getIntent());
6668
return;
6769
}
70+
6871
mName = getIntent().getStringExtra(ExtraConstants.EXTRA_NAME);
6972
mEmail = getIntent().getStringExtra(ExtraConstants.EXTRA_EMAIL);
7073
mPassword = getIntent().getStringExtra(ExtraConstants.EXTRA_PASSWORD);
@@ -207,16 +210,16 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
207210
public static Intent createIntent(
208211
Context context,
209212
FlowParameters flowParams,
210-
String name,
211-
String email,
212-
String password,
213-
String provider,
214-
String profilePictureUri) {
213+
FirebaseUser user,
214+
@Nullable String password,
215+
@Nullable String provider) {
216+
217+
String photoUrl = user.getPhotoUrl() != null ? user.getPhotoUrl().toString() : null;
215218
return ActivityHelper.createBaseIntent(context, SaveCredentialsActivity.class, flowParams)
216-
.putExtra(ExtraConstants.EXTRA_NAME, name)
217-
.putExtra(ExtraConstants.EXTRA_EMAIL, email)
219+
.putExtra(ExtraConstants.EXTRA_NAME, user.getDisplayName())
220+
.putExtra(ExtraConstants.EXTRA_EMAIL, user.getEmail())
218221
.putExtra(ExtraConstants.EXTRA_PASSWORD, password)
219222
.putExtra(ExtraConstants.EXTRA_PROVIDER, provider)
220-
.putExtra(ExtraConstants.EXTRA_PROFILE_PICTURE_URI, profilePictureUri);
223+
.putExtra(ExtraConstants.EXTRA_PROFILE_PICTURE_URI, photoUrl);
221224
}
222225
}

auth/src/main/java/com/firebase/ui/auth/ui/account_link/WelcomeBackPasswordPrompt.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.firebase.ui.auth.ui.TaskFailureLogger;
4141
import com.firebase.ui.auth.ui.email.PasswordToggler;
4242
import com.firebase.ui.auth.ui.email.RecoverPasswordActivity;
43+
import com.firebase.ui.auth.util.SmartlockUtil;
4344
import com.google.android.gms.tasks.OnCompleteListener;
4445
import com.google.android.gms.tasks.OnSuccessListener;
4546
import com.google.android.gms.tasks.Task;
@@ -134,16 +135,14 @@ public void onSuccess(AuthResult authResult) {
134135
photoUrl = photoUri.toString();
135136
}
136137
mActivityHelper.dismissDialog();
137-
startActivityForResult(
138-
SaveCredentialsActivity.createIntent(
139-
mActivityHelper.getApplicationContext(),
140-
mActivityHelper.getFlowParams(),
141-
firebaseUser.getDisplayName(),
142-
firebaseUser.getEmail(),
143-
password,
144-
null,
145-
photoUrl
146-
), RC_CREDENTIAL_SAVE);
138+
139+
SmartlockUtil.saveCredentialOrFinish(
140+
WelcomeBackPasswordPrompt.this,
141+
RC_CREDENTIAL_SAVE,
142+
mActivityHelper.getFlowParams(),
143+
firebaseUser,
144+
password,
145+
null /* provider */);
147146
}
148147
});
149148
} else {

0 commit comments

Comments
 (0)