From 344519f55fb5de26b6d136be5a45f4051bf88ab2 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 22 Feb 2021 16:47:35 -0500 Subject: [PATCH] Fix defined DrawableWrappers with proper ConstantState DrawableWrappers extend from InsetDrawable instead, so a proper internal state is created. This way, we can use the proper drawable attribute and delegate most of the work to DrawableWrapper correctly. Also, create ConstantState that are able to create new instances of the correct drawables. Fixes: 179928515 Fixes: 175026098 Test: manual Change-Id: I8d07fd518ad66e6c456f7a1a6aa31fbaa18ba8aa --- packages/SystemUI/res/values/attrs.xml | 5 -- .../settings/brightness/BrightnessSlider.java | 34 --------- .../util/AlphaTintDrawableWrapper.java | 74 +++++++++++++++++-- .../util/RoundedCornerProgressDrawable.kt | 55 ++++++-------- 4 files changed, 90 insertions(+), 78 deletions(-) diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index a1191aeacddea..3771767a866a9 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -168,7 +168,6 @@ - @@ -189,9 +188,5 @@ - - - - diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java index a6aec3b7b1b73..0b40e225fb2b2 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java @@ -17,8 +17,6 @@ package com.android.systemui.settings.brightness; import android.content.Context; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -29,10 +27,8 @@ import android.widget.SeekBar; import androidx.annotation.Nullable; import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.statusbar.policy.BrightnessMirrorController; -import com.android.systemui.util.RoundedCornerProgressDrawable; import com.android.systemui.util.ViewController; import javax.inject.Inject; @@ -274,9 +270,6 @@ public class BrightnessSlider private BrightnessSlider fromTree(ViewGroup root, boolean useMirror) { BrightnessSliderView v = root.requireViewById(R.id.brightness_slider); - // TODO(175026098) Workaround. Remove when b/175026098 is fixed - applyTheme(v); - return new BrightnessSlider(root, v, useMirror); } @@ -286,32 +279,5 @@ public class BrightnessSlider ? R.layout.quick_settings_brightness_dialog_thick : R.layout.quick_settings_brightness_dialog; } - - private LayerDrawable findProgressClippableDrawable(BrightnessSliderView v) { - SeekBar b = v.requireViewById(R.id.slider); - if (b.getProgressDrawable() instanceof LayerDrawable) { - Drawable progress = ((LayerDrawable) b.getProgressDrawable()) - .findDrawableByLayerId(com.android.internal.R.id.progress); - if (progress instanceof RoundedCornerProgressDrawable) { - Drawable inner = ((RoundedCornerProgressDrawable) progress).getDrawable(); - if (inner instanceof LayerDrawable) { - return (LayerDrawable) inner; - } - } - } - return null; - } - - private void applyTheme(BrightnessSliderView v) { - LayerDrawable layer = findProgressClippableDrawable(v); - if (layer != null) { - layer.findDrawableByLayerId(R.id.slider_foreground).setTintList( - Utils.getColorAttr(v.getContext(), - com.android.internal.R.attr.colorControlActivated)); - layer.findDrawableByLayerId(R.id.slider_icon).setTintList( - Utils.getColorAttr(v.getContext(), - com.android.internal.R.attr.colorBackground)); - } - } } } diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java index 79a197d9d4097..a22793b050709 100644 --- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java @@ -16,15 +16,18 @@ package com.android.systemui.util; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; import android.graphics.drawable.DrawableWrapper; +import android.graphics.drawable.InsetDrawable; import android.util.AttributeSet; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.systemui.R; import org.xmlpull.v1.XmlPullParser; @@ -45,13 +48,18 @@ import java.io.IOException; * @attr ref R.styleable#AlphaTintDrawableWrapper_tint * @attr ref R.styleable#AlphaTintDrawableWrapper_alpha */ -public class AlphaTintDrawableWrapper extends DrawableWrapper { +public class AlphaTintDrawableWrapper extends InsetDrawable { private ColorStateList mTint; private int[] mThemeAttrs; /** No-arg constructor used by drawable inflation. */ public AlphaTintDrawableWrapper() { - super(null); + super(null, 0); + } + + AlphaTintDrawableWrapper(Drawable drawable, int[] themeAttrs) { + super(drawable, 0); + mThemeAttrs = themeAttrs; } @Override @@ -74,7 +82,7 @@ public class AlphaTintDrawableWrapper extends DrawableWrapper { public void applyTheme(Theme t) { super.applyTheme(t); - if (mThemeAttrs != null) { + if (mThemeAttrs != null && t != null) { final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.AlphaTintDrawableWrapper); updateStateFromTypedArray(a); @@ -92,9 +100,6 @@ public class AlphaTintDrawableWrapper extends DrawableWrapper { } private void updateStateFromTypedArray(@NonNull TypedArray a) { - if (a.hasValue(R.styleable.AlphaTintDrawableWrapper_android_drawable)) { - setDrawable(a.getDrawable(R.styleable.AlphaTintDrawableWrapper_android_drawable)); - } if (a.hasValue(R.styleable.AlphaTintDrawableWrapper_android_tint)) { mTint = a.getColorStateList(R.styleable.AlphaTintDrawableWrapper_android_tint); } @@ -109,4 +114,57 @@ public class AlphaTintDrawableWrapper extends DrawableWrapper { getDrawable().mutate().setTintList(mTint); } } + + @Nullable + @Override + public ConstantState getConstantState() { + return new AlphaTintState(super.getConstantState(), mThemeAttrs, getAlpha(), mTint); + } + + static class AlphaTintState extends Drawable.ConstantState { + + private ConstantState mWrappedState; + private int[] mThemeAttrs; + private int mAlpha; + private ColorStateList mColorStateList; + + AlphaTintState( + ConstantState wrappedState, + int[] themeAttrs, + int alpha, + ColorStateList colorStateList + ) { + mWrappedState = wrappedState; + mThemeAttrs = themeAttrs; + mAlpha = alpha; + mColorStateList = colorStateList; + } + + @NonNull + @Override + public Drawable newDrawable() { + return newDrawable(null, null); + } + + @NonNull + @Override + public Drawable newDrawable(Resources res, Theme theme) { + DrawableWrapper wrapper = (DrawableWrapper) mWrappedState.newDrawable(res, theme); + AlphaTintDrawableWrapper alphaTintDrawableWrapper = + new AlphaTintDrawableWrapper(wrapper.getDrawable(), mThemeAttrs); + alphaTintDrawableWrapper.setTintList(mColorStateList); + alphaTintDrawableWrapper.setAlpha(mAlpha); + return alphaTintDrawableWrapper; + } + + @Override + public boolean canApplyTheme() { + return true; + } + + @Override + public int getChangingConfigurations() { + return mWrappedState.getChangingConfigurations(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt index 1af2c9f463739..6aadd1020bce9 100644 --- a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt @@ -17,15 +17,12 @@ package com.android.systemui.util import android.content.res.Resources -import android.content.res.TypedArray import android.graphics.Canvas import android.graphics.Path import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.DrawableWrapper -import android.util.AttributeSet -import com.android.systemui.R -import org.xmlpull.v1.XmlPullParser +import android.graphics.drawable.InsetDrawable /** * [DrawableWrapper] to use in the progress of a slider. @@ -38,9 +35,9 @@ import org.xmlpull.v1.XmlPullParser * is meant to be smaller than the rounded corner. The background should have rounded corners that * are half of the height. */ -class RoundedCornerProgressDrawable(drawable: Drawable?) : DrawableWrapper(drawable) { - - constructor() : this(null) +class RoundedCornerProgressDrawable @JvmOverloads constructor( + drawable: Drawable? = null +) : InsetDrawable(drawable, 0) { companion object { private const val MAX_LEVEL = 10000 // Taken from Drawable @@ -52,35 +49,11 @@ class RoundedCornerProgressDrawable(drawable: Drawable?) : DrawableWrapper(drawa setClipPath(Rect()) } - override fun inflate( - r: Resources, - parser: XmlPullParser, - attrs: AttributeSet, - theme: Resources.Theme? - ) { - val a = obtainAttributes(r, theme, attrs, R.styleable.RoundedCornerProgressDrawable) - - // Inflation will advance the XmlPullParser and AttributeSet. - super.inflate(r, parser, attrs, theme) - - updateStateFromTypedArray(a) - if (drawable == null) { - throw IllegalStateException("${this::class.java.simpleName} needs a drawable") - } - a.recycle() - } - override fun onLayoutDirectionChanged(layoutDirection: Int): Boolean { onLevelChange(level) return super.onLayoutDirectionChanged(layoutDirection) } - private fun updateStateFromTypedArray(a: TypedArray) { - if (a.hasValue(R.styleable.RoundedCornerProgressDrawable_android_drawable)) { - setDrawable(a.getDrawable(R.styleable.RoundedCornerProgressDrawable_android_drawable)) - } - } - override fun onBoundsChange(bounds: Rect) { setClipPath(bounds) super.onBoundsChange(bounds) @@ -115,4 +88,24 @@ class RoundedCornerProgressDrawable(drawable: Drawable?) : DrawableWrapper(drawa super.draw(canvas) canvas.restore() } + + override fun getConstantState(): ConstantState? { + // This should not be null as it was created with a state in the constructor. + return RoundedCornerState(super.getConstantState()!!) + } + + private class RoundedCornerState(private val wrappedState: ConstantState) : ConstantState() { + override fun newDrawable(): Drawable { + return newDrawable(null, null) + } + + override fun newDrawable(res: Resources?, theme: Resources.Theme?): Drawable { + val wrapper = wrappedState.newDrawable(res, theme) as DrawableWrapper + return RoundedCornerProgressDrawable(wrapper.drawable) + } + + override fun getChangingConfigurations(): Int { + return wrappedState.changingConfigurations + } + } } \ No newline at end of file