diff --git a/color-check-baseline.xml b/color-check-baseline.xml index 70744814dc2..e78bac61a6b 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -1309,6 +1309,230 @@ column="5"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 7e0ba105e29..521d709e318 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1378,4 +1378,25 @@ @string/wifi_calling_mode_cellular_preferred_summary + + + @color/bt_color_icon_1 + @color/bt_color_icon_2 + @color/bt_color_icon_3 + @color/bt_color_icon_4 + @color/bt_color_icon_5 + @color/bt_color_icon_6 + @color/bt_color_icon_7 + + + + + @color/bt_color_bg_1 + @color/bt_color_bg_2 + @color/bt_color_bg_3 + @color/bt_color_bg_4 + @color/bt_color_bg_5 + @color/bt_color_bg_6 + @color/bt_color_bg_7 + diff --git a/res/values/colors.xml b/res/values/colors.xml index 0afd28882a4..2cebd28e617 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -140,4 +140,20 @@ #ff1a73e8 #b3ffffff + + #48a50e0e + #480d652d + #48e37400 + #48b06000 + #489c166b + #48681da8 + #48007b83 + + #fad2cf + #ceead6 + #feefc3 + #fedfc8 + #fdcfe8 + #e9d2fd + #cbf0f8 \ No newline at end of file diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java index fd805b828f3..38603526ba6 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java @@ -26,7 +26,6 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.widget.EntityHeaderController; -import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -66,10 +65,8 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController } protected void setHeaderProperties() { - final Pair pair = BluetoothUtils - .getBtClassDrawableWithDescription(mContext, mCachedDevice, - mContext.getResources().getFraction(R.fraction.bt_battery_scale_fraction, 1, - 1)); + final Pair pair = Utils.getBtRainbowDrawableWithDescription(mContext, + mCachedDevice); String summaryText = mCachedDevice.getConnectionSummary(); // If both the hearing aids are connected, two device status should be shown. // If Second Summary is unavailable, to set it to null. diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index d4c0ed099fc..8d727ebdb96 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -38,7 +38,6 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.GearPreference; -import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -130,8 +129,8 @@ public final class BluetoothDevicePreference extends GearPreference implements // Null check is done at the framework setSummary(mCachedDevice.getConnectionSummary()); - final Pair pair = BluetoothUtils - .getBtClassDrawableWithDescription(getContext(), mCachedDevice); + final Pair pair = Utils + .getBtRainbowDrawableWithDescription(getContext(), mCachedDevice); if (pair.first != null) { setIcon(pair.first); contentDescription = pair.second; @@ -246,5 +245,4 @@ public final class BluetoothDevicePreference extends GearPreference implements R.string.bluetooth_pairing_error_message); } } - } diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java index ff4a98fc5ce..e02ddc42616 100755 --- a/src/com/android/settings/bluetooth/Utils.java +++ b/src/com/android/settings/bluetooth/Utils.java @@ -21,8 +21,12 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.DialogInterface; +import android.content.res.Resources; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.provider.Settings; import android.util.Log; +import android.util.Pair; import android.widget.Toast; import androidx.annotation.VisibleForTesting; @@ -30,8 +34,10 @@ import androidx.appcompat.app.AlertDialog; import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.widget.AdaptiveIcon; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback; @@ -179,4 +185,25 @@ public final class Utils { return META_INT_ERROR; } } + + /** + * Get colorful bluetooth icon with description + */ + public static Pair getBtRainbowDrawableWithDescription(Context context, + CachedBluetoothDevice cachedDevice) { + final Pair pair = BluetoothUtils.getBtClassDrawableWithDescription( + context, cachedDevice); + final Resources resources = context.getResources(); + final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors); + final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors); + + // get color index based on mac address + final int index = Math.abs(cachedDevice.getAddress().hashCode()) % iconBgColors.length; + pair.first.setColorFilter(iconFgColors[index], PorterDuff.Mode.SRC_ATOP); + final Drawable adaptiveIcon = new AdaptiveIcon(context, pair.first); + ((AdaptiveIcon) adaptiveIcon).setBackgroundColor(iconBgColors[index]); + + return new Pair<>(adaptiveIcon, pair.second); + } + } diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 6348b912185..744cbd2f566 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -46,7 +46,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.dashboard.profileselector.ProfileSelectDialog; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.widget.AdaptiveHomepageIcon; +import com.android.settings.widget.AdaptiveIcon; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; @@ -197,8 +197,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext()); if (forceRoundedIcon && !TextUtils.equals(mContext.getPackageName(), tile.getPackageName())) { - iconDrawable = new AdaptiveHomepageIcon(mContext, iconDrawable); - ((AdaptiveHomepageIcon) iconDrawable).setBackgroundColor(mContext, tile); + iconDrawable = new AdaptiveIcon(mContext, iconDrawable); + ((AdaptiveIcon) iconDrawable).setBackgroundColor(mContext, tile); } preference.setIcon(iconDrawable); } else if (tile.getMetaData() != null diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java index 99fe21930bf..5c1fbdd3ac6 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java @@ -46,7 +46,6 @@ import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.SliceBroadcastReceiver; import com.android.settings.slices.SliceBuilderUtils; -import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -211,8 +210,9 @@ public class BluetoothDevicesSlice implements CustomSliceable { @VisibleForTesting IconCompat getBluetoothDeviceIcon(CachedBluetoothDevice device) { - final Pair pair = BluetoothUtils - .getBtClassDrawableWithDescription(mContext, device); + final Pair pair = + com.android.settings.bluetooth.Utils.getBtRainbowDrawableWithDescription(mContext, + device); final Drawable drawable = pair.first; // Use default bluetooth icon if can't get icon. diff --git a/src/com/android/settings/widget/AdaptiveHomepageIcon.java b/src/com/android/settings/widget/AdaptiveIcon.java similarity index 76% rename from src/com/android/settings/widget/AdaptiveHomepageIcon.java rename to src/com/android/settings/widget/AdaptiveIcon.java index bc7aaa7f22e..04b33ae8d1e 100644 --- a/src/com/android/settings/widget/AdaptiveHomepageIcon.java +++ b/src/com/android/settings/widget/AdaptiveIcon.java @@ -35,14 +35,15 @@ import com.android.settings.R; import com.android.settings.homepage.AdaptiveIconShapeDrawable; import com.android.settingslib.drawer.Tile; -public class AdaptiveHomepageIcon extends LayerDrawable { +public class AdaptiveIcon extends LayerDrawable { private static final String TAG = "AdaptiveHomepageIcon"; @VisibleForTesting(otherwise = NONE) int mBackgroundColor = -1; + private AdaptiveConstantState mAdaptiveConstantState; - public AdaptiveHomepageIcon(Context context, Drawable foreground) { + public AdaptiveIcon(Context context, Drawable foreground) { super(new Drawable[]{ new AdaptiveIconShapeDrawable(context.getResources()), foreground @@ -50,6 +51,7 @@ public class AdaptiveHomepageIcon extends LayerDrawable { final int insetPx = context.getResources() .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset); setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx); + mAdaptiveConstantState = new AdaptiveConstantState(context, foreground); } public void setBackgroundColor(Context context, Tile tile) { @@ -85,5 +87,36 @@ public class AdaptiveHomepageIcon extends LayerDrawable { mBackgroundColor = color; getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP); Log.d(TAG, "Setting background color " + mBackgroundColor); + mAdaptiveConstantState.color = color; + } + + @Override + public ConstantState getConstantState() { + return mAdaptiveConstantState; + } + + @VisibleForTesting + static class AdaptiveConstantState extends ConstantState { + Context context; + Drawable drawable; + int color; + + public AdaptiveConstantState(Context context, Drawable drawable) { + this.context = context; + this.drawable = drawable; + } + + @Override + public Drawable newDrawable() { + final AdaptiveIcon icon = new AdaptiveIcon(context, drawable); + icon.setBackgroundColor(color); + + return icon; + } + + @Override + public int getChangingConfigurations() { + return 0; + } } } diff --git a/tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java b/tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java similarity index 80% rename from tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java rename to tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java index 05a9cfb3dfc..1be3332c222 100644 --- a/tests/robotests/src/com/android/settings/widget/AdaptiveHomepageIconTest.java +++ b/tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java @@ -48,7 +48,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) -public class AdaptiveHomepageIconTest { +public class AdaptiveIconTest { private Context mContext; private ActivityInfo mActivityInfo; @@ -64,8 +64,8 @@ public class AdaptiveHomepageIconTest { @Test public void createIcon_shouldSetBackgroundAndInset() { - final AdaptiveHomepageIcon icon = - new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); assertThat(icon.getNumberOfLayers()).isEqualTo(2); assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class); @@ -73,8 +73,8 @@ public class AdaptiveHomepageIconTest { @Test public void setBackgroundColor_shouldUpdateColorFilter() { - final AdaptiveHomepageIcon icon = - spy(new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK))); + final AdaptiveIcon icon = + spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK))); final ShapeDrawable background = mock(ShapeDrawable.class); when(icon.getDrawable(0)).thenReturn(background); @@ -89,8 +89,8 @@ public class AdaptiveHomepageIconTest { mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) .when(tile).getIcon(mContext); - final AdaptiveHomepageIcon icon = - new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); assertThat(icon.mBackgroundColor).isEqualTo(0xff0000); @@ -101,8 +101,8 @@ public class AdaptiveHomepageIconTest { final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) .when(tile).getIcon(mContext); - final AdaptiveHomepageIcon icon = - new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); @@ -118,11 +118,24 @@ public class AdaptiveHomepageIconTest { doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) .when(tile).getIcon(mContext); - final AdaptiveHomepageIcon icon = - new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); assertThat(icon.mBackgroundColor) .isEqualTo(mContext.getColor(R.color.material_blue_500)); } + + @Test + public void getConstantState_returnCorrectState() { + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + icon.setBackgroundColor(Color.YELLOW); + + final AdaptiveIcon.AdaptiveConstantState state = + (AdaptiveIcon.AdaptiveConstantState) icon.getConstantState(); + + assertThat(state.color).isEqualTo(Color.YELLOW); + assertThat(state.context).isEqualTo(mContext); + } }