From ba83f8e64a7dbd9eaaacc8ce72f03331565476c5 Mon Sep 17 00:00:00 2001 From: Setup Wizard Team Date: Wed, 5 Dec 2018 09:50:12 +0800 Subject: Import updated Android SetupCompat Library 224078621 PiperOrigin-RevId: 224078621 Change-Id: I119837ab04a29fc34f888e50bfb3796a39792812 --- .../setupcompat/PartnerCustomizationLayout.java | 13 +- .../android/setupcompat/item/FooterButton.java | 135 +++++++++- .../internal/SetupMetricsLoggingConstants.java | 3 + .../setupcompat/template/ButtonFooterMixin.java | 295 ++++++++++++++++++--- .../setupcompat/util/PartnerConfigHelper.java | 5 +- .../setupcompat/util/WizardManagerHelper.java | 6 +- .../suc_customization_button_highlight_ripple.xml | 22 ++ main/res/values/attrs.xml | 23 +- main/res/values/colors.xml | 4 +- main/res/values/config.xml | 4 - main/res/values/dimens.xml | 3 + main/res/values/styles.xml | 37 +-- 12 files changed, 458 insertions(+), 92 deletions(-) create mode 100644 main/res/color-v23/suc_customization_button_highlight_ripple.xml (limited to 'main') diff --git a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java index 885f01d..e2f7b89 100644 --- a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java +++ b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java @@ -85,22 +85,15 @@ public class PartnerCustomizationLayout extends TemplateLayout { attrs, defStyleAttr, /* applyPartnerResources= */ isSetupFlow)); + registerMixin( + ButtonFooterMixin.class, + new ButtonFooterMixin(this, attrs, defStyleAttr, /* applyPartnerResources= */ isSetupFlow)); TypedArray a = getContext() .obtainStyledAttributes( attrs, R.styleable.SucPartnerCustomizationLayout, defStyleAttr, 0); - final int primaryBtn = - a.getResourceId(R.styleable.SucPartnerCustomizationLayout_sucPrimaryFooterButton, 0); - final int secondaryBtn = - a.getResourceId(R.styleable.SucPartnerCustomizationLayout_sucSecondaryFooterButton, 0); - - registerMixin( - ButtonFooterMixin.class, - new ButtonFooterMixin( - this, primaryBtn, secondaryBtn, /* applyPartnerResources= */ isSetupFlow)); - final int footer = a.getResourceId(R.styleable.SucPartnerCustomizationLayout_sucFooter, 0); if (footer != 0) { inflateFooter(footer); diff --git a/main/java/com/google/android/setupcompat/item/FooterButton.java b/main/java/com/google/android/setupcompat/item/FooterButton.java index 31c6e93..e2a2818 100644 --- a/main/java/com/google/android/setupcompat/item/FooterButton.java +++ b/main/java/com/google/android/setupcompat/item/FooterButton.java @@ -18,6 +18,7 @@ package com.google.android.setupcompat.item; import android.content.Context; import android.content.res.TypedArray; +import androidx.annotation.IdRes; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; @@ -28,60 +29,156 @@ import com.google.android.setupcompat.R; import com.google.android.setupcompat.template.ButtonFooterMixin; /** - * Definition of a footer button. Clients can use this class to customize attributes like text and - * click listener, and ButtonFooterMixin will inflate a corresponding Button view. + * Definition of a footer button. Clients can use this class to customize attributes like text, + * button type and click listener, and ButtonFooterMixin will inflate a corresponding Button view. */ public class FooterButton { + private static final int BUTTON_TYPE_NONE = 0; + private final String text; - private final OnClickListener listener; + private final ButtonType buttonType; private int theme; + @IdRes private int id; + private OnClickListener onClickListener; + private OnButtonEventListener buttonListener; public FooterButton(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SucFooterButton); - this.text = a.getString(R.styleable.SucFooterButton_android_text); - this.listener = null; - this.theme = a.getResourceId(R.styleable.SucFooterButton_android_theme, 0); + text = a.getString(R.styleable.SucFooterButton_android_text); + onClickListener = null; + buttonType = + ButtonType.values()[a.getInt(R.styleable.SucFooterButton_sucButtonType, BUTTON_TYPE_NONE)]; + theme = a.getResourceId(R.styleable.SucFooterButton_android_theme, 0); a.recycle(); } /** - * Allows client customize text, click listener and theme for footer button - * before Button has been created. The {@link ButtonFooterMixin} will inflate a corresponding - * Button view. + * Allows client customize text, click listener and theme for footer button before Button has been + * created. The {@link ButtonFooterMixin} will inflate a corresponding Button view. * * @param context The context of application. * @param text The text for button. * @param listener The listener for button. + * @param buttonType The type of button. * @param theme The theme for button. */ + public FooterButton( + Context context, + @StringRes int text, + @Nullable OnClickListener listener, + @Nullable ButtonType buttonType, + @StyleRes int theme) { + this(context.getString(text), listener, buttonType, theme); + } + public FooterButton( Context context, @StringRes int text, @Nullable OnClickListener listener, @StyleRes int theme) { - this(context.getString(text), listener, theme); + this(context.getString(text), listener, ButtonType.NONE, theme); + } + + public FooterButton(String text, @Nullable OnClickListener listener, @StyleRes int theme) { + this(text, listener, ButtonType.NONE, theme); } public FooterButton( - String text, @Nullable OnClickListener listener, @StyleRes int theme) { + String text, + @Nullable OnClickListener listener, + @Nullable ButtonType buttonType, + @StyleRes int theme) { this.text = text; - this.listener = listener; + onClickListener = listener; + this.buttonType = buttonType; this.theme = theme; } + /** Sets the resource id of footer button. */ + @VisibleForTesting + public void setId(@IdRes int id) { + this.id = id; + } + + /** Returns the text that this footer button is displaying. */ public String getText() { return text; } - public OnClickListener getListener() { - return listener; + /** Returns an {@link OnClickListener} of this footer button. */ + @VisibleForTesting + public OnClickListener getOnClickListener() { + return onClickListener; + } + + /** + * Registers a callback to be invoked when this view of footer button is clicked. + * + * @param listener The callback that will run + */ + public void setOnClickListener(@Nullable OnClickListener listener) { + onClickListener = listener; + if (buttonListener != null && id != 0) { + buttonListener.onClickListenerChanged(listener, id); + } + } + + /** Returns the type of this footer button icon. */ + public ButtonType getButtonType() { + return buttonType; } + /** Returns the theme of this footer button. */ @StyleRes public int getTheme() { return theme; } + /** + * Sets the enabled state of this footer button. + * + * @param enabled True if this view is enabled, false otherwise. + */ + public void setEnabled(boolean enabled) { + if (buttonListener != null && id != 0) { + buttonListener.onEnabledChanged(enabled, id); + } + } + + /** + * Sets the visibility state of this footer button. + * + * @param visibility one of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. + */ + public void setVisibility(int visibility) { + if (buttonListener != null && id != 0) { + buttonListener.onVisibilityChanged(visibility, id); + } + } + + /** + * Registers a callback to be invoked when footer button API has set. + * + * @param listener The callback that will run + */ + @VisibleForTesting + public void setOnButtonEventListener(@Nullable OnButtonEventListener listener) { + if (listener != null) { + buttonListener = listener; + } + } + + /** Interface definition for a callback to be invoked when footer button API has set. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public interface OnButtonEventListener { + + void onClickListenerChanged(@Nullable OnClickListener listener, @IdRes int id); + + void onEnabledChanged(boolean enabled, @IdRes int id); + + void onVisibilityChanged(int visibility, @IdRes int id); + } + /** * Sets the default theme for footer button, the method only for internal use in {@link * ButtonFooterMixin} and there will have no influence during setup wizard flow. @@ -92,4 +189,14 @@ public class FooterButton { public void setTheme(@StyleRes int theme) { this.theme = theme; } + + /** Types for footer button. The button appearance and behavior may change based on its type. */ + public enum ButtonType { + /** A type of button that doesn't fit into any other categories. */ + NONE, + /** A type of button that will go to the next screen, or next step in the flow when clicked. */ + NEXT, + /** A type of button that will skip the current step when clicked. */ + SKIP + } } diff --git a/main/java/com/google/android/setupcompat/logging/internal/SetupMetricsLoggingConstants.java b/main/java/com/google/android/setupcompat/logging/internal/SetupMetricsLoggingConstants.java index fd6f450..a06ee76 100644 --- a/main/java/com/google/android/setupcompat/logging/internal/SetupMetricsLoggingConstants.java +++ b/main/java/com/google/android/setupcompat/logging/internal/SetupMetricsLoggingConstants.java @@ -46,6 +46,9 @@ public interface SetupMetricsLoggingConstants { * int)}. */ int COUNTER_EVENT = 2; + + /** MetricType constant used for internal logging purposes. */ + int INTERNAL = 100; } /** Keys of the bundle used while logging data to SetupWizard. */ diff --git a/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java b/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java index c122f07..ff28f16 100644 --- a/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java +++ b/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java @@ -18,6 +18,8 @@ package com.google.android.setupcompat.template; import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PorterDuff.Mode; import android.graphics.Typeface; @@ -28,6 +30,7 @@ import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.RippleDrawable; import android.os.Build; import android.os.Build.VERSION_CODES; +import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.IdRes; import androidx.annotation.LayoutRes; @@ -35,11 +38,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; -import androidx.annotation.XmlRes; +import android.util.AttributeSet; import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewStub; import android.widget.Button; import android.widget.LinearLayout; @@ -47,9 +51,12 @@ import android.widget.LinearLayout.LayoutParams; import com.google.android.setupcompat.R; import com.google.android.setupcompat.TemplateLayout; import com.google.android.setupcompat.item.FooterButton; +import com.google.android.setupcompat.item.FooterButton.ButtonType; +import com.google.android.setupcompat.item.FooterButton.OnButtonEventListener; import com.google.android.setupcompat.item.FooterButtonInflater; import com.google.android.setupcompat.util.PartnerConfig; import com.google.android.setupcompat.util.PartnerConfigHelper; +import java.util.concurrent.atomic.AtomicInteger; /** * A {@link Mixin} for managing buttons. By default, the button bar expects that buttons on the @@ -63,32 +70,93 @@ public class ButtonFooterMixin implements Mixin { @Nullable private final ViewStub footerStub; private LinearLayout buttonContainer; + private FooterButton primaryButton; + private FooterButton secondaryButton; + @IdRes private int primaryButtonId; + @IdRes private int secondaryButtonId; @VisibleForTesting final boolean applyPartnerResources; + private int footerBarPaddingTop; + private int footerBarPaddingBottom; + + private static final AtomicInteger nextGeneratedId = new AtomicInteger(1); + + private final OnButtonEventListener onButtonEventListener = + new OnButtonEventListener() { + @Override + public void onClickListenerChanged(@Nullable OnClickListener listener, @IdRes int id) { + if (buttonContainer != null && id != 0) { + Button button = buttonContainer.findViewById(id); + if (button != null) { + button.setOnClickListener(listener); + } + } + } + + @Override + public void onEnabledChanged(boolean enabled, @IdRes int id) { + if (buttonContainer != null && id != 0) { + Button button = buttonContainer.findViewById(id); + if (button != null) { + button.setEnabled(enabled); + } + } + } + + @Override + public void onVisibilityChanged(int visibility, @IdRes int id) { + if (buttonContainer != null && id != 0) { + Button button = buttonContainer.findViewById(id); + if (button != null) { + button.setVisibility(visibility); + } + } + } + }; + /** * Creates a mixin for managing buttons on the footer. * * @param layout The {@link TemplateLayout} containing this mixin. + * @param attrs XML attributes given to the layout. + * @param defStyleAttr The default style attribute as given to the constructor of the layout. * @param applyPartnerResources determine applies partner resources or not. */ public ButtonFooterMixin( TemplateLayout layout, - @XmlRes int attrPrimaryButton, - @XmlRes int attrSecondaryButton, + @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, boolean applyPartnerResources) { context = layout.getContext(); footerStub = (ViewStub) layout.findManagedViewById(R.id.suc_layout_footer); this.applyPartnerResources = applyPartnerResources; + int defaultPadding = + context + .getResources() + .getDimensionPixelSize(R.dimen.suc_customization_footer_padding_vertical); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SucFooterBar, defStyleAttr, 0); + footerBarPaddingTop = + a.getDimensionPixelSize(R.styleable.SucFooterBar_sucFooterBarPaddingTop, defaultPadding); + footerBarPaddingBottom = + a.getDimensionPixelSize(R.styleable.SucFooterBar_sucFooterBarPaddingBottom, defaultPadding); + + int primaryBtn = a.getResourceId(R.styleable.SucFooterBar_sucFooterBarPrimaryFooterButton, 0); + int secondaryBtn = + a.getResourceId(R.styleable.SucFooterBar_sucFooterBarSecondaryFooterButton, 0); + a.recycle(); + FooterButtonInflater inflater = new FooterButtonInflater(context); - if (attrPrimaryButton != 0) { - setPrimaryButton(inflater.inflate(attrPrimaryButton)); + // If there are both PrimaryButton & SecondaryButton; setSecondaryButton() need to be called + // first. The button will be added from left to right in LTR, right to left in RTL. + if (secondaryBtn != 0) { + setSecondaryButton(inflater.inflate(secondaryBtn)); } - if (attrSecondaryButton != 0) { - setSecondaryButton(inflater.inflate(attrSecondaryButton)); + if (primaryBtn != 0) { + setPrimaryButton(inflater.inflate(primaryBtn)); } } @@ -108,8 +176,8 @@ public class ButtonFooterMixin implements Mixin { if (footerStub == null) { throw new IllegalStateException("Footer stub is not found in this template"); } - footerStub.setLayoutResource(R.layout.suc_footer_button_bar); - buttonContainer = (LinearLayout) footerStub.inflate(); + buttonContainer = (LinearLayout) inflateFooter(R.layout.suc_footer_button_bar); + updateBottomBarPadding(); } return buttonContainer; } @@ -141,12 +209,28 @@ public class ButtonFooterMixin implements Mixin { footerButton.setTheme(R.style.SucPartnerCustomizationButton_Secondary); } - Button button = inflateButton(footerButton, R.id.suc_customization_primary_button); + Button button = inflateButton(footerButton); + primaryButtonId = button.getId(); buttonContainer.addView(button); + + if (applyPartnerResources) { + // This API should only be called after primaryButtonId is set. + updateButtonAttrsWithPartnerConfig(button, true, footerButton.getButtonType()); + } + + footerButton.setId(primaryButtonId); + footerButton.setOnButtonEventListener(onButtonEventListener); + primaryButton = footerButton; + } + + /** Returns the {@link FooterButton} of primary button. */ + public FooterButton getPrimaryButton() { + return primaryButton; } - public Button getPrimaryButton() { - return buttonContainer.findViewById(R.id.suc_customization_primary_button); + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public Button getPrimaryButtonView() { + return buttonContainer.findViewById(primaryButtonId); } /** Sets secondary button for footer. */ @@ -157,52 +241,86 @@ public class ButtonFooterMixin implements Mixin { if (footerButton.getTheme() == 0 || applyPartnerResources) { footerButton.setTheme(R.style.SucPartnerCustomizationButton_Secondary); } + int color = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR); // TODO(b/120055778): Make sure customize attributes in theme can be applied during setup flow. - // If doesn't set background color to full transparent, the button changes to colored bordered - // ink button style. - if (applyPartnerResources - && PartnerConfigHelper.get(context) - .getColor(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR) - != Color.TRANSPARENT) { + // If doesn't set background color to full transparent or white, the button changes to colored + // bordered ink button style. + if (applyPartnerResources && (color != Color.TRANSPARENT && color != Color.WHITE)) { footerButton.setTheme(R.style.SucPartnerCustomizationButton_Primary); } - Button button = inflateButton(footerButton, R.id.suc_customization_secondary_button); + Button button = inflateButton(footerButton); + secondaryButtonId = button.getId(); buttonContainer.addView(button); + + if (applyPartnerResources) { + // This API should only be called after secondaryButtonId is set. + updateButtonAttrsWithPartnerConfig(button, false, footerButton.getButtonType()); + } + + footerButton.setId(secondaryButtonId); + footerButton.setOnButtonEventListener(onButtonEventListener); + secondaryButton = footerButton; addSpace(); } - public Button getSecondaryButton() { - return buttonContainer.findViewById(R.id.suc_customization_secondary_button); + /** Returns the {@link FooterButton} of secondary button. */ + public FooterButton getSecondaryButton() { + return secondaryButton; + } + + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public Button getSecondaryButtonView() { + return buttonContainer.findViewById(secondaryButtonId); + } + + private static int generateViewId() { + for (; ; ) { + final int result = nextGeneratedId.get(); + // aapt-generated IDs have the high byte nonzero; clamp to the range under that. + int newValue = result + 1; + if (newValue > 0x00FFFFFF) { + newValue = 1; // Roll over to 1, not 0. + } + if (nextGeneratedId.compareAndSet(result, newValue)) { + return result; + } + } } - private Button inflateButton(FooterButton footerButton, @IdRes int id) { + private Button inflateButton(FooterButton footerButton) { Button button = createThemedButton(context, footerButton.getTheme()); - button.setId(id); - button.setText(footerButton.getText()); - button.setOnClickListener(footerButton.getListener()); - if (applyPartnerResources) { - updateButtonAttrsWithPartnerConfig(button, id); + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + button.setId(View.generateViewId()); + } else { + button.setId(generateViewId()); } + button.setText(footerButton.getText()); + button.setOnClickListener(footerButton.getOnClickListener()); + return button; } // TODO(b/120055778): Make sure customize attributes in theme can be applied during setup flow. - private void updateButtonAttrsWithPartnerConfig(Button button, @IdRes int id) { - updateButtonTextColorWithPartnerConfig(button, id); - updateButtonTextSizeWithPartnerConfig(button, id); + private void updateButtonAttrsWithPartnerConfig( + Button button, boolean isPrimaryButton, ButtonType buttonType) { + updateButtonTextColorWithPartnerConfig(button, isPrimaryButton); + updateButtonTextSizeWithPartnerConfig(button, isPrimaryButton); updateButtonTypeFaceWithPartnerConfig(button); - updateButtonBackgroundWithPartnerConfig(button, id); + updateButtonBackgroundWithPartnerConfig(button, isPrimaryButton); updateButtonRadiusWithPartnerConfig(button); + updateButtonIconWithPartnerConfig(button, buttonType); } - private void updateButtonTextColorWithPartnerConfig(Button button, @IdRes int id) { + private void updateButtonTextColorWithPartnerConfig(Button button, boolean isPrimaryButton) { @ColorInt int color = 0; - if (id == R.id.suc_customization_primary_button) { + if (isPrimaryButton) { color = PartnerConfigHelper.get(context) .getColor(context, PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_COLOR); - } else if (id == R.id.suc_customization_secondary_button) { + } else { color = PartnerConfigHelper.get(context) .getColor(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_COLOR); @@ -210,13 +328,13 @@ public class ButtonFooterMixin implements Mixin { button.setTextColor(color); } - private void updateButtonTextSizeWithPartnerConfig(Button button, @IdRes int id) { + private void updateButtonTextSizeWithPartnerConfig(Button button, boolean isPrimaryButton) { float size = 0.0f; - if (id == R.id.suc_customization_primary_button) { + if (isPrimaryButton) { size = PartnerConfigHelper.get(context) .getDimension(context, PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_SIZE); - } else if (id == R.id.suc_customization_secondary_button) { + } else { size = PartnerConfigHelper.get(context) .getDimension(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_SIZE); @@ -234,16 +352,16 @@ public class ButtonFooterMixin implements Mixin { } } - private void updateButtonBackgroundWithPartnerConfig(Button button, @IdRes int id) { + private void updateButtonBackgroundWithPartnerConfig(Button button, boolean isPrimaryButton) { if (Build.VERSION.SDK_INT >= VERSION_CODES.M) { - if (id == R.id.suc_customization_primary_button) { + if (isPrimaryButton) { int color = PartnerConfigHelper.get(context) .getColor(context, PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_BG_COLOR); if (color != Color.TRANSPARENT) { button.getBackground().setColorFilter(color, Mode.MULTIPLY); } - } else if (id == R.id.suc_customization_secondary_button) { + } else { int color = PartnerConfigHelper.get(context) .getColor(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR); @@ -268,6 +386,60 @@ public class ButtonFooterMixin implements Mixin { } } + private void updateButtonIconWithPartnerConfig(Button button, ButtonType buttonType) { + if (button == null) { + return; + } + Drawable icon; + switch (buttonType) { + case NEXT: + icon = + PartnerConfigHelper.get(context) + .getDrawable(context, PartnerConfig.CONFIG_FOOTER_BUTTON_ICON_NEXT); + break; + case SKIP: + icon = + PartnerConfigHelper.get(context) + .getDrawable(context, PartnerConfig.CONFIG_FOOTER_BUTTON_ICON_SKIP); + break; + case NONE: + default: + icon = null; + break; + } + setButtonIcon(button, icon); + } + + private void setButtonIcon(Button button, Drawable icon) { + if (button == null || icon == null) { + return; + } + int h = icon.getIntrinsicHeight(); + int w = icon.getIntrinsicWidth(); + icon.setBounds(0, 0, w, h); + + boolean isRtl = false; + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + Configuration config = context.getResources().getConfiguration(); + isRtl = config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + } + + Drawable iconLeft = null; + Drawable iconRight = null; + if (button.getId() == primaryButtonId) { + iconRight = icon; + } else if (button.getId() == secondaryButtonId) { + iconLeft = icon; + } + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + button.setCompoundDrawablesRelative( + isRtl ? iconRight : iconLeft, null, isRtl ? iconLeft : iconRight, null); + } else { + button.setCompoundDrawables( + isRtl ? iconRight : iconLeft, null, isRtl ? iconLeft : iconRight, null); + } + } + GradientDrawable getGradientDrawable(Button button) { Drawable drawable = button.getBackground(); if (drawable instanceof InsetDrawable) { @@ -281,7 +453,50 @@ public class ButtonFooterMixin implements Mixin { } protected View inflateFooter(@LayoutRes int footer) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { + LayoutInflater inflater = + LayoutInflater.from( + new ContextThemeWrapper(context, R.style.SucPartnerCustomizationButtonBar_Stackable)); + footerStub.setLayoutInflater(inflater); + } footerStub.setLayoutResource(footer); return footerStub.inflate(); } + + private void updateBottomBarPadding() { + if (buttonContainer == null) { + // Ignore action since buttonContainer is null + return; + } + + if (applyPartnerResources) { + footerBarPaddingTop = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_FOOTER_BUTTON_PADDING_TOP); + footerBarPaddingBottom = + (int) + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_FOOTER_BUTTON_PADDING_BOTTOM); + } + buttonContainer.setPadding( + buttonContainer.getPaddingLeft(), + footerBarPaddingTop, + buttonContainer.getPaddingRight(), + footerBarPaddingBottom); + } + + /** Returns the paddingTop of footer bar. */ + @VisibleForTesting + int getPaddingTop() { + return (buttonContainer != null) ? buttonContainer.getPaddingTop() : footerStub.getPaddingTop(); + } + + /** Returns the paddingBottom of footer bar. */ + @VisibleForTesting + int getPaddingBottom() { + return (buttonContainer != null) + ? buttonContainer.getPaddingBottom() + : footerStub.getPaddingBottom(); + } } diff --git a/main/java/com/google/android/setupcompat/util/PartnerConfigHelper.java b/main/java/com/google/android/setupcompat/util/PartnerConfigHelper.java index 87a3706..78ac626 100644 --- a/main/java/com/google/android/setupcompat/util/PartnerConfigHelper.java +++ b/main/java/com/google/android/setupcompat/util/PartnerConfigHelper.java @@ -20,6 +20,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; @@ -123,7 +124,9 @@ public class PartnerConfigHelper { result = resource.getDrawable(resourceEntry.getResourceId()); } partnerResourceCache.put(resourceConfig, result); - } catch (PackageManager.NameNotFoundException | NullPointerException exception) { + } catch (PackageManager.NameNotFoundException + | NullPointerException + | NotFoundException exception) { // fall through } return result; diff --git a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java index 780105d..ba46fdf 100644 --- a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java +++ b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java @@ -99,7 +99,11 @@ public class WizardManagerHelper { public static void copyWizardManagerExtras(Intent srcIntent, Intent dstIntent) { dstIntent.putExtra(EXTRA_WIZARD_BUNDLE, srcIntent.getBundleExtra(EXTRA_WIZARD_BUNDLE)); for (String key : - Arrays.asList(EXTRA_IS_FIRST_RUN, EXTRA_IS_DEFERRED_SETUP, EXTRA_IS_PRE_DEFERRED_SETUP)) { + Arrays.asList( + EXTRA_IS_FIRST_RUN, + EXTRA_IS_DEFERRED_SETUP, + EXTRA_IS_PRE_DEFERRED_SETUP, + EXTRA_IS_SETUP_FLOW)) { dstIntent.putExtra(key, srcIntent.getBooleanExtra(key, false)); } diff --git a/main/res/color-v23/suc_customization_button_highlight_ripple.xml b/main/res/color-v23/suc_customization_button_highlight_ripple.xml new file mode 100644 index 0000000..d0c859c --- /dev/null +++ b/main/res/color-v23/suc_customization_button_highlight_ripple.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml index 50cc060..7466586 100644 --- a/main/res/values/attrs.xml +++ b/main/res/values/attrs.xml @@ -30,8 +30,6 @@ - - @@ -58,11 +56,24 @@ + + + + + - - - - + + + + + + + + + + + + diff --git a/main/res/values/colors.xml b/main/res/values/colors.xml index 1a74b47..db4a877 100644 --- a/main/res/values/colors.xml +++ b/main/res/values/colors.xml @@ -19,6 +19,8 @@ - #1f000000 + #1f000000 + + #ff1a73e8 \ No newline at end of file diff --git a/main/res/values/config.xml b/main/res/values/config.xml index 1c226c5..4c2b45d 100644 --- a/main/res/values/config.xml +++ b/main/res/values/config.xml @@ -20,10 +20,6 @@ - - - - google-sans-medium diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml index e8f2d60..a0b7369 100644 --- a/main/res/values/dimens.xml +++ b/main/res/values/dimens.xml @@ -29,4 +29,7 @@ 4dp + + 0.12 + diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml index 01ffa57..4a94218 100644 --- a/main/res/values/styles.xml +++ b/main/res/values/styles.xml @@ -29,12 +29,16 @@ center_vertical @dimen/suc_customization_footer_min_height horizontal - @dimen/suc_customization_footer_padding_vertical - @dimen/suc_customization_footer_padding_vertical + ?attr/sucFooterBarPaddingTop + ?attr/sucFooterBarPaddingBottom @dimen/suc_customization_button_margin_end @dimen/suc_customization_button_margin_start @dimen/suc_customization_button_margin_end @dimen/suc_customization_button_margin_start + + + @dimen/suc_customization_footer_padding_vertical + @dimen/suc_customization_footer_padding_vertical -- cgit v1.2.3