diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2021-05-12 02:47:51 +0000 |
---|---|---|
committer | Cyril Lee <cyrillee@google.com> | 2021-05-12 07:13:02 +0000 |
commit | 6a89234f6c32060dc273ff2962c7b8c78099249c (patch) | |
tree | c4fb537f3a258b11b38b044cdf6cfa9a049ec334 | |
parent | d77ab242a37188333aa7f74eb3d3486a8e0f200d (diff) | |
download | setupcompat-6a89234f6c32060dc273ff2962c7b8c78099249c.tar.gz |
Import updated Android SetupCompat Library 373282927
Copied from google3/third_party/java_src/android_libs/setupcompat
Bug: 187652105
Test: mm
Included changes:
- 373282927 Avoid mixin's color override by partner config
- 373109877 [SetupDesign][SetupCompat] provide footer button styler [...
PiperOrigin-RevId: 373282927
Change-Id: I16a995de491b4642a517bdcdb6d227d1ad12fc20
4 files changed, 331 insertions, 245 deletions
diff --git a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java index 9fd8cef..8f807e6 100644 --- a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java @@ -24,19 +24,10 @@ import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Color; -import android.graphics.PorterDuff.Mode; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.InsetDrawable; -import android.graphics.drawable.LayerDrawable; -import android.graphics.drawable.RippleDrawable; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.PersistableBundle; import android.util.AttributeSet; -import android.util.StateSet; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; @@ -57,7 +48,6 @@ import androidx.annotation.VisibleForTesting; import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.R; import com.google.android.setupcompat.internal.FooterButtonPartnerConfig; -import com.google.android.setupcompat.internal.Preconditions; import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.logging.internal.FooterBarMixinMetrics; import com.google.android.setupcompat.partnerconfig.PartnerConfig; @@ -79,6 +69,7 @@ public class FooterBarMixin implements Mixin { @VisibleForTesting final boolean applyPartnerResources; @VisibleForTesting final boolean applyDynamicColor; + @VisibleForTesting final boolean useFullDynamicColor; private LinearLayout buttonContainer; private FooterButton primaryButton; @@ -98,7 +89,6 @@ public class FooterBarMixin implements Mixin { private boolean removeFooterBarWhenEmpty = true; private boolean isSecondaryButtonInPrimaryStyle = false; - private static final float DEFAULT_DISABLED_ALPHA = 0.26f; private static final AtomicInteger nextGeneratedId = new AtomicInteger(1); @VisibleForTesting public final FooterBarMixinMetrics metrics = new FooterBarMixinMetrics(); @@ -185,6 +175,10 @@ public class FooterBarMixin implements Mixin { layout instanceof PartnerCustomizationLayout && ((PartnerCustomizationLayout) layout).shouldApplyDynamicColor(); + useFullDynamicColor = + layout instanceof PartnerCustomizationLayout + && ((PartnerCustomizationLayout) layout).useFullDynamicColor(); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SucFooterBarMixin, defStyleAttr, 0); defaultPadding = @@ -279,11 +273,14 @@ public class FooterBarMixin implements Mixin { return; } - @ColorInt - int color = - PartnerConfigHelper.get(context) - .getColor(context, PartnerConfig.CONFIG_FOOTER_BAR_BG_COLOR); - buttonContainer.setBackgroundColor(color); + // skip apply partner resources on footerbar background if dynamic color enabled + if (!useFullDynamicColor) { + @ColorInt + int color = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_FOOTER_BAR_BG_COLOR); + buttonContainer.setBackgroundColor(color); + } footerBarPaddingTop = (int) @@ -478,7 +475,7 @@ public class FooterBarMixin implements Mixin { protected void onFooterButtonInflated(Button button, @ColorInt int defaultButtonBackgroundColor) { // Try to set default background if (defaultButtonBackgroundColor != 0) { - updateButtonBackground(button, defaultButtonBackgroundColor); + FooterButtonStyleUtils.updateButtonBackground(button, defaultButtonBackgroundColor); } else { // TODO: get button background color from activity theme } @@ -617,208 +614,45 @@ public class FooterBarMixin implements Mixin { if (!applyDynamicColor) { updateButtonTextColorWithPartnerConfig( button, footerButtonPartnerConfig.getButtonTextColorConfig()); - updateButtonBackgroundWithPartnerConfig( + FooterButtonStyleUtils.updateButtonBackgroundWithPartnerConfig( + context, button, footerButtonPartnerConfig.getButtonBackgroundConfig(), footerButtonPartnerConfig.getButtonDisableAlphaConfig(), footerButtonPartnerConfig.getButtonDisableBackgroundConfig()); - updateButtonRippleColorWithPartnerConfig(button, footerButtonPartnerConfig); + FooterButtonStyleUtils.updateButtonRippleColorWithPartnerConfig( + context, button, footerButtonPartnerConfig); } - updateButtonTextSizeWithPartnerConfig( - button, footerButtonPartnerConfig.getButtonTextSizeConfig()); - updateButtonMinHeightWithPartnerConfig( - button, footerButtonPartnerConfig.getButtonMinHeightConfig()); - updateButtonTypeFaceWithPartnerConfig( + FooterButtonStyleUtils.updateButtonTextSizeWithPartnerConfig( + context, button, footerButtonPartnerConfig.getButtonTextSizeConfig()); + FooterButtonStyleUtils.updateButtonMinHeightWithPartnerConfig( + context, button, footerButtonPartnerConfig.getButtonMinHeightConfig()); + FooterButtonStyleUtils.updateButtonTypeFaceWithPartnerConfig( + context, button, footerButtonPartnerConfig.getButtonTextTypeFaceConfig(), footerButtonPartnerConfig.getButtonTextStyleConfig()); - updateButtonRadiusWithPartnerConfig(button, footerButtonPartnerConfig.getButtonRadiusConfig()); - updateButtonIconWithPartnerConfig(button, footerButtonPartnerConfig.getButtonIconConfig()); + FooterButtonStyleUtils.updateButtonRadiusWithPartnerConfig( + context, button, footerButtonPartnerConfig.getButtonRadiusConfig()); + FooterButtonStyleUtils.updateButtonIconWithPartnerConfig( + context, + button, + footerButtonPartnerConfig.getButtonIconConfig(), + primaryButtonId == button.getId()); } private void updateButtonTextColorWithPartnerConfig( Button button, PartnerConfig buttonTextColorConfig) { if (button.isEnabled()) { - @ColorInt - int color = PartnerConfigHelper.get(context).getColor(context, buttonTextColorConfig); - if (color != Color.TRANSPARENT) { - button.setTextColor(ColorStateList.valueOf(color)); - } - } else { - // disable state will use the default disable state color - button.setTextColor( - button.getId() == primaryButtonId ? primaryDefaultTextColor : secondaryDefaultTextColor); - } - } - - private void updateButtonTextSizeWithPartnerConfig( - Button button, PartnerConfig buttonTextSizeConfig) { - float size = PartnerConfigHelper.get(context).getDimension(context, buttonTextSizeConfig); - if (size > 0) { - button.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); - } - } - - private void updateButtonMinHeightWithPartnerConfig( - Button button, PartnerConfig buttonMinHeightConfig) { - if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonMinHeightConfig)) { - float size = PartnerConfigHelper.get(context).getDimension(context, buttonMinHeightConfig); - if (size > 0) { - button.setMinHeight((int) size); - } - } - } - - private void updateButtonTypeFaceWithPartnerConfig( - Button button, PartnerConfig buttonTextTypeFaceConfig, PartnerConfig buttonTextStyleConfig) { - String fontFamilyName = - PartnerConfigHelper.get(context).getString(context, buttonTextTypeFaceConfig); - - int textStyleValue = Typeface.NORMAL; - if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonTextStyleConfig)) { - textStyleValue = - PartnerConfigHelper.get(context) - .getInteger(context, buttonTextStyleConfig, Typeface.NORMAL); - } - Typeface font = Typeface.create(fontFamilyName, textStyleValue); - if (font != null) { - button.setTypeface(font); - } - } - - @TargetApi(VERSION_CODES.Q) - private void updateButtonBackgroundWithPartnerConfig( - Button button, - PartnerConfig buttonBackgroundConfig, - PartnerConfig buttonDisableAlphaConfig, - PartnerConfig buttonDisableBackgroundConfig) { - Preconditions.checkArgument( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q, - "Update button background only support on sdk Q or higher"); - @ColorInt int color; - @ColorInt int disabledColor; - float disabledAlpha; - int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled}; - int[] ENABLED_STATE_SET = {}; - color = PartnerConfigHelper.get(context).getColor(context, buttonBackgroundConfig); - disabledAlpha = - PartnerConfigHelper.get(context).getFraction(context, buttonDisableAlphaConfig, 0f); - disabledColor = - PartnerConfigHelper.get(context).getColor(context, buttonDisableBackgroundConfig); - - if (color != Color.TRANSPARENT) { - if (disabledAlpha <= 0f) { - // if no partner resource, fallback to theme disable alpha - float alpha; - TypedArray a = context.obtainStyledAttributes(new int[] {android.R.attr.disabledAlpha}); - alpha = a.getFloat(0, DEFAULT_DISABLED_ALPHA); - a.recycle(); - disabledAlpha = alpha; - } - if (disabledColor == Color.TRANSPARENT) { - // if no partner resource, fallback to button background color - disabledColor = color; - } - - // Set text color for ripple. - ColorStateList colorStateList = - new ColorStateList( - new int[][] {DISABLED_STATE_SET, ENABLED_STATE_SET}, - new int[] {convertRgbToArgb(disabledColor, disabledAlpha), color}); - - // b/129482013: When a LayerDrawable is mutated, a new clone of its children drawables are - // created, but without copying the state from the parent drawable. So even though the - // parent is getting the correct drawable state from the view, the children won't get those - // states until a state change happens. - // As a workaround, we mutate the drawable and forcibly set the state to empty, and then - // refresh the state so the children will have the updated states. - button.getBackground().mutate().setState(new int[0]); - button.refreshDrawableState(); - button.setBackgroundTintList(colorStateList); - } - } - - private void updateButtonBackground(Button button, @ColorInt int color) { - button.getBackground().mutate().setColorFilter(color, Mode.SRC_ATOP); - } - - private void updateButtonRadiusWithPartnerConfig( - Button button, PartnerConfig buttonRadiusConfig) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.N) { - float radius = PartnerConfigHelper.get(context).getDimension(context, buttonRadiusConfig); - GradientDrawable gradientDrawable = getGradientDrawable(button); - if (gradientDrawable != null) { - gradientDrawable.setCornerRadius(radius); - } - } - } - - private void updateButtonRippleColorWithPartnerConfig( - Button button, FooterButtonPartnerConfig footerButtonPartnerConfig) { - // RippleDrawable is available after sdk 21. And because on lower sdk the RippleDrawable is - // unavailable. Since Stencil customization provider only works on Q+, there is no need to - // perform any customization for versions 21. - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - RippleDrawable rippleDrawable = getRippleDrawable(button); - if (rippleDrawable == null) { - return; - } - - int[] pressedState = {android.R.attr.state_pressed}; - @ColorInt int color; - // Get partner text color. - color = - PartnerConfigHelper.get(context) - .getColor(context, footerButtonPartnerConfig.getButtonTextColorConfig()); - - float alpha = - PartnerConfigHelper.get(context) - .getFraction(context, footerButtonPartnerConfig.getButtonRippleColorAlphaConfig()); - - // Set text color for ripple. - ColorStateList colorStateList = - new ColorStateList( - new int[][] {pressedState, StateSet.NOTHING}, - new int[] {convertRgbToArgb(color, alpha), Color.TRANSPARENT}); - rippleDrawable.setColor(colorStateList); - } - } - - private void updateButtonIconWithPartnerConfig(Button button, PartnerConfig buttonIconConfig) { - if (button == null) { - return; - } - Drawable icon = null; - if (buttonIconConfig != null) { - icon = PartnerConfigHelper.get(context).getDrawable(context, buttonIconConfig); - } - setButtonIcon(button, icon); - } - - private void setButtonIcon(Button button, Drawable icon) { - if (button == null) { - return; - } - - if (icon != null) { - // TODO: restrict the icons to a reasonable size - int h = icon.getIntrinsicHeight(); - int w = icon.getIntrinsicWidth(); - icon.setBounds(0, 0, w, h); - } - - Drawable iconStart = null; - Drawable iconEnd = null; - if (button.getId() == primaryButtonId) { - iconEnd = icon; - } else if (button.getId() == secondaryButtonId) { - iconStart = icon; - } - if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { - button.setCompoundDrawablesRelative(iconStart, null, iconEnd, null); + FooterButtonStyleUtils.updateButtonTextEnabledColorWithPartnerConfig( + context, button, buttonTextColorConfig); } else { - button.setCompoundDrawables(iconStart, null, iconEnd, null); + FooterButtonStyleUtils.updateButtonTextDisableColor( + button, + /* is Primary= */ (primaryButtonId == button.getId() || isSecondaryButtonInPrimaryStyle) + ? primaryDefaultTextColor + : secondaryDefaultTextColor); } } @@ -857,43 +691,6 @@ public class FooterBarMixin implements Mixin { return result; } - GradientDrawable getGradientDrawable(Button button) { - // RippleDrawable is available after sdk 21, InsetDrawable#getDrawable is available after - // sdk 19. So check the sdk is higher than sdk 21 and since Stencil customization provider only - // works on Q+, there is no need to perform any customization for versions 21. - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - Drawable drawable = button.getBackground(); - if (drawable instanceof InsetDrawable) { - LayerDrawable layerDrawable = (LayerDrawable) ((InsetDrawable) drawable).getDrawable(); - return (GradientDrawable) layerDrawable.getDrawable(0); - } else if (drawable instanceof RippleDrawable) { - InsetDrawable insetDrawable = (InsetDrawable) ((RippleDrawable) drawable).getDrawable(0); - return (GradientDrawable) insetDrawable.getDrawable(); - } - } - return null; - } - - RippleDrawable getRippleDrawable(Button button) { - // RippleDrawable is available after sdk 21. And because on lower sdk the RippleDrawable is - // unavailable. Since Stencil customization provider only works on Q+, there is no need to - // perform any customization for versions 21. - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - Drawable drawable = button.getBackground(); - if (drawable instanceof InsetDrawable) { - return (RippleDrawable) ((InsetDrawable) drawable).getDrawable(); - } else if (drawable instanceof RippleDrawable) { - return (RippleDrawable) drawable; - } - } - return null; - } - - @ColorInt - private static int convertRgbToArgb(@ColorInt int color, float alpha) { - return Color.argb((int) (alpha * 255), Color.red(color), Color.green(color), Color.blue(color)); - } - protected View inflateFooter(@LayoutRes int footer) { if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { LayoutInflater inflater = diff --git a/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java b/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java new file mode 100644 index 0000000..98a1426 --- /dev/null +++ b/main/java/com/google/android/setupcompat/template/FooterButtonStyleUtils.java @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2021 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. + */ + +package com.google.android.setupcompat.template; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.PorterDuff.Mode; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.InsetDrawable; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.RippleDrawable; +import android.os.Build; +import android.os.Build.VERSION_CODES; +import android.util.StateSet; +import android.util.TypedValue; +import android.widget.Button; +import androidx.annotation.ColorInt; +import androidx.annotation.VisibleForTesting; +import com.google.android.setupcompat.internal.FooterButtonPartnerConfig; +import com.google.android.setupcompat.internal.Preconditions; +import com.google.android.setupcompat.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; + +/** Utils for updating the button style. */ +public class FooterButtonStyleUtils { + private static final float DEFAULT_DISABLED_ALPHA = 0.26f; + + static void updateButtonTextEnabledColorWithPartnerConfig( + Context context, Button button, PartnerConfig buttonEnableTextColorConfig) { + @ColorInt + int color = PartnerConfigHelper.get(context).getColor(context, buttonEnableTextColorConfig); + if (color != Color.TRANSPARENT) { + button.setTextColor(ColorStateList.valueOf(color)); + } + } + + static void updateButtonTextDisableColor(Button button, ColorStateList defaultTextColor) { + // TODO : add disable footer button text color partner config + + // disable state will use the default disable state color + button.setTextColor(defaultTextColor); + } + + @TargetApi(VERSION_CODES.Q) + static void updateButtonBackgroundWithPartnerConfig( + Context context, + Button button, + PartnerConfig buttonBackgroundConfig, + PartnerConfig buttonDisableAlphaConfig, + PartnerConfig buttonDisableBackgroundConfig) { + Preconditions.checkArgument( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q, + "Update button background only support on sdk Q or higher"); + @ColorInt int disabledColor; + float disabledAlpha; + int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled}; + int[] ENABLED_STATE_SET = {}; + @ColorInt + int color = PartnerConfigHelper.get(context).getColor(context, buttonBackgroundConfig); + disabledAlpha = + PartnerConfigHelper.get(context).getFraction(context, buttonDisableAlphaConfig, 0f); + disabledColor = + PartnerConfigHelper.get(context).getColor(context, buttonDisableBackgroundConfig); + + if (color != Color.TRANSPARENT) { + if (disabledAlpha <= 0f) { + // if no partner resource, fallback to theme disable alpha + TypedArray a = context.obtainStyledAttributes(new int[] {android.R.attr.disabledAlpha}); + float alpha = a.getFloat(0, DEFAULT_DISABLED_ALPHA); + a.recycle(); + disabledAlpha = alpha; + } + if (disabledColor == Color.TRANSPARENT) { + // if no partner resource, fallback to button background color + disabledColor = color; + } + + // Set text color for ripple. + ColorStateList colorStateList = + new ColorStateList( + new int[][] {DISABLED_STATE_SET, ENABLED_STATE_SET}, + new int[] {convertRgbToArgb(disabledColor, disabledAlpha), color}); + + // b/129482013: When a LayerDrawable is mutated, a new clone of its children drawables are + // created, but without copying the state from the parent drawable. So even though the + // parent is getting the correct drawable state from the view, the children won't get those + // states until a state change happens. + // As a workaround, we mutate the drawable and forcibly set the state to empty, and then + // refresh the state so the children will have the updated states. + button.getBackground().mutate().setState(new int[0]); + button.refreshDrawableState(); + button.setBackgroundTintList(colorStateList); + } + } + + static void updateButtonRippleColorWithPartnerConfig( + Context context, Button button, FooterButtonPartnerConfig footerButtonPartnerConfig) { + // RippleDrawable is available after sdk 21. And because on lower sdk the RippleDrawable is + // unavailable. Since Stencil customization provider only works on Q+, there is no need to + // perform any customization for versions 21. + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + RippleDrawable rippleDrawable = getRippleDrawable(button); + if (rippleDrawable == null) { + return; + } + + int[] pressedState = {android.R.attr.state_pressed}; + // Get partner text color. + @ColorInt + int color = + PartnerConfigHelper.get(context) + .getColor(context, footerButtonPartnerConfig.getButtonTextColorConfig()); + + float alpha = + PartnerConfigHelper.get(context) + .getFraction(context, footerButtonPartnerConfig.getButtonRippleColorAlphaConfig()); + + // Set text color for ripple. + ColorStateList colorStateList = + new ColorStateList( + new int[][] {pressedState, StateSet.NOTHING}, + new int[] {convertRgbToArgb(color, alpha), Color.TRANSPARENT}); + rippleDrawable.setColor(colorStateList); + } + } + + static void updateButtonTextSizeWithPartnerConfig( + Context context, Button button, PartnerConfig buttonTextSizeConfig) { + float size = PartnerConfigHelper.get(context).getDimension(context, buttonTextSizeConfig); + if (size > 0) { + button.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + } + } + + static void updateButtonMinHeightWithPartnerConfig( + Context context, Button button, PartnerConfig buttonMinHeightConfig) { + if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonMinHeightConfig)) { + float size = PartnerConfigHelper.get(context).getDimension(context, buttonMinHeightConfig); + if (size > 0) { + button.setMinHeight((int) size); + } + } + } + + static void updateButtonTypeFaceWithPartnerConfig( + Context context, + Button button, + PartnerConfig buttonTextTypeFaceConfig, + PartnerConfig buttonTextStyleConfig) { + String fontFamilyName = + PartnerConfigHelper.get(context).getString(context, buttonTextTypeFaceConfig); + + int textStyleValue = Typeface.NORMAL; + if (PartnerConfigHelper.get(context).isPartnerConfigAvailable(buttonTextStyleConfig)) { + textStyleValue = + PartnerConfigHelper.get(context) + .getInteger(context, buttonTextStyleConfig, Typeface.NORMAL); + } + Typeface font = Typeface.create(fontFamilyName, textStyleValue); + if (font != null) { + button.setTypeface(font); + } + } + + static void updateButtonRadiusWithPartnerConfig( + Context context, Button button, PartnerConfig buttonRadiusConfig) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.N) { + float radius = PartnerConfigHelper.get(context).getDimension(context, buttonRadiusConfig); + GradientDrawable gradientDrawable = getGradientDrawable(button); + if (gradientDrawable != null) { + gradientDrawable.setCornerRadius(radius); + } + } + } + + static void updateButtonIconWithPartnerConfig( + Context context, Button button, PartnerConfig buttonIconConfig, boolean isPrimary) { + if (button == null) { + return; + } + Drawable icon = null; + if (buttonIconConfig != null) { + icon = PartnerConfigHelper.get(context).getDrawable(context, buttonIconConfig); + } + setButtonIcon(button, icon, isPrimary); + } + + private static void setButtonIcon(Button button, Drawable icon, boolean isPrimary) { + if (button == null) { + return; + } + + if (icon != null) { + // TODO: restrict the icons to a reasonable size + int h = icon.getIntrinsicHeight(); + int w = icon.getIntrinsicWidth(); + icon.setBounds(0, 0, w, h); + } + + Drawable iconStart = null; + Drawable iconEnd = null; + if (isPrimary) { + iconEnd = icon; + } else { + iconStart = icon; + } + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + button.setCompoundDrawablesRelative(iconStart, null, iconEnd, null); + } else { + button.setCompoundDrawables(iconStart, null, iconEnd, null); + } + } + + static void updateButtonBackground(Button button, @ColorInt int color) { + button.getBackground().mutate().setColorFilter(color, Mode.SRC_ATOP); + } + + @VisibleForTesting + public static GradientDrawable getGradientDrawable(Button button) { + // RippleDrawable is available after sdk 21, InsetDrawable#getDrawable is available after + // sdk 19. So check the sdk is higher than sdk 21 and since Stencil customization provider only + // works on Q+, there is no need to perform any customization for versions 21. + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + Drawable drawable = button.getBackground(); + if (drawable instanceof InsetDrawable) { + LayerDrawable layerDrawable = (LayerDrawable) ((InsetDrawable) drawable).getDrawable(); + return (GradientDrawable) layerDrawable.getDrawable(0); + } else if (drawable instanceof RippleDrawable) { + InsetDrawable insetDrawable = (InsetDrawable) ((RippleDrawable) drawable).getDrawable(0); + return (GradientDrawable) insetDrawable.getDrawable(); + } + } + return null; + } + + static RippleDrawable getRippleDrawable(Button button) { + // RippleDrawable is available after sdk 21. And because on lower sdk the RippleDrawable is + // unavailable. Since Stencil customization provider only works on Q+, there is no need to + // perform any customization for versions 21. + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + Drawable drawable = button.getBackground(); + if (drawable instanceof InsetDrawable) { + return (RippleDrawable) ((InsetDrawable) drawable).getDrawable(); + } else if (drawable instanceof RippleDrawable) { + return (RippleDrawable) drawable; + } + } + return null; + } + + @ColorInt + private static int convertRgbToArgb(@ColorInt int color, float alpha) { + return Color.argb((int) (alpha * 255), Color.red(color), Color.green(color), Color.blue(color)); + } + + private FooterButtonStyleUtils() {} +} diff --git a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java index a818793..c0f1c45 100644 --- a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java @@ -112,10 +112,14 @@ public class StatusBarMixin implements Mixin { */ public void setStatusBarBackground(Drawable background) { if (partnerCustomizationLayout.shouldApplyPartnerResource()) { + // If full dynamic color enabled which means this activity is running outside of setup + // flow, the colors should refer to R.style.SudFullDynamicColorThemeGlifV3. + if (!partnerCustomizationLayout.useFullDynamicColor()) { Context context = partnerCustomizationLayout.getContext(); background = PartnerConfigHelper.get(context) .getDrawable(context, PartnerConfig.CONFIG_STATUS_BAR_BACKGROUND); + } } if (statusBarLayout == null) { diff --git a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java index 8050406..32c708c 100644 --- a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java @@ -47,6 +47,7 @@ public class SystemNavBarMixin implements Mixin { private final TemplateLayout templateLayout; @Nullable private final Window windowOfActivity; @VisibleForTesting final boolean applyPartnerResources; + @VisibleForTesting final boolean useFullDynamicColor; private int sucSystemNavBarBackgroundColor = 0; /** @@ -61,6 +62,10 @@ public class SystemNavBarMixin implements Mixin { this.applyPartnerResources = layout instanceof PartnerCustomizationLayout && ((PartnerCustomizationLayout) layout).shouldApplyPartnerResource(); + + this.useFullDynamicColor = + layout instanceof PartnerCustomizationLayout + && ((PartnerCustomizationLayout) layout).useFullDynamicColor(); } /** @@ -109,10 +114,14 @@ public class SystemNavBarMixin implements Mixin { public void setSystemNavBarBackground(int color) { if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && windowOfActivity != null) { if (applyPartnerResources) { - Context context = templateLayout.getContext(); - color = - PartnerConfigHelper.get(context) - .getColor(context, PartnerConfig.CONFIG_NAVIGATION_BAR_BG_COLOR); + // If full dynamic color enabled which means this activity is running outside of setup + // flow, the colors should refer to R.style.SudFullDynamicColorThemeGlifV3. + if (!useFullDynamicColor) { + Context context = templateLayout.getContext(); + color = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_NAVIGATION_BAR_BG_COLOR); + } } windowOfActivity.setNavigationBarColor(color); } |