Skip to content

Fix rotation bugs #1208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 14 additions & 27 deletions auth/src/main/java/com/firebase/ui/auth/data/model/Resource.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public final class Resource<T> {
private State mState;
private final boolean mUsable;

private final State mState;
private final T mValue;
private final Exception mException;

private Resource(State state, boolean usable, T value, Exception exception) {
private boolean mIsUsed;

private Resource(State state, T value, Exception exception) {
mState = state;
mUsable = usable;
mValue = value;
mException = exception;
}
Expand All @@ -30,47 +29,31 @@ private Resource(State state, boolean usable, T value, Exception exception) {
*/
@NonNull
public static Resource<Void> forVoidSuccess() {
return new Resource<>(State.SUCCESS, false, null, null);
return new Resource<>(State.SUCCESS, null, null);
}

/**
* Creates a successful resource containing a value.
*/
@NonNull
public static <T> Resource<T> forSuccess(@NonNull T value) {
return new Resource<>(State.SUCCESS, false, value, null);
}

/**
* Similar to {@link #forSuccess(Object)}, but this resource can be used up.
*/
@NonNull
public static <T> Resource<T> forUsableSuccess(@NonNull T value) {
return new Resource<>(State.SUCCESS, true, value, null);
return new Resource<>(State.SUCCESS, value, null);
}

/**
* Creates a failed resource with an exception.
*/
@NonNull
public static <T> Resource<T> forFailure(@NonNull Exception e) {
return new Resource<>(State.FAILURE, false, null, e);
}

/**
* Similar to {@link #forFailure(Exception)}, but this resource can be used up.
*/
@NonNull
public static <T> Resource<T> forUsableFailure(@NonNull Exception e) {
return new Resource<>(State.FAILURE, true, null, e);
return new Resource<>(State.FAILURE, null, e);
}

/**
* Creates a resource in the loading state, without a value or an exception.
*/
@NonNull
public static <T> Resource<T> forLoading() {
return new Resource<>(State.LOADING, false, null, null);
return new Resource<>(State.LOADING, null, null);
}

@NonNull
Expand All @@ -80,16 +63,20 @@ public State getState() {

@Nullable
public final Exception getException() {
if (mUsable) { mState = State.USED; }
mIsUsed = true;
return mException;
}

@Nullable
public T getValue() {
if (mUsable) { mState = State.USED; }
mIsUsed = true;
return mValue;
}

public boolean isUsed() {
return mIsUsed;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public enum State {
SUCCESS, FAILURE, LOADING, USED
SUCCESS, FAILURE, LOADING
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void startSignIn(@NonNull HelperActivityBase activity) {
}

private void start() {
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
GoogleSignIn.getClient(getApplication(), getSignInOptions()).getSignInIntent(),
RequestCodes.GOOGLE_PROVIDER)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
task.getResult(ApiException.class).getCredential());
} catch (ResolvableApiException e) {
if (e.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
setResult(Resource.<IdpResponse>forUsableFailure(
setResult(Resource.<IdpResponse>forFailure(
new PendingIntentRequiredException(
e.getResolution(), RequestCodes.CRED_HINT)));
} else {
Expand All @@ -99,12 +99,12 @@ private void startAuthMethodChoice() {
String firstProvider = firstIdpConfig.getProviderId();
switch (firstProvider) {
case EmailAuthProvider.PROVIDER_ID:
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
EmailActivity.createIntent(getApplication(), getArguments()),
RequestCodes.EMAIL_FLOW)));
break;
case PhoneAuthProvider.PROVIDER_ID:
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
PhoneActivity.createIntent(
getApplication(), getArguments(), firstIdpConfig.getParams()),
RequestCodes.PHONE_FLOW)));
Expand All @@ -114,7 +114,7 @@ private void startAuthMethodChoice() {
break;
}
} else {
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
AuthMethodPickerActivity.createIntent(getApplication(), getArguments()),
RequestCodes.AUTH_PICKER_FLOW)));
}
Expand All @@ -123,14 +123,14 @@ private void startAuthMethodChoice() {
private void redirectSignIn(String provider, String email) {
switch (provider) {
case EmailAuthProvider.PROVIDER_ID:
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
EmailActivity.createIntent(getApplication(), getArguments(), email),
RequestCodes.EMAIL_FLOW)));
break;
case GoogleAuthProvider.PROVIDER_ID:
case FacebookAuthProvider.PROVIDER_ID:
case TwitterAuthProvider.PROVIDER_ID:
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
SingleSignInActivity.createIntent(
getApplication(),
getArguments(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.firebase.ui.auth.ui.credentials;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
Expand All @@ -10,11 +9,12 @@
import android.util.Log;

import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.R;
import com.firebase.ui.auth.data.model.FlowParameters;
import com.firebase.ui.auth.data.model.Resource;
import com.firebase.ui.auth.ui.HelperActivityBase;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.ui.auth.util.ui.FlowUtils;
import com.firebase.ui.auth.viewmodel.VoidResourceObserver;
import com.firebase.ui.auth.viewmodel.smartlock.SmartLockHandler;
import com.google.android.gms.auth.api.credentials.Credential;

Expand Down Expand Up @@ -47,15 +47,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
Credential credential = getIntent().getParcelableExtra(ExtraConstants.CREDENTIAL);
mIdpResponse = getIntent().getParcelableExtra(ExtraConstants.IDP_RESPONSE);

mHandler.getOperation().observe(this, new Observer<Resource<Void>>() {
mHandler.getOperation().observe(this, new VoidResourceObserver(
this, R.string.fui_progress_dialog_loading) {
@Override
public void onChanged(@Nullable Resource<Void> resource) {
if (resource == null) {
Log.w(TAG, "getSaveOperation:onChanged:null");
return;
}
protected void onSuccess() {
finish(RESULT_OK, mIdpResponse.toIntent());
}

onSaveOperation(resource);
@Override
protected void onFailure(@NonNull Exception e) {
// RESULT_OK since we don't want to halt sign-in just because of a credential save
// error.
finish(RESULT_OK, mIdpResponse.toIntent());
}
});

Expand All @@ -74,18 +77,4 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mHandler.onActivityResult(requestCode, resultCode);
}

private void onSaveOperation(@NonNull Resource<Void> resource) {
switch (resource.getState()) {
case LOADING:
// No-op?
break;
case SUCCESS:
case FAILURE:
if (FlowUtils.unhandled(this, resource.getException())) {
finish(RESULT_OK, mIdpResponse.toIntent());
}
break;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public final void onChanged(Resource<T> resource) {
}
mActivity.getDialogHolder().dismissDialog();

if (resource.isUsed()) { return; }

if (resource.getState() == State.SUCCESS) {
onSuccess(resource.getValue());
} else if (resource.getState() == State.FAILURE) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.firebase.ui.auth.viewmodel;

import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.annotation.StringRes;

import com.firebase.ui.auth.ui.HelperActivityBase;

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public abstract class VoidResourceObserver extends ResourceObserver<Void> {
protected VoidResourceObserver(@NonNull HelperActivityBase activity, @StringRes int message) {
super(activity, message);
}

@Override
protected final void onSuccess(@NonNull Void aVoid) {
onSuccess();
}

protected abstract void onSuccess();
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public void onFailure(@NonNull Exception e) {
setResult(Resource.<IdpResponse>forFailure(e));
}
});
return;
}
} else {
setResult(Resource.<IdpResponse>forFailure(e));
}
setResult(Resource.<IdpResponse>forFailure(e));
}
});
}
Expand Down Expand Up @@ -109,7 +109,7 @@ public void onSuccess(String provider) {

if (provider.equals(EmailAuthProvider.PROVIDER_ID)) {
// Start email welcome back flow
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
WelcomeBackPasswordPrompt.createIntent(
getApplication(),
getArguments(),
Expand All @@ -118,7 +118,7 @@ public void onSuccess(String provider) {
)));
} else {
// Start Idp welcome back flow
setResult(Resource.<IdpResponse>forUsableFailure(new IntentRequiredException(
setResult(Resource.<IdpResponse>forFailure(new IntentRequiredException(
WelcomeBackIdpPrompt.createIntent(
getApplication(),
getArguments(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void onComplete(@NonNull Task<Void> task) {
setResult(Resource.forVoidSuccess());
} else if (task.getException() instanceof ResolvableApiException) {
ResolvableApiException rae = (ResolvableApiException) task.getException();
setResult(Resource.<Void>forUsableFailure(
setResult(Resource.<Void>forFailure(
new PendingIntentRequiredException(
rae.getResolution(), RequestCodes.CRED_SAVE)));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ public static <T> ArgumentMatcher<Resource<T>> isFailure() {
return isState(State.FAILURE);
}

public static <T> ArgumentMatcher<Resource<T>> isUsed() {
return isState(State.USED);
}

public static <T> ArgumentMatcher<Resource<T>> isSuccessWith(final T result) {
return new ArgumentMatcher<Resource<T>>() {
@Override
Expand Down