From 4c537f53f549cd1f96d1ac8c3e7eac5c9e4a7990 Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Mon, 22 Oct 2018 13:59:39 +0700 Subject: [PATCH 1/8] Proposal - API for Custom Layout for AuthMethodPickerActivity --- .../java/com/firebase/ui/auth/AuthLayout.java | 122 ++++++++++++++++++ .../java/com/firebase/ui/auth/AuthUI.java | 10 +- .../ui/auth/data/model/FlowParameters.java | 13 +- .../java/com/firebase/ui/auth/AuthUITest.java | 16 +++ .../ui/auth/testhelpers/TestHelper.java | 3 +- 5 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 auth/src/main/java/com/firebase/ui/auth/AuthLayout.java diff --git a/auth/src/main/java/com/firebase/ui/auth/AuthLayout.java b/auth/src/main/java/com/firebase/ui/auth/AuthLayout.java new file mode 100644 index 000000000..d1db0b801 --- /dev/null +++ b/auth/src/main/java/com/firebase/ui/auth/AuthLayout.java @@ -0,0 +1,122 @@ +package com.firebase.ui.auth; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.IdRes; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import com.google.firebase.auth.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * Layout model to help customizing the AuthPicker + */ +public class AuthLayout implements Parcelable { + + @LayoutRes + private int mainLayout; + + /** + * PROVIDER_ID -> IdRes of the Button + */ + private Map providersButton; + + private AuthLayout() { + } + + private AuthLayout(@NonNull Parcel in) { + this.mainLayout = in.readInt(); + Bundle buttonsBundle = in.readBundle(getClass().getClassLoader()); + this.providersButton = new HashMap<>(); + + for (String key : buttonsBundle.keySet()) { + this.providersButton.put(key, buttonsBundle.getInt(key)); + } + } + + public int getMainLayout() { + return mainLayout; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeInt(mainLayout); + + Bundle bundle = new Bundle(); + for (String key : providersButton.keySet()) { + bundle.putInt(key, providersButton.get(key)); + } + parcel.writeBundle(bundle); + } + + public static final Creator CREATOR = new Creator() { + + @Override + public AuthLayout createFromParcel(Parcel in) { + return new AuthLayout(in); + } + + @Override + public AuthLayout[] newArray(int size) { + return new AuthLayout[size]; + } + }; + + /** + * Builder for AuthLayout + */ + public static class Builder { + + private Map providersMapping; + private AuthLayout instance; + + public Builder(@LayoutRes int mainLayout) { + instance = new AuthLayout(); + instance.mainLayout = mainLayout; + providersMapping = new HashMap<>(); + } + + public AuthLayout.Builder setupGoogleButton(@IdRes int googleBtn) { + providersMapping.put(GoogleAuthProvider.PROVIDER_ID, googleBtn); + return this; + } + + public AuthLayout.Builder setupFacebookButton(@IdRes int facebookBtn) { + providersMapping.put(FacebookAuthProvider.PROVIDER_ID, facebookBtn); + return this; + } + + public AuthLayout.Builder setupTwitterButton(@IdRes int twitterBtn) { + providersMapping.put(TwitterAuthProvider.PROVIDER_ID, twitterBtn); + return this; + } + + public AuthLayout.Builder setupEmailButton(@IdRes int emailButton) { + providersMapping.put(EmailAuthProvider.PROVIDER_ID, emailButton); + return this; + } + + public AuthLayout.Builder setupPhoneButton(@IdRes int phoneButton) { + providersMapping.put(PhoneAuthProvider.PROVIDER_ID, phoneButton); + return this; + } + + public AuthLayout.Builder setupAnonymousButton(@IdRes int anonymousButton) { + providersMapping.put(AuthUI.ANONYMOUS_PROVIDER, anonymousButton); + return this; + } + + public AuthLayout build() { + instance.providersButton = providersMapping; + return instance; + } + } +} diff --git a/auth/src/main/java/com/firebase/ui/auth/AuthUI.java b/auth/src/main/java/com/firebase/ui/auth/AuthUI.java index 488c1777b..cde179f08 100644 --- a/auth/src/main/java/com/firebase/ui/auth/AuthUI.java +++ b/auth/src/main/java/com/firebase/ui/auth/AuthUI.java @@ -1027,6 +1027,7 @@ private abstract class AuthIntentBuilder { String mPrivacyPolicyUrl; boolean mEnableCredentials = true; boolean mEnableHints = true; + AuthLayout mCustomLayout = null; /** * Specifies the theme to use for the application flow. If no theme is specified, a @@ -1156,6 +1157,12 @@ public T setIsSmartLockEnabled(boolean enableCredentials, boolean enableHints) { return (T) this; } + @NonNull + public T setCustomLayout(@NonNull AuthLayout customLayout) { + mCustomLayout = customLayout; + return (T) this; + } + @CallSuper @NonNull public Intent build() { @@ -1201,7 +1208,8 @@ protected FlowParameters getFlowParams() { mPrivacyPolicyUrl, mEnableCredentials, mEnableHints, - mEnableAnonymousUpgrade); + mEnableAnonymousUpgrade, + mCustomLayout); } } } diff --git a/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java b/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java index ee088ebfc..2a45d7b69 100644 --- a/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java +++ b/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java @@ -23,6 +23,7 @@ import android.support.annotation.StyleRes; import android.text.TextUtils; +import com.firebase.ui.auth.AuthLayout; import com.firebase.ui.auth.AuthUI.IdpConfig; import com.firebase.ui.auth.util.ExtraConstants; import com.firebase.ui.auth.util.Preconditions; @@ -58,6 +59,9 @@ public class FlowParameters implements Parcelable { public final boolean enableHints; public final boolean enableAnonymousUpgrade; + @Nullable + public final AuthLayout customLayout; + public FlowParameters( @NonNull String appName, @NonNull List providers, @@ -67,7 +71,8 @@ public FlowParameters( @Nullable String privacyPolicyUrl, boolean enableCredentials, boolean enableHints, - boolean enableAnonymousUpgrade) { + boolean enableAnonymousUpgrade, + @Nullable AuthLayout customLayout) { this.appName = Preconditions.checkNotNull(appName, "appName cannot be null"); this.providers = Collections.unmodifiableList( Preconditions.checkNotNull(providers, "providers cannot be null")); @@ -78,6 +83,7 @@ public FlowParameters( this.enableCredentials = enableCredentials; this.enableHints = enableHints; this.enableAnonymousUpgrade = enableAnonymousUpgrade; + this.customLayout = customLayout; } /** @@ -98,6 +104,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(enableCredentials ? 1 : 0); dest.writeInt(enableHints ? 1 : 0); dest.writeInt(enableAnonymousUpgrade ? 1 : 0); + dest.writeParcelable(customLayout, flags); } @Override @@ -117,6 +124,7 @@ public FlowParameters createFromParcel(Parcel in) { boolean enableCredentials = in.readInt() != 0; boolean enableHints = in.readInt() != 0; boolean enableAnonymousUpgrade = in.readInt() != 0; + AuthLayout customLayout = in.readParcelable(AuthLayout.class.getClassLoader()); return new FlowParameters( appName, @@ -127,7 +135,8 @@ public FlowParameters createFromParcel(Parcel in) { privacyPolicyUrl, enableCredentials, enableHints, - enableAnonymousUpgrade); + enableAnonymousUpgrade, + customLayout); } @Override diff --git a/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java b/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java index f5ef5d526..5986ac05b 100644 --- a/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java +++ b/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java @@ -216,4 +216,20 @@ public void testAnonymousBuilder_expectSucess() { .build(); } + @Test + public void testCustomAuthLayout() { + //Testing with some random layout res + AuthLayout customLayout = new AuthLayout + .Builder(R.layout.fui_phone_layout) + .build(); + + FlowParameters flowParameters = mAuthUi + .createSignInIntentBuilder() + .setCustomLayout(customLayout) + .build() + .getParcelableExtra(ExtraConstants.FLOW_PARAMS); + + assert flowParameters.customLayout != null; + assertEquals(customLayout.getMainLayout(), flowParameters.customLayout.getMainLayout()); + } } diff --git a/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java b/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java index 6ca3d5fa5..e99dc51d6 100644 --- a/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java +++ b/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java @@ -142,7 +142,8 @@ public static FlowParameters getFlowParameters(Collection providerIds, null, true, true, - enableAnonymousUpgrade); + enableAnonymousUpgrade, + null); } From 164218df53caa6bead0f24850fe32dc2dcac7d7a Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Mon, 22 Oct 2018 20:05:29 +0700 Subject: [PATCH 2/8] Proposal - Implementation for AuthMethodPickerLayout --- ...ayout.java => AuthMethodPickerLayout.java} | 50 +++-- .../java/com/firebase/ui/auth/AuthUI.java | 8 +- .../ui/auth/data/model/FlowParameters.java | 12 +- .../auth/ui/idp/AuthMethodPickerActivity.java | 179 +++++++++++++++--- .../java/com/firebase/ui/auth/AuthUITest.java | 10 +- 5 files changed, 193 insertions(+), 66 deletions(-) rename auth/src/main/java/com/firebase/ui/auth/{AuthLayout.java => AuthMethodPickerLayout.java} (59%) diff --git a/auth/src/main/java/com/firebase/ui/auth/AuthLayout.java b/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java similarity index 59% rename from auth/src/main/java/com/firebase/ui/auth/AuthLayout.java rename to auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java index d1db0b801..93cbd0740 100644 --- a/auth/src/main/java/com/firebase/ui/auth/AuthLayout.java +++ b/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java @@ -8,13 +8,12 @@ import android.support.annotation.NonNull; import com.google.firebase.auth.*; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Layout model to help customizing the AuthPicker */ -public class AuthLayout implements Parcelable { +public class AuthMethodPickerLayout implements Parcelable { @LayoutRes private int mainLayout; @@ -24,10 +23,10 @@ public class AuthLayout implements Parcelable { */ private Map providersButton; - private AuthLayout() { + private AuthMethodPickerLayout() { } - private AuthLayout(@NonNull Parcel in) { + private AuthMethodPickerLayout(@NonNull Parcel in) { this.mainLayout = in.readInt(); Bundle buttonsBundle = in.readBundle(getClass().getClassLoader()); this.providersButton = new HashMap<>(); @@ -37,10 +36,15 @@ private AuthLayout(@NonNull Parcel in) { } } + @LayoutRes public int getMainLayout() { return mainLayout; } + public Map getProvidersButton() { + return providersButton; + } + @Override public int describeContents() { return 0; @@ -57,64 +61,70 @@ public void writeToParcel(Parcel parcel, int flags) { parcel.writeBundle(bundle); } - public static final Creator CREATOR = new Creator() { + public static final Creator CREATOR = new Creator() { @Override - public AuthLayout createFromParcel(Parcel in) { - return new AuthLayout(in); + public AuthMethodPickerLayout createFromParcel(Parcel in) { + return new AuthMethodPickerLayout(in); } @Override - public AuthLayout[] newArray(int size) { - return new AuthLayout[size]; + public AuthMethodPickerLayout[] newArray(int size) { + return new AuthMethodPickerLayout[size]; } }; /** - * Builder for AuthLayout + * Builder for AuthMethodPickerLayout */ public static class Builder { private Map providersMapping; - private AuthLayout instance; + private AuthMethodPickerLayout instance; public Builder(@LayoutRes int mainLayout) { - instance = new AuthLayout(); + instance = new AuthMethodPickerLayout(); instance.mainLayout = mainLayout; providersMapping = new HashMap<>(); } - public AuthLayout.Builder setupGoogleButton(@IdRes int googleBtn) { + public AuthMethodPickerLayout.Builder setupGoogleButtonId(@IdRes int googleBtn) { providersMapping.put(GoogleAuthProvider.PROVIDER_ID, googleBtn); return this; } - public AuthLayout.Builder setupFacebookButton(@IdRes int facebookBtn) { + public AuthMethodPickerLayout.Builder setupFacebookButtonId(@IdRes int facebookBtn) { providersMapping.put(FacebookAuthProvider.PROVIDER_ID, facebookBtn); return this; } - public AuthLayout.Builder setupTwitterButton(@IdRes int twitterBtn) { + public AuthMethodPickerLayout.Builder setupTwitterButtonId(@IdRes int twitterBtn) { providersMapping.put(TwitterAuthProvider.PROVIDER_ID, twitterBtn); return this; } - public AuthLayout.Builder setupEmailButton(@IdRes int emailButton) { + public AuthMethodPickerLayout.Builder setupEmailButtonId(@IdRes int emailButton) { providersMapping.put(EmailAuthProvider.PROVIDER_ID, emailButton); return this; } - public AuthLayout.Builder setupPhoneButton(@IdRes int phoneButton) { + public AuthMethodPickerLayout.Builder setupPhoneButtonId(@IdRes int phoneButton) { providersMapping.put(PhoneAuthProvider.PROVIDER_ID, phoneButton); return this; } - public AuthLayout.Builder setupAnonymousButton(@IdRes int anonymousButton) { + public AuthMethodPickerLayout.Builder setupAnonymousButtonId(@IdRes int anonymousButton) { providersMapping.put(AuthUI.ANONYMOUS_PROVIDER, anonymousButton); return this; } - public AuthLayout build() { + public AuthMethodPickerLayout build() { + //Validating the button set + for (String key : providersMapping.keySet()) { + if (AuthUI.SUPPORTED_PROVIDERS.contains(key)) { + throw new IllegalArgumentException("Unknown provider: " + key); + } + } instance.providersButton = providersMapping; return instance; } diff --git a/auth/src/main/java/com/firebase/ui/auth/AuthUI.java b/auth/src/main/java/com/firebase/ui/auth/AuthUI.java index cde179f08..aba7eeaa6 100644 --- a/auth/src/main/java/com/firebase/ui/auth/AuthUI.java +++ b/auth/src/main/java/com/firebase/ui/auth/AuthUI.java @@ -1027,7 +1027,7 @@ private abstract class AuthIntentBuilder { String mPrivacyPolicyUrl; boolean mEnableCredentials = true; boolean mEnableHints = true; - AuthLayout mCustomLayout = null; + AuthMethodPickerLayout mAuthMethodPickerLayout = null; /** * Specifies the theme to use for the application flow. If no theme is specified, a @@ -1158,8 +1158,8 @@ public T setIsSmartLockEnabled(boolean enableCredentials, boolean enableHints) { } @NonNull - public T setCustomLayout(@NonNull AuthLayout customLayout) { - mCustomLayout = customLayout; + public T setAuthMethodPickerLayout(@NonNull AuthMethodPickerLayout authMethodPickerLayout) { + mAuthMethodPickerLayout = authMethodPickerLayout; return (T) this; } @@ -1209,7 +1209,7 @@ protected FlowParameters getFlowParams() { mEnableCredentials, mEnableHints, mEnableAnonymousUpgrade, - mCustomLayout); + mAuthMethodPickerLayout); } } } diff --git a/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java b/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java index 2a45d7b69..c7ba1688d 100644 --- a/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java +++ b/auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java @@ -23,7 +23,7 @@ import android.support.annotation.StyleRes; import android.text.TextUtils; -import com.firebase.ui.auth.AuthLayout; +import com.firebase.ui.auth.AuthMethodPickerLayout; import com.firebase.ui.auth.AuthUI.IdpConfig; import com.firebase.ui.auth.util.ExtraConstants; import com.firebase.ui.auth.util.Preconditions; @@ -60,7 +60,7 @@ public class FlowParameters implements Parcelable { public final boolean enableAnonymousUpgrade; @Nullable - public final AuthLayout customLayout; + public final AuthMethodPickerLayout authMethodPickerLayout; public FlowParameters( @NonNull String appName, @@ -72,7 +72,7 @@ public FlowParameters( boolean enableCredentials, boolean enableHints, boolean enableAnonymousUpgrade, - @Nullable AuthLayout customLayout) { + @Nullable AuthMethodPickerLayout authMethodPickerLayout) { this.appName = Preconditions.checkNotNull(appName, "appName cannot be null"); this.providers = Collections.unmodifiableList( Preconditions.checkNotNull(providers, "providers cannot be null")); @@ -83,7 +83,7 @@ public FlowParameters( this.enableCredentials = enableCredentials; this.enableHints = enableHints; this.enableAnonymousUpgrade = enableAnonymousUpgrade; - this.customLayout = customLayout; + this.authMethodPickerLayout = authMethodPickerLayout; } /** @@ -104,7 +104,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(enableCredentials ? 1 : 0); dest.writeInt(enableHints ? 1 : 0); dest.writeInt(enableAnonymousUpgrade ? 1 : 0); - dest.writeParcelable(customLayout, flags); + dest.writeParcelable(authMethodPickerLayout, flags); } @Override @@ -124,7 +124,7 @@ public FlowParameters createFromParcel(Parcel in) { boolean enableCredentials = in.readInt() != 0; boolean enableHints = in.readInt() != 0; boolean enableAnonymousUpgrade = in.readInt() != 0; - AuthLayout customLayout = in.readParcelable(AuthLayout.class.getClassLoader()); + AuthMethodPickerLayout customLayout = in.readParcelable(AuthMethodPickerLayout.class.getClassLoader()); return new FlowParameters( appName, 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 3ed8b5553..cc3bf3501 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 @@ -19,10 +19,7 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.support.annotation.LayoutRes; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.RestrictTo; +import android.support.annotation.*; import android.support.constraint.ConstraintLayout; import android.support.constraint.ConstraintSet; import android.view.View; @@ -32,13 +29,8 @@ import android.widget.TextView; import android.widget.Toast; -import com.firebase.ui.auth.AuthUI; +import com.firebase.ui.auth.*; import com.firebase.ui.auth.AuthUI.IdpConfig; -import com.firebase.ui.auth.ErrorCodes; -import com.firebase.ui.auth.FirebaseAuthAnonymousUpgradeException; -import com.firebase.ui.auth.FirebaseUiException; -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.UserCancellationException; import com.firebase.ui.auth.data.remote.AnonymousSignInHandler; @@ -62,6 +54,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; /** Presents the list of authentication options for this app to the user. */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @@ -73,6 +66,8 @@ public class AuthMethodPickerActivity extends AppCompatBase { private ProgressBar mProgressBar; private ViewGroup mProviderHolder; + private AuthMethodPickerLayout customLayout; + public static Intent createIntent(Context context, FlowParameters flowParams) { return createBaseIntent(context, AuthMethodPickerActivity.class, flowParams); } @@ -80,32 +75,51 @@ public static Intent createIntent(Context context, FlowParameters flowParams) { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.fui_auth_method_picker_layout); - - mProgressBar = findViewById(R.id.top_progress_bar); - mProviderHolder = findViewById(R.id.btn_holder); FlowParameters params = getFlowParams(); + customLayout = params.authMethodPickerLayout; + mHandler = ViewModelProviders.of(this).get(SocialProviderResponseHandler.class); mHandler.init(params); - populateIdpList(params.providers, mHandler); + if (customLayout != null) { + setContentView(customLayout.getMainLayout()); - int logoId = params.logoId; - if (logoId == AuthUI.NO_LOGO) { - findViewById(R.id.logo).setVisibility(View.GONE); + //Setup using custom layout + populateIdpListCustomLayout(params.providers, mHandler); - ConstraintLayout layout = findViewById(R.id.root); - ConstraintSet constraints = new ConstraintSet(); - constraints.clone(layout); - constraints.setHorizontalBias(R.id.container, 0.5f); - constraints.setVerticalBias(R.id.container, 0.5f); - constraints.applyTo(layout); } else { - ImageView logo = findViewById(R.id.logo); - logo.setImageResource(logoId); + setContentView(R.layout.fui_auth_method_picker_layout); + + //UI only with default layout + mProgressBar = findViewById(R.id.top_progress_bar); + mProviderHolder = findViewById(R.id.btn_holder); + + + populateIdpList(params.providers, mHandler); + + int logoId = params.logoId; + if (logoId == AuthUI.NO_LOGO) { + findViewById(R.id.logo).setVisibility(View.GONE); + + ConstraintLayout layout = findViewById(R.id.root); + ConstraintSet constraints = new ConstraintSet(); + constraints.clone(layout); + constraints.setHorizontalBias(R.id.container, 0.5f); + constraints.setVerticalBias(R.id.container, 0.5f); + constraints.applyTo(layout); + } else { + ImageView logo = findViewById(R.id.logo); + logo.setImageResource(logoId); + } + + TextView termsText = findViewById(R.id.main_tos_and_pp); + PrivacyDisclosureUtils.setupTermsOfServiceAndPrivacyPolicyText(this, + getFlowParams(), + termsText); } + //Handler for both mHandler.getOperation().observe(this, new ResourceObserver( this, R.string.fui_progress_dialog_signing_in) { @Override @@ -127,11 +141,6 @@ protected void onFailure(@NonNull Exception e) { } } }); - - TextView termsText = findViewById(R.id.main_tos_and_pp); - PrivacyDisclosureUtils.setupTermsOfServiceAndPrivacyPolicyText(this, - getFlowParams(), - termsText); } private void populateIdpList(List providerConfigs, @@ -244,6 +253,114 @@ public void onClick(View view) { } } + /** + * This function is very similar with poplulateIdpList, but specifically made for custom layout + */ + private void populateIdpListCustomLayout(List providerConfigs, + final SocialProviderResponseHandler handler) { + ViewModelProvider supplier = ViewModelProviders.of(this); + + Map providerButtonIds = customLayout.getProvidersButton(); + mProviders = new ArrayList<>(); + for (IdpConfig idpConfig : providerConfigs) { + final ProviderSignInBase provider; + + final String providerId = idpConfig.getProviderId(); + @IdRes int buttonId = providerButtonIds.get(providerId); + + switch (providerId) { + case GoogleAuthProvider.PROVIDER_ID: + GoogleSignInHandler google = supplier.get(GoogleSignInHandler.class); + google.init(new GoogleSignInHandler.Params(idpConfig)); + provider = google; + + break; + case FacebookAuthProvider.PROVIDER_ID: + FacebookSignInHandler facebook = supplier.get(FacebookSignInHandler.class); + facebook.init(idpConfig); + provider = facebook; + + break; + case TwitterAuthProvider.PROVIDER_ID: + TwitterSignInHandler twitter = supplier.get(TwitterSignInHandler.class); + twitter.init(null); + provider = twitter; + + break; + case GithubAuthProvider.PROVIDER_ID: + ProviderSignInBase github = + supplier.get(GitHubSignInHandlerBridge.HANDLER_CLASS); + github.init(idpConfig); + provider = github; + + break; + case EmailAuthProvider.PROVIDER_ID: + EmailSignInHandler email = supplier.get(EmailSignInHandler.class); + email.init(null); + provider = email; + + break; + case PhoneAuthProvider.PROVIDER_ID: + PhoneSignInHandler phone = supplier.get(PhoneSignInHandler.class); + phone.init(idpConfig); + provider = phone; + + break; + case AuthUI.ANONYMOUS_PROVIDER: + AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class); + anonymous.init(getFlowParams()); + provider = anonymous; + + break; + default: + throw new IllegalStateException("Unknown provider: " + providerId); + } + mProviders.add(provider); + + provider.getOperation().observe(this, new ResourceObserver(this) { + @Override + protected void onSuccess(@NonNull IdpResponse response) { + handleResponse(response); + } + + @Override + protected void onFailure(@NonNull Exception e) { + handleResponse(IdpResponse.from(e)); + } + + private void handleResponse(@NonNull IdpResponse response) { + if (!response.isSuccessful()) { + // We have no idea what provider this error stemmed from so just forward + // this along to the handler. + handler.startSignIn(response); + } else if (AuthUI.SOCIAL_PROVIDERS.contains(providerId)) { + // Don't use the response's provider since it can be different than the one + // that launched the sign-in attempt. Ex: the email flow is started, but + // ends up turning into a Google sign-in because that account already + // existed. In the previous example, an extra sign-in would incorrectly + // started. + handler.startSignIn(response); + } else { + // Email or phone: the credentials should have already been saved so + // simply move along. Anononymous sign in also does not require any + // other operations. + finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED, + response.toIntent()); + } + } + }); + + View loginButton = findViewById(buttonId); + loginButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + provider.startSignIn(AuthMethodPickerActivity.this); + } + }); + mProviderHolder.addView(loginButton); + } + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java b/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java index 5986ac05b..e2a7c1367 100644 --- a/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java +++ b/auth/src/test/java/com/firebase/ui/auth/AuthUITest.java @@ -217,19 +217,19 @@ public void testAnonymousBuilder_expectSucess() { } @Test - public void testCustomAuthLayout() { + public void testCustomAuthMethodPickerLayout() { //Testing with some random layout res - AuthLayout customLayout = new AuthLayout + AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout .Builder(R.layout.fui_phone_layout) .build(); FlowParameters flowParameters = mAuthUi .createSignInIntentBuilder() - .setCustomLayout(customLayout) + .setAuthMethodPickerLayout(customLayout) .build() .getParcelableExtra(ExtraConstants.FLOW_PARAMS); - assert flowParameters.customLayout != null; - assertEquals(customLayout.getMainLayout(), flowParameters.customLayout.getMainLayout()); + assert flowParameters.authMethodPickerLayout != null; + assertEquals(customLayout.getMainLayout(), flowParameters.authMethodPickerLayout.getMainLayout()); } } From c8f66046ca41e7397f8abfae99dc1e9de4cccc1b Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Mon, 22 Oct 2018 22:44:46 +0700 Subject: [PATCH 3/8] Revised AuthMethodPickerActivity, separating operation handler --- .../auth/ui/idp/AuthMethodPickerActivity.java | 260 +++++++----------- 1 file changed, 96 insertions(+), 164 deletions(-) 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 cc3bf3501..f00e6316a 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 @@ -145,220 +145,152 @@ protected void onFailure(@NonNull Exception e) { private void populateIdpList(List providerConfigs, final SocialProviderResponseHandler handler) { - ViewModelProvider supplier = ViewModelProviders.of(this); - mProviders = new ArrayList<>(); for (IdpConfig idpConfig : providerConfigs) { - final ProviderSignInBase provider; @LayoutRes int buttonLayout; final String providerId = idpConfig.getProviderId(); switch (providerId) { case GoogleAuthProvider.PROVIDER_ID: - GoogleSignInHandler google = supplier.get(GoogleSignInHandler.class); - google.init(new GoogleSignInHandler.Params(idpConfig)); - provider = google; - buttonLayout = R.layout.fui_idp_button_google; break; case FacebookAuthProvider.PROVIDER_ID: - FacebookSignInHandler facebook = supplier.get(FacebookSignInHandler.class); - facebook.init(idpConfig); - provider = facebook; - buttonLayout = R.layout.fui_idp_button_facebook; break; case TwitterAuthProvider.PROVIDER_ID: - TwitterSignInHandler twitter = supplier.get(TwitterSignInHandler.class); - twitter.init(null); - provider = twitter; - buttonLayout = R.layout.fui_idp_button_twitter; break; case GithubAuthProvider.PROVIDER_ID: - ProviderSignInBase github = - supplier.get(GitHubSignInHandlerBridge.HANDLER_CLASS); - github.init(idpConfig); - provider = github; - buttonLayout = R.layout.fui_idp_button_github; break; case EmailAuthProvider.PROVIDER_ID: - EmailSignInHandler email = supplier.get(EmailSignInHandler.class); - email.init(null); - provider = email; - buttonLayout = R.layout.fui_provider_button_email; break; case PhoneAuthProvider.PROVIDER_ID: - PhoneSignInHandler phone = supplier.get(PhoneSignInHandler.class); - phone.init(idpConfig); - provider = phone; - buttonLayout = R.layout.fui_provider_button_phone; break; case AuthUI.ANONYMOUS_PROVIDER: - AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class); - anonymous.init(getFlowParams()); - provider = anonymous; - buttonLayout = R.layout.fui_provider_button_anonymous; break; default: throw new IllegalStateException("Unknown provider: " + providerId); } - mProviders.add(provider); - - provider.getOperation().observe(this, new ResourceObserver(this) { - @Override - protected void onSuccess(@NonNull IdpResponse response) { - handleResponse(response); - } - - @Override - protected void onFailure(@NonNull Exception e) { - handleResponse(IdpResponse.from(e)); - } - - private void handleResponse(@NonNull IdpResponse response) { - if (!response.isSuccessful()) { - // We have no idea what provider this error stemmed from so just forward - // this along to the handler. - handler.startSignIn(response); - } else if (AuthUI.SOCIAL_PROVIDERS.contains(providerId)) { - // Don't use the response's provider since it can be different than the one - // that launched the sign-in attempt. Ex: the email flow is started, but - // ends up turning into a Google sign-in because that account already - // existed. In the previous example, an extra sign-in would incorrectly - // started. - handler.startSignIn(response); - } else { - // Email or phone: the credentials should have already been saved so - // simply move along. Anononymous sign in also does not require any - // other operations. - finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED, - response.toIntent()); - } - } - }); View loginButton = getLayoutInflater().inflate(buttonLayout, mProviderHolder, false); - loginButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - provider.startSignIn(AuthMethodPickerActivity.this); - } - }); + handleSignInOperation(idpConfig, loginButton, handler); mProviderHolder.addView(loginButton); } } - /** - * This function is very similar with poplulateIdpList, but specifically made for custom layout - */ private void populateIdpListCustomLayout(List providerConfigs, final SocialProviderResponseHandler handler) { - ViewModelProvider supplier = ViewModelProviders.of(this); - Map providerButtonIds = customLayout.getProvidersButton(); mProviders = new ArrayList<>(); for (IdpConfig idpConfig : providerConfigs) { - final ProviderSignInBase provider; - final String providerId = idpConfig.getProviderId(); @IdRes int buttonId = providerButtonIds.get(providerId); + View loginButton = findViewById(buttonId); + if (loginButton == null) { + throw new IllegalStateException("No button found for this auth provider"); + } - switch (providerId) { - case GoogleAuthProvider.PROVIDER_ID: - GoogleSignInHandler google = supplier.get(GoogleSignInHandler.class); - google.init(new GoogleSignInHandler.Params(idpConfig)); - provider = google; - - break; - case FacebookAuthProvider.PROVIDER_ID: - FacebookSignInHandler facebook = supplier.get(FacebookSignInHandler.class); - facebook.init(idpConfig); - provider = facebook; - - break; - case TwitterAuthProvider.PROVIDER_ID: - TwitterSignInHandler twitter = supplier.get(TwitterSignInHandler.class); - twitter.init(null); - provider = twitter; - - break; - case GithubAuthProvider.PROVIDER_ID: - ProviderSignInBase github = - supplier.get(GitHubSignInHandlerBridge.HANDLER_CLASS); - github.init(idpConfig); - provider = github; - - break; - case EmailAuthProvider.PROVIDER_ID: - EmailSignInHandler email = supplier.get(EmailSignInHandler.class); - email.init(null); - provider = email; - - break; - case PhoneAuthProvider.PROVIDER_ID: - PhoneSignInHandler phone = supplier.get(PhoneSignInHandler.class); - phone.init(idpConfig); - provider = phone; + handleSignInOperation(idpConfig, loginButton, handler); + } + } - break; - case AuthUI.ANONYMOUS_PROVIDER: - AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class); - anonymous.init(getFlowParams()); - provider = anonymous; + private void handleSignInOperation(IdpConfig idpConfig, View view, + final SocialProviderResponseHandler handler) { + ViewModelProvider supplier = ViewModelProviders.of(this); + final String providerId = idpConfig.getProviderId(); + final ProviderSignInBase provider; + + switch (providerId) { + case GoogleAuthProvider.PROVIDER_ID: + GoogleSignInHandler google = supplier.get(GoogleSignInHandler.class); + google.init(new GoogleSignInHandler.Params(idpConfig)); + provider = google; + + break; + case FacebookAuthProvider.PROVIDER_ID: + FacebookSignInHandler facebook = supplier.get(FacebookSignInHandler.class); + facebook.init(idpConfig); + provider = facebook; + + break; + case TwitterAuthProvider.PROVIDER_ID: + TwitterSignInHandler twitter = supplier.get(TwitterSignInHandler.class); + twitter.init(null); + provider = twitter; + + break; + case GithubAuthProvider.PROVIDER_ID: + ProviderSignInBase github = + supplier.get(GitHubSignInHandlerBridge.HANDLER_CLASS); + github.init(idpConfig); + provider = github; + + break; + case EmailAuthProvider.PROVIDER_ID: + EmailSignInHandler email = supplier.get(EmailSignInHandler.class); + email.init(null); + provider = email; + + break; + case PhoneAuthProvider.PROVIDER_ID: + PhoneSignInHandler phone = supplier.get(PhoneSignInHandler.class); + phone.init(idpConfig); + provider = phone; + + break; + case AuthUI.ANONYMOUS_PROVIDER: + AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class); + anonymous.init(getFlowParams()); + provider = anonymous; + + break; + default: + throw new IllegalStateException("Unknown provider: " + providerId); + } + mProviders.add(provider); - break; - default: - throw new IllegalStateException("Unknown provider: " + providerId); + provider.getOperation().observe(this, new ResourceObserver(this) { + @Override + protected void onSuccess(@NonNull IdpResponse response) { + handleResponse(response); } - mProviders.add(provider); - provider.getOperation().observe(this, new ResourceObserver(this) { - @Override - protected void onSuccess(@NonNull IdpResponse response) { - handleResponse(response); - } - - @Override - protected void onFailure(@NonNull Exception e) { - handleResponse(IdpResponse.from(e)); - } - - private void handleResponse(@NonNull IdpResponse response) { - if (!response.isSuccessful()) { - // We have no idea what provider this error stemmed from so just forward - // this along to the handler. - handler.startSignIn(response); - } else if (AuthUI.SOCIAL_PROVIDERS.contains(providerId)) { - // Don't use the response's provider since it can be different than the one - // that launched the sign-in attempt. Ex: the email flow is started, but - // ends up turning into a Google sign-in because that account already - // existed. In the previous example, an extra sign-in would incorrectly - // started. - handler.startSignIn(response); - } else { - // Email or phone: the credentials should have already been saved so - // simply move along. Anononymous sign in also does not require any - // other operations. - finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED, - response.toIntent()); - } - } - }); + @Override + protected void onFailure(@NonNull Exception e) { + handleResponse(IdpResponse.from(e)); + } - View loginButton = findViewById(buttonId); - loginButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - provider.startSignIn(AuthMethodPickerActivity.this); + private void handleResponse(@NonNull IdpResponse response) { + if (!response.isSuccessful()) { + // We have no idea what provider this error stemmed from so just forward + // this along to the handler. + handler.startSignIn(response); + } else if (AuthUI.SOCIAL_PROVIDERS.contains(providerId)) { + // Don't use the response's provider since it can be different than the one + // that launched the sign-in attempt. Ex: the email flow is started, but + // ends up turning into a Google sign-in because that account already + // existed. In the previous example, an extra sign-in would incorrectly + // started. + handler.startSignIn(response); + } else { + // Email or phone: the credentials should have already been saved so + // simply move along. Anononymous sign in also does not require any + // other operations. + finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED, + response.toIntent()); } - }); - mProviderHolder.addView(loginButton); - } + } + }); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + provider.startSignIn(AuthMethodPickerActivity.this); + } + }); } @Override From 82f8177c74427d65b52202c89e9c1759dccd0463 Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Tue, 23 Oct 2018 16:33:51 +0700 Subject: [PATCH 4/8] Fixed implementation AuthMethodPickerLayout + Functional Test --- .../ui/auth/AuthMethodPickerLayout.java | 2 +- .../auth/ui/idp/AuthMethodPickerActivity.java | 8 ++--- .../ui/auth/testhelpers/TestHelper.java | 9 ++++- .../ui/idp/AuthMethodPickerActivityTest.java | 36 +++++++++++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java b/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java index 93cbd0740..266766971 100644 --- a/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java +++ b/auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java @@ -121,7 +121,7 @@ public AuthMethodPickerLayout.Builder setupAnonymousButtonId(@IdRes int anonymou public AuthMethodPickerLayout build() { //Validating the button set for (String key : providersMapping.keySet()) { - if (AuthUI.SUPPORTED_PROVIDERS.contains(key)) { + if (!AuthUI.SUPPORTED_PROVIDERS.contains(key)) { throw new IllegalArgumentException("Unknown provider: " + key); } } 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 f00e6316a..b8de7f3ff 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 @@ -56,7 +56,9 @@ import java.util.List; import java.util.Map; -/** Presents the list of authentication options for this app to the user. */ +/** + * Presents the list of authentication options for this app to the user. + */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public class AuthMethodPickerActivity extends AppCompatBase { @@ -82,12 +84,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { mHandler = ViewModelProviders.of(this).get(SocialProviderResponseHandler.class); mHandler.init(params); + mProviders = new ArrayList<>(); if (customLayout != null) { setContentView(customLayout.getMainLayout()); //Setup using custom layout populateIdpListCustomLayout(params.providers, mHandler); - } else { setContentView(R.layout.fui_auth_method_picker_layout); @@ -145,7 +147,6 @@ protected void onFailure(@NonNull Exception e) { private void populateIdpList(List providerConfigs, final SocialProviderResponseHandler handler) { - mProviders = new ArrayList<>(); for (IdpConfig idpConfig : providerConfigs) { @LayoutRes int buttonLayout; @@ -185,7 +186,6 @@ private void populateIdpList(List providerConfigs, private void populateIdpListCustomLayout(List providerConfigs, final SocialProviderResponseHandler handler) { Map providerButtonIds = customLayout.getProvidersButton(); - mProviders = new ArrayList<>(); for (IdpConfig idpConfig : providerConfigs) { final String providerId = idpConfig.getProviderId(); @IdRes int buttonId = providerButtonIds.get(providerId); diff --git a/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java b/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java index e99dc51d6..4de5fe666 100644 --- a/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java +++ b/auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java @@ -17,6 +17,7 @@ import android.content.Context; import android.content.res.Resources; +import com.firebase.ui.auth.AuthMethodPickerLayout; import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.AuthUI.IdpConfig; import com.firebase.ui.auth.R; @@ -105,6 +106,12 @@ public static FlowParameters getFlowParameters(Collection providerIds) { public static FlowParameters getFlowParameters(Collection providerIds, boolean enableAnonymousUpgrade) { + return getFlowParameters(providerIds, enableAnonymousUpgrade, null); + } + + public static FlowParameters getFlowParameters(Collection providerIds, + boolean enableAnonymousUpgrade, + AuthMethodPickerLayout customLayout) { List idpConfigs = new ArrayList<>(); for (String providerId : providerIds) { switch (providerId) { @@ -143,7 +150,7 @@ public static FlowParameters getFlowParameters(Collection providerIds, true, true, enableAnonymousUpgrade, - null); + customLayout); } diff --git a/auth/src/test/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivityTest.java b/auth/src/test/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivityTest.java index 9da3b2a73..6dd22eafc 100644 --- a/auth/src/test/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivityTest.java +++ b/auth/src/test/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivityTest.java @@ -18,6 +18,7 @@ import android.widget.Button; import android.widget.LinearLayout; +import com.firebase.ui.auth.AuthMethodPickerLayout; import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.R; import com.firebase.ui.auth.testhelpers.TestHelper; @@ -99,6 +100,41 @@ public void testPhoneLoginFlow() { nextIntent.intent.getComponent().getClassName()); } + @Test + public void testCustomAuthMethodPickerLayout() { + List providers = Arrays.asList(EmailAuthProvider.PROVIDER_ID); + + AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout + .Builder(R.layout.fui_provider_button_email) + .setupEmailButtonId(R.id.email_button) + .build(); + + AuthMethodPickerActivity authMethodPickerActivity = createActivityWithCustomLayout(providers, customLayout); + + Button emailButton = authMethodPickerActivity.findViewById(R.id.email_button); + emailButton.performClick(); + + //Expected result -> Directing users to EmailActivity + ShadowActivity.IntentForResult nextIntent = + Shadows.shadowOf(authMethodPickerActivity).getNextStartedActivityForResult(); + assertEquals( + EmailActivity.class.getName(), + nextIntent.intent.getComponent().getClassName()); + } + + private AuthMethodPickerActivity createActivityWithCustomLayout(List providers, + AuthMethodPickerLayout layout) { + Intent startIntent = AuthMethodPickerActivity.createIntent( + RuntimeEnvironment.application, + TestHelper.getFlowParameters(providers, false, layout)); + + return Robolectric + .buildActivity(AuthMethodPickerActivity.class, startIntent) + .create() + .visible() + .get(); + } + private AuthMethodPickerActivity createActivity(List providers) { Intent startIntent = AuthMethodPickerActivity.createIntent( RuntimeEnvironment.application, From ad1ee83b76cdd71bcd3f29afaa04149db3af2957 Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Tue, 23 Oct 2018 18:39:14 +0700 Subject: [PATCH 5/8] Fixed possible NPE with progressBar and providerHolder --- .../auth/ui/idp/AuthMethodPickerActivity.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) 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 b8de7f3ff..26380203f 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 @@ -304,21 +304,27 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { @Override public void showProgress(int message) { - mProgressBar.setVisibility(View.VISIBLE); - for (int i = 0; i < mProviderHolder.getChildCount(); i++) { - View child = mProviderHolder.getChildAt(i); - child.setEnabled(false); - child.setAlpha(0.75f); + //mProgressBar & mProviderHolder might be null if using custom AuthMethodPickerLayout + if (customLayout == null) { + mProgressBar.setVisibility(View.VISIBLE); + for (int i = 0; i < mProviderHolder.getChildCount(); i++) { + View child = mProviderHolder.getChildAt(i); + child.setEnabled(false); + child.setAlpha(0.75f); + } } } @Override public void hideProgress() { - mProgressBar.setVisibility(View.INVISIBLE); - for (int i = 0; i < mProviderHolder.getChildCount(); i++) { - View child = mProviderHolder.getChildAt(i); - child.setEnabled(true); - child.setAlpha(1.0f); + //mProgressBar & mProviderHolder might be null if using custom AuthMethodPickerLayout + if (customLayout == null) { + mProgressBar.setVisibility(View.INVISIBLE); + for (int i = 0; i < mProviderHolder.getChildCount(); i++) { + View child = mProviderHolder.getChildAt(i); + child.setEnabled(true); + child.setAlpha(1.0f); + } } } } From ce92bdd2995181cfb4283652bd1b52560051e547 Mon Sep 17 00:00:00 2001 From: iamyaoxi Date: Tue, 23 Oct 2018 18:39:44 +0700 Subject: [PATCH 6/8] Added sample usage for custom AuthMethodPickerLayout in app module --- .../firebase/uidemo/auth/AuthUiActivity.java | 142 +++++++++++++----- .../auth_method_picker_custom_layout.xml | 56 +++++++ app/src/main/res/layout/auth_ui_layout.xml | 11 +- app/src/main/res/values/strings.xml | 7 + 4 files changed, 174 insertions(+), 42 deletions(-) create mode 100644 app/src/main/res/layout/auth_method_picker_custom_layout.xml diff --git a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java index 0b18950ce..8b02c0f2b 100644 --- a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java +++ b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java @@ -33,6 +33,7 @@ import android.widget.RadioButton; import android.widget.TextView; +import com.firebase.ui.auth.AuthMethodPickerLayout; import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.AuthUI.IdpConfig; import com.firebase.ui.auth.ErrorCodes; @@ -46,6 +47,7 @@ import com.google.firebase.auth.FirebaseAuth; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import butterknife.BindView; @@ -62,47 +64,79 @@ public class AuthUiActivity extends AppCompatActivity { private static final int RC_SIGN_IN = 100; - @BindView(R.id.root) View mRootView; - - @BindView(R.id.google_provider) CheckBox mUseGoogleProvider; - @BindView(R.id.facebook_provider) CheckBox mUseFacebookProvider; - @BindView(R.id.twitter_provider) CheckBox mUseTwitterProvider; - @BindView(R.id.github_provider) CheckBox mUseGitHubProvider; - @BindView(R.id.email_provider) CheckBox mUseEmailProvider; - @BindView(R.id.phone_provider) CheckBox mUsePhoneProvider; - @BindView(R.id.anonymous_provider) CheckBox mUseAnonymousProvider; - - @BindView(R.id.default_theme) RadioButton mDefaultTheme; - @BindView(R.id.green_theme) RadioButton mGreenTheme; - @BindView(R.id.purple_theme) RadioButton mPurpleTheme; - @BindView(R.id.dark_theme) RadioButton mDarkTheme; - - @BindView(R.id.firebase_logo) RadioButton mFirebaseLogo; - @BindView(R.id.google_logo) RadioButton mGoogleLogo; - @BindView(R.id.no_logo) RadioButton mNoLogo; - - @BindView(R.id.google_tos) RadioButton mUseGoogleTos; - @BindView(R.id.firebase_tos) RadioButton mUseFirebaseTos; - - @BindView(R.id.google_privacy) RadioButton mUseGooglePrivacyPolicy; - @BindView(R.id.firebase_privacy) RadioButton mUseFirebasePrivacyPolicy; - - @BindView(R.id.google_scopes_header) TextView mGoogleScopesHeader; - @BindView(R.id.google_scope_drive_file) CheckBox mGoogleScopeDriveFile; - @BindView(R.id.google_scope_youtube_data) CheckBox mGoogleScopeYoutubeData; - - @BindView(R.id.facebook_permissions_header) TextView mFacebookPermissionsHeader; - @BindView(R.id.facebook_permission_friends) CheckBox mFacebookPermissionFriends; - @BindView(R.id.facebook_permission_photos) CheckBox mFacebookPermissionPhotos; - - @BindView(R.id.github_permissions_header) TextView mGitHubPermissionsHeader; - @BindView(R.id.github_permission_repo) CheckBox mGitHubPermissionRepo; - @BindView(R.id.github_permission_gist) CheckBox mGitHubPermissionGist; - - @BindView(R.id.credential_selector_enabled) CheckBox mEnableCredentialSelector; - @BindView(R.id.hint_selector_enabled) CheckBox mEnableHintSelector; - @BindView(R.id.allow_new_email_accounts) CheckBox mAllowNewEmailAccounts; - @BindView(R.id.require_name) CheckBox mRequireName; + @BindView(R.id.root) + View mRootView; + + @BindView(R.id.google_provider) + CheckBox mUseGoogleProvider; + @BindView(R.id.facebook_provider) + CheckBox mUseFacebookProvider; + @BindView(R.id.twitter_provider) + CheckBox mUseTwitterProvider; + @BindView(R.id.github_provider) + CheckBox mUseGitHubProvider; + @BindView(R.id.email_provider) + CheckBox mUseEmailProvider; + @BindView(R.id.phone_provider) + CheckBox mUsePhoneProvider; + @BindView(R.id.anonymous_provider) + CheckBox mUseAnonymousProvider; + + @BindView(R.id.default_theme) + RadioButton mDefaultTheme; + @BindView(R.id.green_theme) + RadioButton mGreenTheme; + @BindView(R.id.purple_theme) + RadioButton mPurpleTheme; + @BindView(R.id.dark_theme) + RadioButton mDarkTheme; + + @BindView(R.id.firebase_logo) + RadioButton mFirebaseLogo; + @BindView(R.id.google_logo) + RadioButton mGoogleLogo; + @BindView(R.id.no_logo) + RadioButton mNoLogo; + + @BindView(R.id.google_tos) + RadioButton mUseGoogleTos; + @BindView(R.id.firebase_tos) + RadioButton mUseFirebaseTos; + + @BindView(R.id.google_privacy) + RadioButton mUseGooglePrivacyPolicy; + @BindView(R.id.firebase_privacy) + RadioButton mUseFirebasePrivacyPolicy; + + @BindView(R.id.google_scopes_header) + TextView mGoogleScopesHeader; + @BindView(R.id.google_scope_drive_file) + CheckBox mGoogleScopeDriveFile; + @BindView(R.id.google_scope_youtube_data) + CheckBox mGoogleScopeYoutubeData; + + @BindView(R.id.facebook_permissions_header) + TextView mFacebookPermissionsHeader; + @BindView(R.id.facebook_permission_friends) + CheckBox mFacebookPermissionFriends; + @BindView(R.id.facebook_permission_photos) + CheckBox mFacebookPermissionPhotos; + + @BindView(R.id.github_permissions_header) + TextView mGitHubPermissionsHeader; + @BindView(R.id.github_permission_repo) + CheckBox mGitHubPermissionRepo; + @BindView(R.id.github_permission_gist) + CheckBox mGitHubPermissionGist; + + @BindView(R.id.credential_selector_enabled) + CheckBox mEnableCredentialSelector; + @BindView(R.id.hint_selector_enabled) + CheckBox mEnableHintSelector; + @BindView(R.id.allow_new_email_accounts) + CheckBox mAllowNewEmailAccounts; + @BindView(R.id.require_name) + CheckBox mRequireName; @NonNull public static Intent createIntent(@NonNull Context context) { @@ -193,6 +227,32 @@ public void signIn() { RC_SIGN_IN); } + @OnClick(R.id.customised_sign_in) + public void signInCustomLayout() { + AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout + .Builder(R.layout.auth_method_picker_custom_layout) + .setupGoogleButtonId(R.id.custom_google_signin_button) + .setupEmailButtonId(R.id.custom_email_signin_clickable_text) + .build(); + + //For now we only test Google and Email + List availableProviders = Arrays.asList( + new AuthUI.IdpConfig.GoogleBuilder() + .setScopes(getGoogleScopes()) + .build(), + new IdpConfig.EmailBuilder() + .setRequireName(mRequireName.isChecked()) + .setAllowNewAccounts(mAllowNewEmailAccounts.isChecked()) + .build()); + + startActivityForResult( + AuthUI.getInstance().createSignInIntentBuilder() + .setAvailableProviders(availableProviders) + .setAuthMethodPickerLayout(customLayout) + .build(), + RC_SIGN_IN); + } + @OnClick(R.id.sign_in_silent) public void silentSignIn() { AuthUI.getInstance().silentSignIn(this, getSelectedProviders()) diff --git a/app/src/main/res/layout/auth_method_picker_custom_layout.xml b/app/src/main/res/layout/auth_method_picker_custom_layout.xml new file mode 100644 index 000000000..e27026300 --- /dev/null +++ b/app/src/main/res/layout/auth_method_picker_custom_layout.xml @@ -0,0 +1,56 @@ + + + + + + + + + +