diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml index 171fe7867d6..6c91aeae70b 100644 --- a/res/xml/top_level_settings.xml +++ b/res/xml/top_level_settings.xml @@ -26,6 +26,7 @@ android:title="@string/network_dashboard_title" android:summary="@string/summary_placeholder" android:icon="@drawable/ic_homepage_network" + android:order="-110" android:fragment="com.android.settings.network.NetworkDashboardFragment" settings:controller="com.android.settings.network.TopLevelNetworkEntryPreferenceController"/> @@ -34,6 +35,7 @@ android:title="@string/connected_devices_dashboard_title" android:summary="@string/summary_placeholder" android:icon="@drawable/ic_homepage_connected_device" + android:order="-100" android:fragment="com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment" settings:controller="com.android.settings.connecteddevice.TopLevelConnectedDevicesPreferenceController"/> @@ -42,6 +44,7 @@ android:title="@string/app_and_notification_dashboard_title" android:summary="@string/app_and_notification_dashboard_summary" android:icon="@drawable/ic_homepage_apps" + android:order="-90" android:fragment="com.android.settings.applications.AppAndNotificationDashboardFragment"/> @@ -79,6 +86,7 @@ android:title="@string/security_settings_title" android:summary="@string/summary_placeholder" android:icon="@drawable/ic_homepage_security" + android:order="-40" android:fragment="com.android.settings.security.SecuritySettings" settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/> @@ -87,6 +95,7 @@ android:title="@string/account_dashboard_title" android:summary="@string/summary_placeholder" android:icon="@drawable/ic_homepage_accounts" + android:order="-30" android:fragment="com.android.settings.accounts.AccountDashboardFragment" settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/> @@ -95,6 +104,7 @@ android:title="@string/accessibility_settings" android:summary="@string/accessibility_settings_summary" android:icon="@drawable/ic_homepage_accessibility" + android:order="-20" android:fragment="com.android.settings.accessibility.AccessibilitySettings"/> + android:icon="@drawable/ic_homepage_support" + android:order="100"/> \ No newline at end of file diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index 5cc1b3b6712..c11c668d8ba 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -16,7 +16,6 @@ package com.android.settings.dashboard; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Bundle; @@ -51,7 +50,6 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.drawer.TileUtils; import com.android.settingslib.suggestions.SuggestionControllerMixinCompat; import com.android.settingslib.utils.IconCache; @@ -65,7 +63,7 @@ public class DashboardAdapter extends RecyclerView.Adapter { diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java index 4c371ddfdc3..f5330a7b5eb 100644 --- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java +++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java @@ -62,8 +62,9 @@ public class DashboardFragmentRegistry { static { PARENT_TO_CATEGORY_KEY_MAP = new ArrayMap<>(); - PARENT_TO_CATEGORY_KEY_MAP.put(TopLevelSettings.class.getName(), - CategoryKey.CATEGORY_HOMEPAGE); + // TODO(b/110405144): Add the mapping when IA.homepage intent-filter is is removed. + // PARENT_TO_CATEGORY_KEY_MAP.put(TopLevelSettings.class.getName(), + // CategoryKey.CATEGORY_HOMEPAGE); PARENT_TO_CATEGORY_KEY_MAP.put( NetworkDashboardFragment.class.getName(), CategoryKey.CATEGORY_NETWORK); PARENT_TO_CATEGORY_KEY_MAP.put(ConnectedDeviceDashboardFragment.class.getName(), diff --git a/src/com/android/settings/widget/RoundedHomepageIcon.java b/src/com/android/settings/widget/RoundedHomepageIcon.java index ab0dfecd4e7..f7927e756ca 100644 --- a/src/com/android/settings/widget/RoundedHomepageIcon.java +++ b/src/com/android/settings/widget/RoundedHomepageIcon.java @@ -18,25 +18,31 @@ package com.android.settings.widget; import static androidx.annotation.VisibleForTesting.NONE; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; + import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import android.os.Bundle; import android.util.Log; -import com.android.settings.R; - import androidx.annotation.VisibleForTesting; +import com.android.settings.R; +import com.android.settingslib.drawer.Tile; + public class RoundedHomepageIcon extends LayerDrawable { private static final String TAG = "RoundedHomepageIcon"; @VisibleForTesting(otherwise = NONE) - public int mBackgroundColor = -1; + int mBackgroundColor = -1; public RoundedHomepageIcon(Context context, Drawable foreground) { - super(new Drawable[] { + super(new Drawable[]{ context.getDrawable(R.drawable.ic_homepage_generic_background), foreground }); @@ -45,6 +51,33 @@ public class RoundedHomepageIcon extends LayerDrawable { setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx); } + public void setBackgroundColor(Context context, Tile tile) { + final Bundle metaData = tile.getMetaData(); + try { + if (metaData != null) { + // Load from bg.argb first + int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, + 0 /* default */); + // Not found, load from bg.hint + if (bgColor == 0) { + final int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, + 0 /* default */); + if (colorRes != 0) { + bgColor = context.getPackageManager() + .getResourcesForApplication(tile.getPackageName()) + .getColor(colorRes, null /* theme */); + } + } + // If found anything, use it. + if (bgColor != 0) { + setBackgroundColor(bgColor); + } + } + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Failed to set background color for " + tile.getPackageName()); + } + } + public void setBackgroundColor(int color) { mBackgroundColor = color; getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP); diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java index 0f84be1e8e9..df6a1a3b713 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java @@ -53,7 +53,6 @@ import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.widget.RoundedHomepageIcon; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.drawer.TileUtils; import com.android.settingslib.utils.IconCache; import org.junit.Before; @@ -115,7 +114,7 @@ public class DashboardAdapterTest { spy(new DashboardAdapter(mContext, null /* savedInstanceState */, null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */)); - final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3"); + final List suggestions = makeSuggestions("pkg1", "pkg2", "pkg3"); adapter.setSuggestions(suggestions); final RecyclerView data = mock(RecyclerView.class); @@ -147,7 +146,7 @@ public class DashboardAdapterTest { spy(new DashboardAdapter(mContext, null /* savedInstanceState */, null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */)); - final List suggestions = makeSuggestionsV2("pkg1"); + final List suggestions = makeSuggestions("pkg1"); adapter.setSuggestions(suggestions); final DashboardData dashboardData = adapter.mDashboardData; reset(adapter); // clear interactions tracking @@ -164,7 +163,7 @@ public class DashboardAdapterTest { spy(new DashboardAdapter(mContext, null /* savedInstanceState */, null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */)); - final List suggestions = makeSuggestionsV2("pkg1"); + final List suggestions = makeSuggestions("pkg1"); adapter.setSuggestions(suggestions); reset(adapter); // clear interactions tracking @@ -178,7 +177,7 @@ public class DashboardAdapterTest { public void onBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() { mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */, null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */); - final List suggestions = makeSuggestionsV2("pkg1"); + final List suggestions = makeSuggestions("pkg1"); mDashboardAdapter.setSuggestions(suggestions); @@ -243,55 +242,6 @@ public class DashboardAdapterTest { .isInstanceOf(RoundedHomepageIcon.class); } - @Test - public void onBindTile_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() { - final Context context = spy(RuntimeEnvironment.application); - final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null); - final DashboardAdapter.DashboardItemHolder holder = - new DashboardAdapter.DashboardItemHolder(view); - final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - tile.getMetaData().putInt(DashboardAdapter.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, - 0xff0000); - doReturn(Icon.createWithResource(context, R.drawable.ic_settings)) - .when(tile).getIcon(context); - final IconCache iconCache = new IconCache(context); - mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */, - null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */); - ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache); - - doReturn("another.package").when(context).getPackageName(); - mDashboardAdapter.onBindTile(holder, tile); - - final RoundedHomepageIcon homepageIcon = (RoundedHomepageIcon) iconCache.getIcon( - tile.getIcon(context)); - assertThat(homepageIcon.mBackgroundColor).isEqualTo(0xff0000); - } - - @Test - public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() { - final Context context = spy(RuntimeEnvironment.application); - final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null); - final DashboardAdapter.DashboardItemHolder holder = - new DashboardAdapter.DashboardItemHolder(view); - final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - tile.getMetaData().putInt(TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, - R.color.memory_critical); - doReturn(Icon.createWithResource(context, R.drawable.ic_settings)) - .when(tile).getIcon(context); - final IconCache iconCache = new IconCache(context); - mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */, - null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */); - ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache); - - doReturn("another.package").when(context).getPackageName(); - mDashboardAdapter.onBindTile(holder, tile); - - final RoundedHomepageIcon homepageIcon = (RoundedHomepageIcon) iconCache.getIcon( - tile.getIcon(context)); - assertThat(homepageIcon.mBackgroundColor) - .isEqualTo(RuntimeEnvironment.application.getColor(R.color.memory_critical)); - } - @Test public void onBindTile_externalTile_usingRoundedHomepageIcon_shouldNotUpdateIcon() { final Context context = RuntimeEnvironment.application; @@ -315,7 +265,7 @@ public class DashboardAdapterTest { any(RoundedHomepageIcon.class)); } - private List makeSuggestionsV2(String... pkgNames) { + private List makeSuggestions(String... pkgNames) { final List suggestions = new ArrayList<>(); for (String pkgName : pkgNames) { final Suggestion suggestion = new Suggestion.Builder(pkgName) diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java index dbaf8fe5b30..22c589c8fd6 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java @@ -291,7 +291,7 @@ public class DashboardFeatureProviderImplTest { mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, "content://com.android.settings/tile_icon"); - mImpl.bindIcon(preference, tile); + mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); assertThat(preference.getIcon()).isNotNull(); } diff --git a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java b/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java index 177dba0083e..042341b24db 100644 --- a/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java +++ b/tests/robotests/src/com/android/settings/widget/RoundedHomepageIconTest.java @@ -16,21 +16,30 @@ package com.android.settings.widget; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.pm.ActivityInfo; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Icon; import android.graphics.drawable.ShapeDrawable; +import android.os.Bundle; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.drawer.CategoryKey; +import com.android.settingslib.drawer.Tile; import org.junit.Before; import org.junit.Test; @@ -41,10 +50,15 @@ import org.robolectric.RuntimeEnvironment; public class RoundedHomepageIconTest { private Context mContext; + private ActivityInfo mActivityInfo; @Before public void setUp() { mContext = RuntimeEnvironment.application; + mActivityInfo = new ActivityInfo(); + mActivityInfo.packageName = mContext.getPackageName(); + mActivityInfo.name = "class"; + mActivityInfo.metaData = new Bundle(); } @Test @@ -68,4 +82,34 @@ public class RoundedHomepageIconTest { verify(background).setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP); } + + @Test + public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() { + final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); + doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings)) + .when(tile).getIcon(mContext); + final RoundedHomepageIcon icon = + new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + + icon.setBackgroundColor(mContext, tile); + assertThat(icon.mBackgroundColor).isEqualTo(0xff0000); + } + + @Test + public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() { + final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, + R.color.memory_critical); + doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings)) + .when(tile).getIcon(mContext); + + final RoundedHomepageIcon icon = + new RoundedHomepageIcon(mContext, new ColorDrawable(Color.BLACK)); + icon.setBackgroundColor(mContext, tile); + + assertThat(icon.mBackgroundColor) + .isEqualTo(mContext.getColor(R.color.memory_critical)); + } + }