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"/>
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"/>
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"/>
<Preference
android:summary="@string/summary_placeholder"
android:icon="@drawable/ic_homepage_battery"
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
+ android:order="-80"
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
<Preference
android:title="@string/display_settings"
android:summary="@string/display_dashboard_summary"
android:icon="@drawable/ic_homepage_display"
+ android:order="-70"
android:fragment="com.android.settings.DisplaySettings"/>
<Preference
android:title="@string/sound_settings"
android:summary="@string/sound_dashboard_summary"
android:icon="@drawable/ic_homepage_sound"
+ android:order="-60"
android:fragment="com.android.settings.notification.SoundSettings"/>
<Preference
android:title="@string/storage_settings"
android:summary="@string/summary_placeholder"
android:icon="@drawable/ic_homepage_storage"
+ android:order="-50"
android:fragment="com.android.settings.deviceinfo.StorageSettings"
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
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"/>
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"/>
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"/>
<Preference
android:title="@string/header_category_system"
android:summary="@string/system_dashboard_summary"
android:icon="@drawable/ic_homepage_system_dashboard"
+ android:order="-10"
android:fragment="com.android.settings.system.SystemDashboardFragment"/>
<Preference
android:key="top_level_support"
android:summary="@string/support_summary"
android:title="@string/page_tab_title_support"
- android:icon="@drawable/ic_homepage_support"/>
+ android:icon="@drawable/ic_homepage_support"
+ android:order="100"/>
</PreferenceScreen>
\ No newline at end of file
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;
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;
@VisibleForTesting
static final String STATE_CONDITION_EXPANDED = "condition_expanded";
- static final String META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB = "com.android.settings.bg.argb";
+
private final IconCache mCache;
private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider;
return mDashboardData.getItemEntityById(itemId);
}
- public Suggestion getSuggestion(int position) {
- return mSuggestionAdapter.getSuggestion(position);
- }
-
@VisibleForTesting
void notifyDashboardDataChanged(DashboardData prevData) {
if (mFirstFrameDrawn && prevData != null) {
if (!TextUtils.equals(tileIcon.getResPackage(), mContext.getPackageName())
&& !(icon instanceof RoundedHomepageIcon)) {
icon = new RoundedHomepageIcon(mContext, icon);
- 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(
- TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
- 0 /* default */);
- if (colorRes != 0) {
- bgColor = mContext.getPackageManager()
- .getResourcesForApplication(tileIcon.getResPackage())
- .getColor(colorRes, null /* theme */);
- }
- }
- // If found anything, use it.
- if (bgColor != 0) {
- ((RoundedHomepageIcon) icon).setBackgroundColor(bgColor);
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Failed to set background color for " + tile.getPackageName());
- }
+ ((RoundedHomepageIcon) icon).setBackgroundColor(mContext, tile);
mCache.updateIcon(tileIcon, icon);
}
holder.icon.setImageDrawable(icon);
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.provider.Settings;
import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.RoundedHomepageIcon;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.TileUtils;
import com.android.settingslib.utils.ThreadUtils;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
pref.setKey(getDashboardKeyForTile(tile));
}
bindSummary(pref, tile);
- bindIcon(pref, tile);
+ bindIcon(pref, tile, forceRoundedIcon);
final Bundle metadata = tile.getMetaData();
String clsName = null;
String action = null;
}
@VisibleForTesting
- void bindIcon(Preference preference, Tile tile) {
+ void bindIcon(Preference preference, Tile tile, boolean forceRoundedIcon) {
final Icon tileIcon = tile.getIcon(mContext);
if (tileIcon != null) {
- preference.setIcon(tileIcon.loadDrawable(preference.getContext()));
+ Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext());
+ if (forceRoundedIcon
+ && !TextUtils.equals(mContext.getPackageName(), tile.getPackageName())) {
+ iconDrawable = new RoundedHomepageIcon(mContext, iconDrawable);
+ ((RoundedHomepageIcon) iconDrawable).setBackgroundColor(mContext, tile);
+ }
+ preference.setIcon(iconDrawable);
} else if (tile.getMetaData() != null
&& tile.getMetaData().containsKey(META_DATA_PREFERENCE_ICON_URI)) {
ThreadUtils.postOnBackgroundThread(() -> {
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(),
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
});
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);
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;
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */,
null /* lifecycle */));
- final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
+ final List<Suggestion> suggestions = makeSuggestions("pkg1", "pkg2", "pkg3");
adapter.setSuggestions(suggestions);
final RecyclerView data = mock(RecyclerView.class);
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */,
null /* lifecycle */));
- final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
+ final List<Suggestion> suggestions = makeSuggestions("pkg1");
adapter.setSuggestions(suggestions);
final DashboardData dashboardData = adapter.mDashboardData;
reset(adapter); // clear interactions tracking
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */,
null /* lifecycle */));
- final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
+ final List<Suggestion> suggestions = makeSuggestions("pkg1");
adapter.setSuggestions(suggestions);
reset(adapter); // clear interactions tracking
public void onBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
- final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
+ final List<Suggestion> suggestions = makeSuggestions("pkg1");
mDashboardAdapter.setSuggestions(suggestions);
}
@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;
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
any(RoundedHomepageIcon.class));
}
- private List<Suggestion> makeSuggestionsV2(String... pkgNames) {
+ private List<Suggestion> makeSuggestions(String... pkgNames) {
final List<Suggestion> suggestions = new ArrayList<>();
for (String pkgName : pkgNames) {
final Suggestion suggestion = new Suggestion.Builder(pkgName)
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();
}
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;
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
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));
+ }
+
}