1414
1515package com .firebase .ui .auth .ui .email ;
1616
17+ import android .arch .lifecycle .Observer ;
18+ import android .arch .lifecycle .ViewModelProviders ;
1719import android .content .Context ;
1820import android .content .Intent ;
21+ import android .content .IntentSender ;
1922import android .graphics .Typeface ;
2023import android .os .Bundle ;
21- import android .support .annotation .NonNull ;
2224import android .support .annotation .Nullable ;
2325import android .support .annotation .RestrictTo ;
2426import android .support .design .widget .TextInputLayout ;
2527import android .text .Spannable ;
2628import android .text .SpannableStringBuilder ;
2729import android .text .TextUtils ;
2830import android .text .style .StyleSpan ;
31+ import android .util .Log ;
2932import android .view .View ;
3033import android .view .WindowManager ;
3134import android .widget .EditText ;
3235import android .widget .TextView ;
3336
37+ import com .firebase .ui .auth .ErrorCodes ;
3438import com .firebase .ui .auth .IdpResponse ;
3539import com .firebase .ui .auth .R ;
40+ import com .firebase .ui .auth .data .model .FirebaseUiException ;
3641import com .firebase .ui .auth .data .model .FlowParameters ;
37- import com .firebase .ui .auth .data .model .User ;
38- import com .firebase .ui .auth .data .remote . ProfileMerger ;
42+ import com .firebase .ui .auth .data .model .Resource ;
43+ import com .firebase .ui .auth .data .model . State ;
3944import com .firebase .ui .auth .ui .AppCompatBase ;
4045import com .firebase .ui .auth .ui .HelperActivityBase ;
41- import com .firebase .ui .auth .ui .TaskFailureLogger ;
4246import com .firebase .ui .auth .util .ExtraConstants ;
4347import com .firebase .ui .auth .util .data .ProviderUtils ;
44- import com .firebase .ui .auth .util .signincontainer .SaveSmartLock ;
4548import com .firebase .ui .auth .util .ui .ImeHelper ;
46- import com .google . android . gms . tasks . OnFailureListener ;
47- import com .google . android . gms . tasks . OnSuccessListener ;
49+ import com .firebase . ui . auth . viewmodel . PendingResolution ;
50+ import com .firebase . ui . auth . viewmodel . email . WelcomeBackPasswordHandler ;
4851import com .google .firebase .auth .AuthCredential ;
49- import com .google .firebase .auth .AuthResult ;
50- import com .google .firebase .auth .EmailAuthProvider ;
5152
5253/**
5354 * Activity to link a pre-existing email/password account to a new IDP sign-in by confirming the
@@ -62,8 +63,8 @@ public class WelcomeBackPasswordPrompt extends AppCompatBase
6263 private TextInputLayout mPasswordLayout ;
6364 private EditText mPasswordField ;
6465 private IdpResponse mIdpResponse ;
65- @ Nullable
66- private SaveSmartLock mSaveSmartLock ;
66+
67+ private WelcomeBackPasswordHandler mHandler ;
6768
6869 public static Intent createIntent (
6970 Context context ,
@@ -81,7 +82,6 @@ protected void onCreate(Bundle savedInstanceState) {
8182 // Show keyboard
8283 getWindow ().setSoftInputMode (WindowManager .LayoutParams .SOFT_INPUT_STATE_VISIBLE );
8384
84- mSaveSmartLock = getAuthHelper ().getSaveSmartLockInstance (this );
8585 mIdpResponse = IdpResponse .fromResultIntent (getIntent ());
8686 mEmail = mIdpResponse .getEmail ();
8787
@@ -106,21 +106,88 @@ protected void onCreate(Bundle savedInstanceState) {
106106 // Click listeners
107107 findViewById (R .id .button_done ).setOnClickListener (this );
108108 findViewById (R .id .trouble_signing_in ).setOnClickListener (this );
109+
110+ // Initialize ViewModel with arguments
111+ mHandler = ViewModelProviders .of (this ).get (WelcomeBackPasswordHandler .class );
112+ mHandler .init (getFlowHolder ().getArguments ());
113+
114+ // Fire resolutions when asked
115+ mHandler .getPendingResolution ().observe (this ,
116+ new Observer <PendingResolution >() {
117+ @ Override
118+ public void onChanged (@ Nullable PendingResolution resolution ) {
119+ onPendingResolution (resolution );
120+ }
121+ });
122+
123+ // Observe the state of the main auth operation
124+ mHandler .getSignInResult ().observe (this , new Observer <Resource <IdpResponse >>() {
125+ @ Override
126+ public void onChanged (@ Nullable Resource <IdpResponse > resource ) {
127+ onAuthResult (resource );
128+ }
129+ });
109130 }
110131
111132 @ Override
112- public void onClick (View view ) {
113- final int id = view .getId ();
114- if (id == R .id .button_done ) {
115- validateAndSignIn ();
116- } else if (id == R .id .trouble_signing_in ) {
117- startActivity (RecoverPasswordActivity .createIntent (
118- this ,
119- getFlowParams (),
120- mEmail ));
133+ protected void onActivityResult (int requestCode , int resultCode , Intent data ) {
134+ // Forward activity results to the ViewModel
135+ if (!mHandler .onActivityResult (requestCode , resultCode , data )) {
136+ super .onActivityResult (requestCode , resultCode , data );
137+ }
138+ }
139+
140+ private void onAuthResult (@ Nullable Resource <IdpResponse > resource ) {
141+ if (resource == null ) {
142+ Log .w (TAG , "Got null resource, ignoring." );
143+ return ;
144+ }
145+
146+ if (resource .getState () == State .LOADING ) {
147+ getDialogHolder ().showLoadingDialog (R .string .fui_progress_dialog_signing_in );
148+ }
149+
150+ if (resource .getState () == State .SUCCESS ) {
151+ getDialogHolder ().dismissDialog ();
152+ Log .d (TAG , "onAuthResult:SUCCESS:" + resource .getValue ());
153+
154+ finish (RESULT_OK , resource .getValue ().toIntent ());
155+ }
156+
157+ if (resource .getState () == State .FAILURE ) {
158+ getDialogHolder ().dismissDialog ();
159+
160+ // TODO: Is this message what we want?
161+ String message = resource .getException ().getLocalizedMessage ();
162+ mPasswordLayout .setError (message );
121163 }
122164 }
123165
166+ private void onPendingResolution (@ Nullable PendingResolution resolution ) {
167+ if (resolution == null ) {
168+ Log .e (TAG , "Got null resolution, can't do anything" );
169+ return ;
170+ }
171+
172+ try {
173+ startIntentSenderForResult (resolution .getPendingIntent ().getIntentSender (),
174+ resolution .getRequestCode (), null , 0 , 0 , 0 );
175+ } catch (IntentSender .SendIntentException e ) {
176+ Log .e (TAG , "Failed to send resolution." , e );
177+
178+ IdpResponse errorResponse = IdpResponse .fromError (
179+ new FirebaseUiException (ErrorCodes .UNKNOWN_ERROR , getString (R .string .fui_general_error ), e ));
180+ finish (RESULT_OK , errorResponse .toIntent ());
181+ }
182+ }
183+
184+ private void onForgotPasswordClicked () {
185+ startActivity (RecoverPasswordActivity .createIntent (
186+ this ,
187+ getFlowParams (),
188+ mEmail ));
189+ }
190+
124191 @ Override
125192 public void onDonePressed () {
126193 validateAndSignIn ();
@@ -138,64 +205,18 @@ private void validateAndSignIn(final String email, final String password) {
138205 } else {
139206 mPasswordLayout .setError (null );
140207 }
141- getDialogHolder ().showLoadingDialog (R .string .fui_progress_dialog_signing_in );
142208
143- final AuthCredential authCredential = ProviderUtils .getAuthCredential (mIdpResponse );
209+ AuthCredential authCredential = ProviderUtils .getAuthCredential (mIdpResponse );
210+ mHandler .startSignIn (email , password , mIdpResponse , authCredential );
211+ }
144212
145- final IdpResponse response ;
146- if (authCredential == null ) {
147- response = new IdpResponse .Builder (
148- new User .Builder (EmailAuthProvider .PROVIDER_ID , email ).build ())
149- .build ();
150- } else {
151- response = new IdpResponse .Builder (mIdpResponse .getUser ())
152- .setToken (mIdpResponse .getIdpToken ())
153- .setSecret (mIdpResponse .getIdpSecret ())
154- .build ();
213+ @ Override
214+ public void onClick (View view ) {
215+ final int id = view .getId ();
216+ if (id == R .id .button_done ) {
217+ validateAndSignIn ();
218+ } else if (id == R .id .trouble_signing_in ) {
219+ onForgotPasswordClicked ();
155220 }
156-
157- // Sign in with known email and the password provided
158- getAuthHelper ().getFirebaseAuth ()
159- .signInWithEmailAndPassword (email , password )
160- .addOnSuccessListener (new OnSuccessListener <AuthResult >() {
161- @ Override
162- public void onSuccess (AuthResult authResult ) {
163- // If authCredential is null, the user only has an email account.
164- // Otherwise, the user has an email account that we need to link to an idp.
165- if (authCredential == null ) {
166- saveCredentialsOrFinish (
167- mSaveSmartLock ,
168- authResult .getUser (),
169- password ,
170- response );
171- } else {
172- authResult .getUser ()
173- .linkWithCredential (authCredential )
174- .continueWithTask (new ProfileMerger (response ))
175- .addOnFailureListener (new TaskFailureLogger (
176- TAG , "Error signing in with credential " +
177- authCredential .getProvider ()))
178- .addOnSuccessListener (new OnSuccessListener <AuthResult >() {
179- @ Override
180- public void onSuccess (AuthResult authResult ) {
181- saveCredentialsOrFinish (
182- mSaveSmartLock ,
183- authResult .getUser (),
184- response );
185- }
186- });
187- }
188- }
189- })
190- .addOnFailureListener (
191- new TaskFailureLogger (TAG , "Error signing in with email and password" ))
192- .addOnFailureListener (this , new OnFailureListener () {
193- @ Override
194- public void onFailure (@ NonNull Exception e ) {
195- getDialogHolder ().dismissDialog ();
196- String error = e .getLocalizedMessage ();
197- mPasswordLayout .setError (error );
198- }
199- });
200221 }
201222}
0 commit comments