Skip to content

Commit 2bc242a

Browse files
authored
Kill smartlock fragments (#1124)
1 parent 6fbe224 commit 2bc242a

28 files changed

+678
-631
lines changed

auth/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
12
<manifest
23
xmlns:android="http://schemas.android.com/apk/res/android"
34
xmlns:tools="http://schemas.android.com/tools"
@@ -11,6 +12,7 @@
1112
<meta-data
1213
android:name="com.google.android.gms.version"
1314
android:value="@integer/google_play_services_version" />
15+
1416
<meta-data
1517
android:name="com.facebook.sdk.ApplicationId"
1618
android:value="@string/facebook_application_id" />
@@ -60,6 +62,12 @@
6062
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
6163
tools:ignore="MissingRegistered" />
6264

65+
<activity
66+
android:name=".ui.credentials.CredentialSaveActivity"
67+
android:label=""
68+
android:exported="false"
69+
android:theme="@style/FirebaseUI.Transparent" />
70+
6371
<activity
6472
android:name="com.facebook.CustomTabActivity"
6573
android:exported="true"

auth/src/main/java/com/firebase/ui/auth/data/model/Resource.java

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import android.support.annotation.Nullable;
55
import android.support.annotation.RestrictTo;
66

7-
import com.firebase.ui.auth.util.Preconditions;
8-
97
/**
108
* Base state model object.
119
* <p>
@@ -14,39 +12,47 @@
1412
*/
1513
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
1614
public final class Resource<T> {
15+
1716
private final State mState;
1817
private final T mValue;
1918
private final Exception mException;
2019

20+
private Resource(State state, T value, Exception exception) {
21+
mState = state;
22+
mValue = value;
23+
mException = exception;
24+
}
25+
26+
/**
27+
* Creates a successful, empty Resource.
28+
*/
29+
@NonNull
30+
public static Resource<Void> forVoidSuccess() {
31+
return new Resource<>(State.SUCCESS, null, null);
32+
}
33+
2134
/**
22-
* Creates a default, unfinished, state.
35+
* Creates a successful resource containing a value.
2336
*/
24-
public Resource() {
25-
mState = State.LOADING;
26-
mValue = null;
27-
mException = null;
37+
@NonNull
38+
public static <T> Resource<T> forSuccess(@NonNull T value) {
39+
return new Resource<>(State.SUCCESS, value, null);
2840
}
2941

3042
/**
31-
* Creates a finished success state.
32-
*
33-
* @param value result of the operation
43+
* Creates a failed resource with an exception.
3444
*/
35-
public Resource(@NonNull T value) {
36-
mState = State.SUCCESS;
37-
mValue = Preconditions.checkNotNull(value, "Success state cannot have null result.");
38-
mException = null;
45+
@NonNull
46+
public static <T> Resource<T> forFailure(@NonNull Exception e) {
47+
return new Resource<>(State.FAILURE, null, e);
3948
}
4049

4150
/**
42-
* Creates a finished failure state.
43-
*
44-
* @param exception error in computing the result
51+
* Creates a resource in the loading state, without a value or an exception.
4552
*/
46-
public Resource(@NonNull Exception exception) {
47-
mState = State.FAILURE;
48-
mValue = null;
49-
mException = Preconditions.checkNotNull(exception, "Failure state cannot have null error.");
53+
@NonNull
54+
public static <T> Resource<T> forLoading() {
55+
return new Resource<>(State.LOADING, null, null);
5056
}
5157

5258
@NonNull

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

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212

1313
import com.firebase.ui.auth.IdpResponse;
1414
import com.firebase.ui.auth.data.model.FlowParameters;
15+
import com.firebase.ui.auth.ui.credentials.CredentialSaveActivity;
1516
import com.firebase.ui.auth.util.AuthHelper;
17+
import com.firebase.ui.auth.util.CredentialsUtil;
1618
import com.firebase.ui.auth.util.ExtraConstants;
17-
import com.firebase.ui.auth.util.signincontainer.SaveSmartLock;
19+
import com.firebase.ui.auth.util.data.ProviderUtils;
1820
import com.firebase.ui.auth.viewmodel.FlowHolder;
21+
import com.google.android.gms.auth.api.credentials.Credential;
1922
import com.google.firebase.auth.FirebaseUser;
2023

2124
import static com.firebase.ui.auth.util.Preconditions.checkNotNull;
@@ -24,6 +27,10 @@
2427
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
2528
public class HelperActivityBase extends AppCompatActivity {
2629

30+
private static final String TAG = "HelperActivityBase";
31+
32+
private static final int RC_SAVE_CREDENTIAL = 101;
33+
2734
private FlowHolder mFlowHolder;
2835

2936
private FlowParameters mFlowParameters;
@@ -54,6 +61,16 @@ protected void onDestroy() {
5461
mProgressDialogHolder.dismissDialog();
5562
}
5663

64+
@Override
65+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
66+
super.onActivityResult(requestCode, resultCode, data);
67+
68+
// Forward the results of Smartlock Saving
69+
if (requestCode == RC_SAVE_CREDENTIAL) {
70+
finish(RESULT_OK, data);
71+
}
72+
}
73+
5774
public FlowHolder getFlowHolder() {
5875
if (mFlowHolder == null) {
5976
mFlowHolder = ViewModelProviders.of(this).get(FlowHolder.class);
@@ -84,20 +101,19 @@ public void finish(int resultCode, Intent intent) {
84101
finish();
85102
}
86103

87-
public void saveCredentialsOrFinish(FirebaseUser firebaseUser, IdpResponse response) {
88-
saveCredentialsOrFinish(firebaseUser, null, response);
89-
}
90-
91-
public void saveCredentialsOrFinish(
104+
public void startSaveCredentials(
92105
FirebaseUser firebaseUser,
93106
@Nullable String password,
94107
IdpResponse response) {
95-
SaveSmartLock saveSmartLock = SaveSmartLock.getInstance(this);
96-
if (saveSmartLock == null) {
97-
finish(Activity.RESULT_OK, response.toIntent());
98-
} else {
99-
saveSmartLock.saveCredentialsOrFinish(firebaseUser, password, response);
100-
}
101-
}
102108

109+
// Build credential
110+
String accountType = ProviderUtils.idpResponseToAccountType(response);
111+
Credential credential = CredentialsUtil.buildCredential(
112+
firebaseUser, password, accountType);
113+
114+
// Start the dedicated SmartLock Activity
115+
Intent intent = CredentialSaveActivity.createIntent(this, getFlowParams(),
116+
credential, response);
117+
startActivityForResult(intent, RC_SAVE_CREDENTIAL);
118+
}
103119
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package com.firebase.ui.auth.ui.credentials;
2+
3+
import android.arch.lifecycle.Observer;
4+
import android.arch.lifecycle.ViewModelProviders;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.content.IntentSender;
8+
import android.os.Bundle;
9+
import android.support.annotation.NonNull;
10+
import android.support.annotation.Nullable;
11+
import android.util.Log;
12+
13+
import com.firebase.ui.auth.IdpResponse;
14+
import com.firebase.ui.auth.data.model.FlowParameters;
15+
import com.firebase.ui.auth.data.model.Resource;
16+
import com.firebase.ui.auth.ui.HelperActivityBase;
17+
import com.firebase.ui.auth.util.ExtraConstants;
18+
import com.firebase.ui.auth.viewmodel.PendingResolution;
19+
import com.firebase.ui.auth.viewmodel.ResolutionCodes;
20+
import com.firebase.ui.auth.viewmodel.smartlock.SmartLockHandler;
21+
import com.google.android.gms.auth.api.credentials.Credential;
22+
23+
/**
24+
* Invisible Activity used for saving credentials to SmartLock.
25+
*/
26+
public class CredentialSaveActivity extends HelperActivityBase {
27+
28+
private static final String TAG = "SmartlockSave";
29+
30+
private SmartLockHandler mHandler;
31+
private IdpResponse mIdpResponse;
32+
33+
@NonNull
34+
public static Intent createIntent(Context context,
35+
FlowParameters flowParams,
36+
Credential credential,
37+
IdpResponse response) {
38+
return HelperActivityBase.createBaseIntent(context, CredentialSaveActivity.class, flowParams)
39+
.putExtra(ExtraConstants.EXTRA_CREDENTIAL, credential)
40+
.putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, response);
41+
}
42+
43+
@Override
44+
protected void onCreate(Bundle savedInstanceState) {
45+
super.onCreate(savedInstanceState);
46+
47+
mHandler = ViewModelProviders.of(this).get(SmartLockHandler.class);
48+
mHandler.init(getFlowParams());
49+
50+
Credential credential = getIntent().getParcelableExtra(ExtraConstants.EXTRA_CREDENTIAL);
51+
mIdpResponse = getIntent().getParcelableExtra(ExtraConstants.EXTRA_IDP_RESPONSE);
52+
53+
mHandler.getSaveOperation().observe(this, new Observer<Resource<Void>>() {
54+
@Override
55+
public void onChanged(@Nullable Resource<Void> resource) {
56+
if (resource == null) {
57+
Log.w(TAG, "getSaveOperation:onChanged:null");
58+
return;
59+
}
60+
61+
onSaveOperation(resource);
62+
}
63+
});
64+
65+
mHandler.getPendingResolution().observe(this, new Observer<PendingResolution>() {
66+
@Override
67+
public void onChanged(@Nullable PendingResolution resolution) {
68+
if (resolution == null) {
69+
Log.w(TAG, "getPendingResolution:onChanged: null");
70+
return;
71+
}
72+
73+
onPendingResolution(resolution);
74+
}
75+
});
76+
77+
// Avoid double-saving
78+
Resource<Void> currentOp = mHandler.getSaveOperation().getValue();
79+
if (currentOp == null) {
80+
Log.d(TAG, "Launching save operation.");
81+
mHandler.saveCredentials(credential);
82+
} else {
83+
Log.d(TAG, "Save operation in progress, doing nothing.");
84+
}
85+
}
86+
87+
@Override
88+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
89+
// Forward activity results to the ViewModel
90+
if (!mHandler.onActivityResult(requestCode, resultCode, data)) {
91+
super.onActivityResult(requestCode, resultCode, data);
92+
}
93+
}
94+
95+
private void onSaveOperation(@NonNull Resource<Void> resource) {
96+
switch (resource.getState()) {
97+
case LOADING:
98+
// No-op?
99+
break;
100+
case SUCCESS:
101+
case FAILURE:
102+
finish(RESULT_OK, mIdpResponse.toIntent());
103+
break;
104+
}
105+
}
106+
107+
private void onPendingResolution(@NonNull PendingResolution resolution) {
108+
if (resolution.getRequestCode() == ResolutionCodes.RC_CRED_SAVE) {
109+
try {
110+
startIntentSenderForResult(
111+
resolution.getPendingIntent().getIntentSender(),
112+
resolution.getRequestCode(),
113+
null, 0, 0, 0);
114+
} catch (IntentSender.SendIntentException e) {
115+
Log.e(TAG, "Failed to send resolution.", e);
116+
finish(RESULT_OK, mIdpResponse.toIntent());
117+
};
118+
}
119+
}
120+
121+
}

auth/src/main/java/com/firebase/ui/auth/ui/email/EmailActivity.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.firebase.ui.auth.ui.idp.WelcomeBackIdpPrompt;
3333
import com.firebase.ui.auth.util.ExtraConstants;
3434
import com.firebase.ui.auth.util.data.ProviderUtils;
35+
import com.google.firebase.auth.AuthResult;
3536
import com.google.firebase.auth.EmailAuthProvider;
3637

3738
/**
@@ -41,7 +42,8 @@
4142
*/
4243
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
4344
public class EmailActivity extends AppCompatBase implements
44-
CheckEmailFragment.CheckEmailListener {
45+
CheckEmailFragment.CheckEmailListener,
46+
RegisterEmailFragment.RegistrationListener {
4547

4648
public static final int RC_WELCOME_BACK_IDP = 18;
4749
private static final int RC_SIGN_IN = 17;
@@ -141,6 +143,12 @@ public void onNewUser(User user) {
141143
}
142144
}
143145

146+
@Override
147+
public void onRegistrationSuccess(AuthResult authResult, String password,
148+
IdpResponse response) {
149+
startSaveCredentials(authResult.getUser(), password, response);
150+
}
151+
144152
private void setSlideAnimation() {
145153
// Make the next activity slide in
146154
overridePendingTransition(R.anim.fui_slide_in_right, R.anim.fui_slide_out_left);

auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailFragment.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.firebase.ui.auth.data.model.User;
2222
import com.firebase.ui.auth.data.remote.ProfileMerger;
2323
import com.firebase.ui.auth.ui.FragmentBase;
24-
import com.firebase.ui.auth.ui.HelperActivityBase;
2524
import com.firebase.ui.auth.ui.TaskFailureLogger;
2625
import com.firebase.ui.auth.ui.idp.WelcomeBackIdpPrompt;
2726
import com.firebase.ui.auth.util.ExtraConstants;
@@ -53,7 +52,7 @@ public class RegisterEmailFragment extends FragmentBase implements
5352

5453
public static final String TAG = "RegisterEmailFragment";
5554

56-
private HelperActivityBase mActivity;
55+
private RegistrationListener mListener;
5756

5857
private EditText mEmailEditText;
5958
private EditText mNameEditText;
@@ -69,6 +68,12 @@ public class RegisterEmailFragment extends FragmentBase implements
6968

7069
private User mUser;
7170

71+
public interface RegistrationListener {
72+
73+
void onRegistrationSuccess(AuthResult authResult, String password, IdpResponse response);
74+
75+
}
76+
7277
public static RegisterEmailFragment newInstance(FlowParameters flowParameters, User user) {
7378
RegisterEmailFragment fragment = new RegisterEmailFragment();
7479

@@ -181,11 +186,11 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
181186
super.onActivityCreated(savedInstanceState);
182187
getActivity().setTitle(R.string.fui_title_register_email);
183188

184-
if (!(getActivity() instanceof HelperActivityBase)) {
185-
throw new RuntimeException("Must be attached to a HelperActivityBase.");
189+
if (!(getActivity() instanceof RegistrationListener)) {
190+
throw new RuntimeException("Must be attached to a RegistrationListener.");
186191
}
187192

188-
mActivity = (HelperActivityBase) getActivity();
193+
mListener = (RegistrationListener) getActivity();
189194
PreambleHandler.setup(getContext(),
190195
getFlowParams(),
191196
R.string.fui_button_text_save,
@@ -257,10 +262,7 @@ private void registerUser(final String email, final String name, final String pa
257262
.addOnSuccessListener(getActivity(), new OnSuccessListener<AuthResult>() {
258263
@Override
259264
public void onSuccess(AuthResult authResult) {
260-
mActivity.saveCredentialsOrFinish(
261-
authResult.getUser(),
262-
password,
263-
response);
265+
mListener.onRegistrationSuccess(authResult, password, response);
264266
}
265267
})
266268
.addOnFailureListener(getActivity(), new OnFailureListener() {

0 commit comments

Comments
 (0)