summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorSetup Wizard Team <android-setup-team-eng@google.com>2018-12-05 09:50:12 +0800
committercnchen <cnchen@google.com>2018-12-05 10:55:50 +0800
commitba83f8e64a7dbd9eaaacc8ce72f03331565476c5 (patch)
tree3d499a066c2a4cb14cc6058e9c85bf75abd2c40b /main
parente54804b554da82624f3c12a3d3e33ef9bb7061b2 (diff)
downloadsetupcompat-ba83f8e64a7dbd9eaaacc8ce72f03331565476c5.tar.gz
Import updated Android SetupCompat Library 224078621
PiperOrigin-RevId: 224078621 Change-Id: I119837ab04a29fc34f888e50bfb3796a39792812
Diffstat (limited to 'main')
-rw-r--r--main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java13
-rw-r--r--main/java/com/google/android/setupcompat/item/FooterButton.java135
-rw-r--r--main/java/com/google/android/setupcompat/logging/internal/SetupMetricsLoggingConstants.java3
-rw-r--r--main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java295
-rw-r--r--main/java/com/google/android/setupcompat/util/PartnerConfigHelper.java5
-rw-r--r--main/java/com/google/android/setupcompat/util/WizardManagerHelper.java6
-rw-r--r--main/res/color-v23/suc_customization_button_highlight_ripple.xml22
-rw-r--r--main/res/values/attrs.xml23
-rw-r--r--main/res/values/colors.xml4
-rw-r--r--main/res/values/config.xml4
-rw-r--r--main/res/values/dimens.xml3
-rw-r--r--main/res/values/styles.xml37
12 files changed, 458 insertions, 92 deletions
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,61 +29,157 @@ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- TODO(b/120391478): Gets ripple color and alpha from partner if client sets the values -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="?attr/sucFooterBarButtonColorControlHighlightRipple"
+ android:alpha="?attr/sucFooterBarButtonHighlightAlpha" />
+</selector>
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 @@
<declare-styleable name="SucPartnerCustomizationLayout">
<attr name="sucFooter" format="reference" />
<attr name="sucLayoutFullscreen" format="boolean" />
- <attr name="sucPrimaryFooterButton" format="reference" />
- <attr name="sucSecondaryFooterButton" format="reference" />
</declare-styleable>
<!-- Status bar attributes -->
@@ -58,11 +56,24 @@
<declare-styleable name="SucFooterButton">
<attr name="android:text" />
<attr name="android:theme" />
+ <attr name="sucButtonType">
+ <enum name="none" value="0" />
+ <enum name="next" value="1" />
+ <enum name="skip" value="2" />
+ </attr>
</declare-styleable>
<!-- Button of footer attributes -->
- <attr name="sucPartnerCustomizationButtonAllCaps" format="boolean" />
- <attr name="sucPartnerCustomizationButtonCornerRadius" format="dimension" />
- <attr name="sucPartnerCustomizationButtonFontFamily" format="string|reference" />
-
+ <declare-styleable name="SucFooterBar">
+ <attr name="sucFooterBarButtonAllCaps" format="boolean" />
+ <attr name="sucFooterBarButtonCornerRadius" format="dimension" />
+ <attr name="sucFooterBarButtonFontFamily" format="string|reference" />
+ <attr name="sucFooterBarPaddingTop" format="dimension" />
+ <attr name="sucFooterBarPaddingBottom" format="dimension" />
+ <attr name="sucFooterBarPrimaryFooterButton" format="reference" />
+ <attr name="sucFooterBarSecondaryFooterButton" format="reference" />
+ <attr name="sucFooterBarButtonHighlightAlpha" format="dimension" />
+ <attr name="sucFooterBarButtonColorControlHighlight" format="color" />
+ <attr name="sucFooterBarButtonColorControlHighlightRipple" format="color" />
+ </declare-styleable>
</resources>
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 @@
<!-- On versions < 23, we cannot reference other theme values in a color resource. Default to
the framework default of 12% black -->
- <color name="suc_customization_button_highlight">#1f000000</color>
+ <color name="suc_customization_button_highlight_ripple">#1f000000</color>
+
+ <color name="suc_customization_button_highlight_default">#ff1a73e8</color>
</resources> \ 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 @@
<!-- ID used with View#setTag to store the original weight on a ButtonBar -->
<item name="suc_customization_original_weight" type="id" />
- <!-- Footer button id -->
- <item name="suc_customization_primary_button" type="id" />
- <item name="suc_customization_secondary_button" type="id" />
-
<!-- Footer button typeface -->
<string name="suc_customization_button_font_family" translatable="false">google-sans-medium</string>
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 @@
<!-- Footer button style radius attributes -->
<dimen name="suc_customization_button_corner_radius">4dp</dimen>
+ <!-- Footer button style ripple alpha attributes -->
+ <item name="suc_customization_button_ripple_alpha" format="float" type="dimen">0.12</item>
+
</resources>
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 @@
<item name="android:gravity">center_vertical</item>
<item name="android:minHeight">@dimen/suc_customization_footer_min_height</item>
<item name="android:orientation">horizontal</item>
- <item name="android:paddingTop">@dimen/suc_customization_footer_padding_vertical</item>
- <item name="android:paddingBottom">@dimen/suc_customization_footer_padding_vertical</item>
+ <item name="android:paddingTop">?attr/sucFooterBarPaddingTop</item>
+ <item name="android:paddingBottom">?attr/sucFooterBarPaddingBottom</item>
<item name="android:paddingEnd" tools:ignore="NewApi">@dimen/suc_customization_button_margin_end</item>
<item name="android:paddingLeft">@dimen/suc_customization_button_margin_start</item>
<item name="android:paddingRight">@dimen/suc_customization_button_margin_end</item>
<item name="android:paddingStart" tools:ignore="NewApi">@dimen/suc_customization_button_margin_start</item>
+
+ <!-- Default value -->
+ <item name="sucFooterBarPaddingTop">@dimen/suc_customization_footer_padding_vertical</item>
+ <item name="sucFooterBarPaddingBottom">@dimen/suc_customization_footer_padding_vertical</item>
</style>
<style name="SucPartnerCustomizationButton.Primary" parent="android:Widget.Material.Button.Colored">
@@ -45,18 +49,18 @@
<item name="android:theme">@style/SucPartnerCustomizationButton.Primary</item>
<!-- Values used in styles -->
- <item name="android:fontFamily">?attr/sucPartnerCustomizationButtonFontFamily</item>
+ <item name="android:fontFamily">?attr/sucFooterBarButtonFontFamily</item>
<item name="android:paddingLeft">@dimen/suc_customization_button_padding</item>
<item name="android:paddingRight">@dimen/suc_customization_button_padding</item>
- <item name="android:textAllCaps">?attr/sucPartnerCustomizationButtonAllCaps</item>
+ <item name="android:textAllCaps">?attr/sucFooterBarButtonAllCaps</item>
<!-- Values used in themes -->
- <item name="android:buttonCornerRadius" tools:ignore="NewApi">?attr/sucPartnerCustomizationButtonCornerRadius</item>
+ <item name="android:buttonCornerRadius" tools:ignore="NewApi">?attr/sucFooterBarButtonCornerRadius</item>
<!-- Default value -->
- <item name="sucPartnerCustomizationButtonFontFamily">@string/suc_customization_button_font_family</item>
- <item name="sucPartnerCustomizationButtonCornerRadius">@dimen/suc_customization_button_corner_radius</item>
- <item name="sucPartnerCustomizationButtonAllCaps">false</item>
+ <item name="sucFooterBarButtonFontFamily">@string/suc_customization_button_font_family</item>
+ <item name="sucFooterBarButtonCornerRadius">@dimen/suc_customization_button_corner_radius</item>
+ <item name="sucFooterBarButtonAllCaps">false</item>
</style>
<style name="SucPartnerCustomizationButton.Secondary" parent="android:Widget.Material.Button.Borderless.Colored">
@@ -67,20 +71,23 @@
<item name="android:theme">@style/SucPartnerCustomizationButton.Secondary</item>
<!-- Values used in styles -->
- <item name="android:fontFamily">?attr/sucPartnerCustomizationButtonFontFamily</item>
+ <item name="android:fontFamily">?attr/sucFooterBarButtonFontFamily</item>
<item name="android:minWidth">0dp</item>
<item name="android:paddingLeft">@dimen/suc_customization_button_padding</item>
<item name="android:paddingRight">@dimen/suc_customization_button_padding</item>
- <item name="android:textAllCaps">?attr/sucPartnerCustomizationButtonAllCaps</item>
+ <item name="android:textAllCaps">?attr/sucFooterBarButtonAllCaps</item>
<!-- Values used in themes -->
- <item name="android:buttonCornerRadius" tools:ignore="NewApi">?attr/sucPartnerCustomizationButtonCornerRadius</item>
- <item name="android:colorControlHighlight" tools:targetApi="lollipop">@color/suc_customization_button_highlight</item>
+ <item name="android:buttonCornerRadius" tools:ignore="NewApi">?attr/sucFooterBarButtonCornerRadius</item>
+ <item name="android:colorControlHighlight" tools:targetApi="lollipop">@color/suc_customization_button_highlight_ripple</item>
+ <item name="sucFooterBarButtonColorControlHighlight">@color/suc_customization_button_highlight_ripple</item>
+ <item name="sucFooterBarButtonHighlightAlpha">@dimen/suc_customization_button_ripple_alpha</item>
<!-- Default value -->
- <item name="sucPartnerCustomizationButtonFontFamily">@string/suc_customization_button_font_family</item>
- <item name="sucPartnerCustomizationButtonCornerRadius">@dimen/suc_customization_button_corner_radius</item>
- <item name="sucPartnerCustomizationButtonAllCaps">false</item>
+ <item name="sucFooterBarButtonFontFamily">@string/suc_customization_button_font_family</item>
+ <item name="sucFooterBarButtonCornerRadius">@dimen/suc_customization_button_corner_radius</item>
+ <item name="sucFooterBarButtonAllCaps">false</item>
+ <item name="sucFooterBarButtonColorControlHighlightRipple">@color/suc_customization_button_highlight_default</item>
</style>
</resources>