diff options
| author | 2020-05-29 16:25:42 +0800 | |
|---|---|---|
| committer | 2020-06-04 10:59:20 +0800 | |
| commit | eb06dfd70e2e47dd3436e212c1a0beffd45dc6b2 (patch) | |
| tree | cc7b44cb7d7cf8d4248074d55e93473815c93ec1 | |
| parent | 27630cbb4e87801ffcd427b3142889704da13302 (diff) | |
Implement advanced icon style for output switch
This CL add new type "TYPE_ADVANCED" in AdaptiveOutlineDrawable.
It use to customize icon for output switch.
Bug: 157208551
Test: make -j42 RunSettingsLibRoboTests
Change-Id: I06bfacf2fc6e798648a94117d3e861a807650a5a
10 files changed, 151 insertions, 26 deletions
diff --git a/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml index 76d106a067dd..8f5b2ed3aaaf 100644 --- a/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml +++ b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml @@ -18,4 +18,8 @@ <color name="homepage_generic_icon_background">#1A73E8</color> <color name="bt_outline_color">#1f000000</color> <!-- icon outline color --> + + <color name="advanced_outline_color">#BDC1C6</color> <!-- icon outline color --> + + <color name="advanced_icon_color">#3C4043</color> </resources> diff --git a/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml index 7f5b58c48abb..8f6e358cd9b6 100644 --- a/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml +++ b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml @@ -18,6 +18,8 @@ <resources> <!-- Dashboard foreground image inset (from background edge to foreground edge) --> <dimen name="dashboard_tile_foreground_image_inset">6dp</dimen> + <!-- Advanced dashboard foreground image inset (from background edge to foreground edge) --> + <dimen name="advanced_dashboard_tile_foreground_image_inset">9dp</dimen> <!-- Stroke size of adaptive outline --> <dimen name="adaptive_outline_stroke">1dp</dimen> diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java index 1c65bc248961..4438893dabfc 100644 --- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java @@ -16,6 +16,10 @@ package com.android.settingslib.widget; +import static com.android.settingslib.widget.AdaptiveOutlineDrawable.AdaptiveOutlineIconType.TYPE_ADVANCED; +import static com.android.settingslib.widget.AdaptiveOutlineDrawable.AdaptiveOutlineIconType.TYPE_DEFAULT; + +import android.annotation.ColorInt; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -27,35 +31,90 @@ import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.DrawableWrapper; import android.util.PathParser; +import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Adaptive outline drawable with white plain background color and black outline */ public class AdaptiveOutlineDrawable extends DrawableWrapper { + + @Retention(RetentionPolicy.SOURCE) + @IntDef({TYPE_DEFAULT, TYPE_ADVANCED}) + public @interface AdaptiveOutlineIconType { + int TYPE_DEFAULT = 0; + int TYPE_ADVANCED = 1; + } + @VisibleForTesting - final Paint mOutlinePaint; + Paint mOutlinePaint; private Path mPath; - private final int mInsetPx; - private final Bitmap mBitmap; + private int mInsetPx; + private int mStrokeWidth; + private Bitmap mBitmap; + private int mType; public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) { super(new AdaptiveIconShapeDrawable(resources)); + init(resources, bitmap, TYPE_DEFAULT); + } + + public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap, + @AdaptiveOutlineIconType int type) { + super(new AdaptiveIconShapeDrawable(resources)); + + init(resources, bitmap, type); + } + + private void init(Resources resources, Bitmap bitmap, + @AdaptiveOutlineIconType int type) { + mType = type; getDrawable().setTint(Color.WHITE); mPath = new Path(PathParser.createPathFromPathData( resources.getString(com.android.internal.R.string.config_icon_mask))); + mStrokeWidth = resources.getDimensionPixelSize(R.dimen.adaptive_outline_stroke); mOutlinePaint = new Paint(); - mOutlinePaint.setColor(resources.getColor(R.color.bt_outline_color, null)); + mOutlinePaint.setColor(getColor(resources, type)); mOutlinePaint.setStyle(Paint.Style.STROKE); - mOutlinePaint.setStrokeWidth(resources.getDimension(R.dimen.adaptive_outline_stroke)); + mOutlinePaint.setStrokeWidth(mStrokeWidth); mOutlinePaint.setAntiAlias(true); - mInsetPx = resources - .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset); + mInsetPx = getDimensionPixelSize(resources, type); mBitmap = bitmap; } + private @ColorInt int getColor(Resources resources, @AdaptiveOutlineIconType int type) { + int resId; + switch (type) { + case TYPE_ADVANCED: + resId = R.color.advanced_outline_color; + break; + case TYPE_DEFAULT: + default: + resId = R.color.bt_outline_color; + break; + } + return resources.getColor(resId, /* theme */ null); + } + + private int getDimensionPixelSize(Resources resources, @AdaptiveOutlineIconType int type) { + int resId; + switch (type) { + case TYPE_ADVANCED: + resId = R.dimen.advanced_dashboard_tile_foreground_image_inset; + break; + case TYPE_DEFAULT: + default: + resId = R.dimen.dashboard_tile_foreground_image_inset; + break; + } + return resources.getDimensionPixelSize(resId); + } + @Override public void draw(Canvas canvas) { super.draw(canvas); @@ -68,7 +127,12 @@ public class AdaptiveOutlineDrawable extends DrawableWrapper { final int count = canvas.save(); canvas.scale(scaleX, scaleY); // Draw outline - canvas.drawPath(mPath, mOutlinePaint); + if (mType == TYPE_DEFAULT) { + canvas.drawPath(mPath, mOutlinePaint); + } else { + canvas.drawCircle(2 * mInsetPx, 2 * mInsetPx, 2 * mInsetPx - mStrokeWidth, + mOutlinePaint); + } canvas.restoreToCount(count); // Draw the foreground icon diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml index a5ec5e66f242..e552d78e1a45 100644 --- a/packages/SettingsLib/res/values/dimens.xml +++ b/packages/SettingsLib/res/values/dimens.xml @@ -94,4 +94,7 @@ <!-- Define minimal size of the tap area --> <dimen name="min_tap_target_size">48dp</dimen> + + <!-- Size of advanced icon --> + <dimen name="advanced_icon_size">18dp</dimen> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java index 9d1b3cf116d9..95e916b9871a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java @@ -1,5 +1,7 @@ package com.android.settingslib.bluetooth; +import static com.android.settingslib.widget.AdaptiveOutlineDrawable.AdaptiveOutlineIconType.TYPE_ADVANCED; + import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; @@ -7,6 +9,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -213,6 +216,46 @@ public class BluetoothUtils { } /** + * Build device icon with advanced outline + */ + public static Drawable buildAdvancedDrawable(Context context, Drawable drawable) { + final int iconSize = context.getResources().getDimensionPixelSize( + R.dimen.advanced_icon_size); + final Resources resources = context.getResources(); + + Bitmap bitmap = null; + if (drawable instanceof BitmapDrawable) { + bitmap = ((BitmapDrawable) drawable).getBitmap(); + } else { + final int width = drawable.getIntrinsicWidth(); + final int height = drawable.getIntrinsicHeight(); + bitmap = createBitmap(drawable, + width > 0 ? width : 1, + height > 0 ? height : 1); + } + + if (bitmap != null) { + final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, iconSize, + iconSize, false); + bitmap.recycle(); + return new AdaptiveOutlineDrawable(resources, resizedBitmap, TYPE_ADVANCED); + } + + return drawable; + } + + /** + * Creates a drawable with specified width and height. + */ + public static Bitmap createBitmap(Drawable drawable, int width, int height) { + final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + + /** * Get boolean Bluetooth metadata * * @param bluetoothDevice the BluetoothDevice to get metadata diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java index 40d80488af96..00f94f5c2e64 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java @@ -21,7 +21,6 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.media.MediaRoute2Info; import android.media.MediaRouter2Manager; -import android.util.Pair; import com.android.settingslib.R; import com.android.settingslib.bluetooth.BluetoothUtils; @@ -57,13 +56,11 @@ public class BluetoothMediaDevice extends MediaDevice { @Override public Drawable getIcon() { - final Pair<Drawable, String> pair = BluetoothUtils - .getBtRainbowDrawableWithDescription(mContext, mCachedDevice); - return isFastPairDevice() - ? pair.first - : BluetoothUtils.buildBtRainbowDrawable(mContext, - mContext.getDrawable(R.drawable.ic_headphone), - mCachedDevice.getAddress().hashCode()); + final Drawable drawable = getIconWithoutBackground(); + if (!isFastPairDevice()) { + setColorFilter(drawable); + } + return BluetoothUtils.buildAdvancedDrawable(mContext, drawable); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java index 8d6bc5c97228..ea71e52dc9c9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java @@ -55,9 +55,9 @@ public class InfoMediaDevice extends MediaDevice { @Override public Drawable getIcon() { - //TODO(b/120669861): Return remote device icon uri once api is ready. - return BluetoothUtils.buildBtRainbowDrawable(mContext, - mContext.getDrawable(getDrawableResId()), getId().hashCode()); + final Drawable drawable = getIconWithoutBackground(); + setColorFilter(drawable); + return BluetoothUtils.buildAdvancedDrawable(mContext, drawable); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 317077b14e30..126f9b91b0d2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -31,6 +31,9 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.media.MediaRoute2Info; import android.media.MediaRouter2Manager; @@ -39,6 +42,8 @@ import android.text.TextUtils; import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; +import com.android.settingslib.R; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -131,6 +136,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { getId()); } + void setColorFilter(Drawable drawable) { + final ColorStateList list = + mContext.getResources().getColorStateList( + R.color.advanced_icon_color, mContext.getTheme()); + drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(), + PorterDuff.Mode.SRC_IN)); + } + /** * Get name from MediaDevice. * diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java index c43a51246fb5..b6c0b30b3bd4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java @@ -85,8 +85,9 @@ public class PhoneMediaDevice extends MediaDevice { @Override public Drawable getIcon() { - return BluetoothUtils.buildBtRainbowDrawable(mContext, - mContext.getDrawable(getDrawableResId()), getId().hashCode()); + final Drawable drawable = getIconWithoutBackground(); + setColorFilter(drawable); + return BluetoothUtils.buildAdvancedDrawable(mContext, drawable); } @Override @@ -105,7 +106,7 @@ public class PhoneMediaDevice extends MediaDevice { case TYPE_HDMI: case TYPE_WIRED_HEADSET: case TYPE_WIRED_HEADPHONES: - resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp; + resId = R.drawable.ic_headphone; break; case TYPE_BUILTIN_SPEAKER: default: diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java index 421e5c0db1a1..00d1f76f025f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java @@ -79,13 +79,11 @@ public class PhoneMediaDeviceTest { public void getDrawableResId_returnCorrectResId() { when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES); - assertThat(mPhoneMediaDevice.getDrawableResId()) - .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp); + assertThat(mPhoneMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_headphone); when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET); - assertThat(mPhoneMediaDevice.getDrawableResId()) - .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp); + assertThat(mPhoneMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_headphone); when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER); |