From fb36be1a2f82e263281a77d69cda4a012c7b8845 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 7 Oct 2020 18:19:21 +0800 Subject: [PATCH] [Injection] Refine UI behavior for icon_uri 1. Make the icon provided by the content provider override static icon. 2. Apply the background settings "bg.hint" and "bg.argb" to icon_uri. Bug: 167568758 Test: visual, robotest Change-Id: I44c66d8ea2686df1dfe1f9ad28645da7e21414ed --- .../DashboardFeatureProviderImpl.java | 39 +++++++---- .../DashboardFeatureProviderImplTest.java | 69 ++++++++++++++++++- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 82c3668e86b..bfcfc823668 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -357,18 +357,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { @VisibleForTesting void bindIcon(Preference preference, Tile tile, boolean forceRoundedIcon) { - // Use preference context instead here when get icon from Tile, as we are using the context - // to get the style to tint the icon. Using mContext here won't get the correct style. - final Icon tileIcon = tile.getIcon(preference.getContext()); - if (tileIcon != null) { - Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext()); - if (forceRoundedIcon - && !TextUtils.equals(mContext.getPackageName(), tile.getPackageName())) { - iconDrawable = new AdaptiveIcon(mContext, iconDrawable); - ((AdaptiveIcon) iconDrawable).setBackgroundColor(mContext, tile); - } - preference.setIcon(iconDrawable); - } else if (tile.getMetaData() != null + // Icon provided by the content provider overrides any static icon. + if (tile.getMetaData() != null && tile.getMetaData().containsKey(META_DATA_PREFERENCE_ICON_URI)) { ThreadUtils.postOnBackgroundThread(() -> { final Intent intent = tile.getIntent(); @@ -388,11 +378,30 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { return; } final Icon icon = Icon.createWithResource(iconInfo.first, iconInfo.second); - ThreadUtils.postOnMainThread(() -> - preference.setIcon(icon.loadDrawable(preference.getContext())) - ); + ThreadUtils.postOnMainThread(() -> { + setPreferenceIcon(preference, tile, forceRoundedIcon, iconInfo.first, icon); + }); }); + return; } + + // Use preference context instead here when get icon from Tile, as we are using the context + // to get the style to tint the icon. Using mContext here won't get the correct style. + final Icon tileIcon = tile.getIcon(preference.getContext()); + if (tileIcon == null) { + return; + } + setPreferenceIcon(preference, tile, forceRoundedIcon, tile.getPackageName(), tileIcon); + } + + private void setPreferenceIcon(Preference preference, Tile tile, boolean forceRoundedIcon, + String iconPackage, Icon icon) { + Drawable iconDrawable = icon.loadDrawable(preference.getContext()); + if (forceRoundedIcon && !TextUtils.equals(mContext.getPackageName(), iconPackage)) { + iconDrawable = new AdaptiveIcon(mContext, iconDrawable); + ((AdaptiveIcon) iconDrawable).setBackgroundColor(mContext, tile); + } + preference.setIcon(iconDrawable); } private void launchIntentOrSelectProfile(FragmentActivity activity, Tile tile, Intent intent, diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java index b5b0f30bb25..5bc07da6e45 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java @@ -21,6 +21,8 @@ import static android.content.Intent.EXTRA_USER; import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR; import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER; import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI; @@ -48,10 +50,12 @@ import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; +import android.util.Pair; import androidx.fragment.app.FragmentActivity; import androidx.preference.Preference; @@ -60,6 +64,7 @@ import androidx.preference.SwitchPreference; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowTileUtils; import com.android.settings.testutils.shadow.ShadowUserManager; @@ -401,19 +406,77 @@ public class DashboardFeatureProviderImplTest { } @Test - @Config(shadows = {ShadowTileUtils.class}) - public void bindPreference_withIconUri_shouldLoadIconFromContentProvider() { + public void bindIcon_withStaticIcon_shouldLoadStaticIcon() { final Preference preference = new Preference(RuntimeEnvironment.application); mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); - mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, R.drawable.ic_add_40dp); + + mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); + + final Bitmap preferenceBmp = Utils.createIconWithDrawable(preference.getIcon()).getBitmap(); + final Drawable staticIcon = Icon.createWithResource(mActivityInfo.packageName, + R.drawable.ic_add_40dp).loadDrawable(preference.getContext()); + final Bitmap staticIconBmp = Utils.createIconWithDrawable(staticIcon).getBitmap(); + assertThat(preferenceBmp.sameAs(staticIconBmp)).isTrue(); + } + + @Test + @Config(shadows = {ShadowTileUtils.class}) + public void bindIcon_withIconUri_shouldLoadIconFromContentProvider() { + final Preference preference = new Preference(RuntimeEnvironment.application); + mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); + final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_ICON_URI, "content://com.android.settings/tile_icon"); + mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); assertThat(preference.getIcon()).isNotNull(); } + @Test + @Config(shadows = {ShadowTileUtils.class}) + public void bindIcon_withStaticIconAndIconUri_shouldLoadIconFromContentProvider() { + final Preference preference = new Preference(RuntimeEnvironment.application); + mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); + final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, R.drawable.ic_add_40dp); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_ICON_URI, + "content://com.android.settings/tile_icon"); + + mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); + + final Bitmap preferenceBmp = Utils.createIconWithDrawable(preference.getIcon()).getBitmap(); + final Drawable staticIcon = Icon.createWithResource(mActivityInfo.packageName, + R.drawable.ic_add_40dp).loadDrawable(preference.getContext()); + final Bitmap staticIconBmp = Utils.createIconWithDrawable(staticIcon).getBitmap(); + assertThat(preferenceBmp.sameAs(staticIconBmp)).isFalse(); + + final Pair iconInfo = TileUtils.getIconFromUri( + mContext, "pkg", null /* uri */, null /* providerMap */); + final Drawable iconFromUri = Icon.createWithResource(iconInfo.first, iconInfo.second) + .loadDrawable(preference.getContext()); + final Bitmap iconBmpFromUri = Utils.createIconWithDrawable(iconFromUri).getBitmap(); + assertThat(preferenceBmp.sameAs(iconBmpFromUri)).isTrue(); + } + + @Test + @Config(shadows = {ShadowTileUtils.class}) + public void bindIcon_noIcon_shouldNotLoadIcon() { + final Preference preference = new Preference(RuntimeEnvironment.application); + mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); + final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); + + mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); + + assertThat(preference.getIcon()).isNull(); + } + @Test public void bindPreference_withBaseOrder_shouldOffsetOrder() { final int baseOrder = 100;