Move CategoryManager to Settings.
Bug: 77600770
Test: robo
Change-Id: Id4a0c89938d43d21147944b820a191486c589238
diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java
index 9672694..23eb860 100644
--- a/src/com/android/settings/core/SettingsBaseActivity.java
+++ b/src/com/android/settings/core/SettingsBaseActivity.java
@@ -38,7 +38,7 @@
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
-import com.android.settingslib.drawer.CategoryManager;
+import com.android.settings.dashboard.CategoryManager;
import java.util.ArrayList;
import java.util.List;
@@ -172,10 +172,6 @@
new CategoriesUpdateTask().execute();
}
- public String getSettingPkg() {
- return CategoryManager.SETTING_PKG;
- }
-
public interface CategoryListener {
void onCategoriesChanged();
}
@@ -190,7 +186,7 @@
@Override
protected Void doInBackground(Void... params) {
- mCategoryManager.reloadAllCategories(SettingsBaseActivity.this, getSettingPkg());
+ mCategoryManager.reloadAllCategories(SettingsBaseActivity.this);
return null;
}
diff --git a/src/com/android/settings/dashboard/CategoryManager.java b/src/com/android/settings/dashboard/CategoryManager.java
new file mode 100644
index 0000000..f000458
--- /dev/null
+++ b/src/com/android/settings/dashboard/CategoryManager.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.dashboard;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class CategoryManager {
+
+ public static final String SETTING_PKG = "com.android.settings";
+
+ private static final String TAG = "CategoryManager";
+
+ private static CategoryManager sInstance;
+ private final InterestingConfigChanges mInterestingConfigChanges;
+
+ // Tile cache (key: <packageName, activityName>, value: tile)
+ private final Map<Pair<String, String>, Tile> mTileByComponentCache;
+
+ // Tile cache (key: category key, value: category)
+ private final Map<String, DashboardCategory> mCategoryByKeyMap;
+
+ private List<DashboardCategory> mCategories;
+ private String mExtraAction;
+
+ public static CategoryManager get(Context context) {
+ return get(context, null);
+ }
+
+ public static CategoryManager get(Context context, String action) {
+ if (sInstance == null) {
+ sInstance = new CategoryManager(context, action);
+ }
+ return sInstance;
+ }
+
+ CategoryManager(Context context, String action) {
+ mTileByComponentCache = new ArrayMap<>();
+ mCategoryByKeyMap = new ArrayMap<>();
+ mInterestingConfigChanges = new InterestingConfigChanges();
+ mInterestingConfigChanges.applyNewConfig(context.getResources());
+ mExtraAction = action;
+ }
+
+ public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
+ tryInitCategories(context);
+
+ return mCategoryByKeyMap.get(categoryKey);
+ }
+
+ public synchronized List<DashboardCategory> getCategories(Context context) {
+ tryInitCategories(context);
+ return mCategories;
+ }
+
+ public synchronized void reloadAllCategories(Context context) {
+ final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig(
+ context.getResources());
+ mCategories = null;
+ tryInitCategories(context, forceClearCache);
+ }
+
+ public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) {
+ if (mCategories == null) {
+ Log.w(TAG, "Category is null, skipping blacklist update");
+ }
+ for (int i = 0; i < mCategories.size(); i++) {
+ DashboardCategory category = mCategories.get(i);
+ for (int j = 0; j < category.getTilesCount(); j++) {
+ Tile tile = category.getTile(j);
+ if (tileBlacklist.contains(tile.intent.getComponent())) {
+ category.removeTile(j--);
+ }
+ }
+ }
+ }
+
+ private synchronized void tryInitCategories(Context context) {
+ // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
+ // happens.
+ tryInitCategories(context, false /* forceClearCache */);
+ }
+
+ private synchronized void tryInitCategories(Context context, boolean forceClearCache) {
+ if (mCategories == null) {
+ if (forceClearCache) {
+ mTileByComponentCache.clear();
+ }
+ mCategoryByKeyMap.clear();
+ mCategories = TileUtils.getCategories(context, mTileByComponentCache, mExtraAction);
+ for (DashboardCategory category : mCategories) {
+ mCategoryByKeyMap.put(category.key, category);
+ }
+ backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+ sortCategories(context, mCategoryByKeyMap);
+ filterDuplicateTiles(mCategoryByKeyMap);
+ }
+ }
+
+ @VisibleForTesting
+ synchronized void backwardCompatCleanupForCategory(
+ Map<Pair<String, String>, Tile> tileByComponentCache,
+ Map<String, DashboardCategory> categoryByKeyMap) {
+ // A package can use a) CategoryKey, b) old category keys, c) both.
+ // Check if a package uses old category key only.
+ // If yes, map them to new category key.
+
+ // Build a package name -> tile map first.
+ final Map<String, List<Tile>> packageToTileMap = new HashMap<>();
+ for (Entry<Pair<String, String>, Tile> tileEntry : tileByComponentCache.entrySet()) {
+ final String packageName = tileEntry.getKey().first;
+ List<Tile> tiles = packageToTileMap.get(packageName);
+ if (tiles == null) {
+ tiles = new ArrayList<>();
+ packageToTileMap.put(packageName, tiles);
+ }
+ tiles.add(tileEntry.getValue());
+ }
+
+ for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) {
+ final List<Tile> tiles = entry.getValue();
+ // Loop map, find if all tiles from same package uses old key only.
+ boolean useNewKey = false;
+ boolean useOldKey = false;
+ for (Tile tile : tiles) {
+ if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) {
+ useOldKey = true;
+ } else {
+ useNewKey = true;
+ break;
+ }
+ }
+ // Uses only old key, map them to new keys one by one.
+ if (useOldKey && !useNewKey) {
+ for (Tile tile : tiles) {
+ final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category);
+ tile.category = newCategoryKey;
+ // move tile to new category.
+ DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey);
+ if (newCategory == null) {
+ newCategory = new DashboardCategory();
+ categoryByKeyMap.put(newCategoryKey, newCategory);
+ }
+ newCategory.addTile(tile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort the tiles injected from all apps such that if they have the same priority value,
+ * they wil lbe sorted by package name.
+ * <p/>
+ * A list of tiles are considered sorted when their priority value decreases in a linear
+ * scan.
+ */
+ @VisibleForTesting
+ synchronized void sortCategories(Context context,
+ Map<String, DashboardCategory> categoryByKeyMap) {
+ for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+ categoryEntry.getValue().sortTiles(context.getPackageName());
+ }
+ }
+
+ /**
+ * Filter out duplicate tiles from category. Duplicate tiles are the ones pointing to the
+ * same intent.
+ */
+ @VisibleForTesting
+ synchronized void filterDuplicateTiles(Map<String, DashboardCategory> categoryByKeyMap) {
+ for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+ final DashboardCategory category = categoryEntry.getValue();
+ final int count = category.getTilesCount();
+ final Set<ComponentName> components = new ArraySet<>();
+ for (int i = count - 1; i >= 0; i--) {
+ final Tile tile = category.getTile(i);
+ if (tile.intent == null) {
+ continue;
+ }
+ final ComponentName tileComponent = tile.intent.getComponent();
+ if (components.contains(tileComponent)) {
+ category.removeTile(i);
+ } else {
+ components.add(tileComponent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort priority value for tiles within a single {@code DashboardCategory}.
+ *
+ * @see #sortCategories(Context, Map)
+ */
+ private synchronized void sortCategoriesForExternalTiles(Context context,
+ DashboardCategory dashboardCategory) {
+ dashboardCategory.sortTiles(context.getPackageName());
+
+ }
+}
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index a443355..46beac4 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -40,7 +40,6 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
-import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProfileSelectDialog;
import com.android.settingslib.drawer.Tile;
diff --git a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
new file mode 100644
index 0000000..e22f07d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.dashboard;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Pair;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CategoryManagerTest {
+
+ private Context mContext;
+ private CategoryManager mCategoryManager;
+ private Map<Pair<String, String>, Tile> mTileByComponentCache;
+ private Map<String, DashboardCategory> mCategoryByKeyMap;
+
+ @Before
+ public void setUp() {
+ mContext = ShadowApplication.getInstance().getApplicationContext();
+ mTileByComponentCache = new HashMap<>();
+ mCategoryByKeyMap = new HashMap<>();
+ mCategoryManager = CategoryManager.get(mContext);
+ }
+
+ @Test
+ public void getInstance_shouldBeSingleton() {
+ assertThat(mCategoryManager).isSameAs(CategoryManager.get(mContext));
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() {
+ final Tile tile1 = new Tile();
+ final Tile tile2 = new Tile();
+ tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+ tile2.category = CategoryKey.CATEGORY_ACCOUNT;
+ final DashboardCategory category = new DashboardCategory();
+ category.addTile(tile1);
+ category.addTile(tile2);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "1"), tile1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "2"), tile2);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(1);
+ assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT)).isNotNull();
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() {
+ final Tile tile1 = new Tile();
+ final Tile tile2 = new Tile();
+ final String oldCategory = "com.android.settings.category.wireless";
+ tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+ tile2.category = oldCategory;
+ final DashboardCategory category1 = new DashboardCategory();
+ category1.addTile(tile1);
+ final DashboardCategory category2 = new DashboardCategory();
+ category2.addTile(tile2);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1);
+ mCategoryByKeyMap.put(oldCategory, category2);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS2"), tile2);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+ assertThat(
+ mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT).getTilesCount()).isEqualTo(1);
+ assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() {
+ final Tile tile1 = new Tile();
+ final String oldCategory = "com.android.settings.category.wireless";
+ tile1.category = oldCategory;
+ final DashboardCategory category1 = new DashboardCategory();
+ category1.addTile(tile1);
+ mCategoryByKeyMap.put(oldCategory, category1);
+ mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+
+ mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+ // Added 1 more category to category map.
+ assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+ // The new category map has CATEGORY_NETWORK type now, which contains 1 tile.
+ assertThat(
+ mCategoryByKeyMap.get(CategoryKey.CATEGORY_NETWORK).getTilesCount()).isEqualTo(1);
+ // Old category still exists.
+ assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void sortCategories_singlePackage_shouldReorderBasedOnPriority() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage = "com.android.test";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile();
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 50;
+ final Tile tile3 = new Tile();
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 200;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify they are now sorted.
+ assertThat(category.getTile(0)).isSameAs(tile3);
+ assertThat(category.getTile(1)).isSameAs(tile1);
+ assertThat(category.getTile(2)).isSameAs(tile2);
+ }
+
+ @Test
+ public void sortCategories_multiPackage_shouldReorderBasedOnPackageAndPriority() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage1 = "com.android.test1";
+ final String testPackage2 = "com.android.test2";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile();
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage1, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile();
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage1, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify they are now sorted.
+ assertThat(category.getTile(0)).isSameAs(tile2);
+ assertThat(category.getTile(1)).isSameAs(tile1);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ }
+
+ @Test
+ public void sortCategories_internalPackageTiles_shouldSkipTileForInternalPackage() {
+ // Create some fake tiles that are not sorted.
+ final String testPackage =
+ ShadowApplication.getInstance().getApplicationContext().getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile();
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile();
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify the sorting order is not changed
+ assertThat(category.getTile(0)).isSameAs(tile1);
+ assertThat(category.getTile(1)).isSameAs(tile2);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ }
+
+ @Test
+ public void sortCategories_internalAndExternalPackageTiles_shouldRetainPriorityOrdering() {
+ // Inject one external tile among internal tiles.
+ final String testPackage =
+ ShadowApplication.getInstance().getApplicationContext().getPackageName();
+ final String testPackage2 = "com.google.test2";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent = new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 2;
+ final Tile tile2 = new Tile();
+ tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 1;
+ final Tile tile3 = new Tile();
+ tile3.intent = new Intent().setComponent(new ComponentName(testPackage2, "class0"));
+ tile3.priority = 0;
+ final Tile tile4 = new Tile();
+ tile4.intent = new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile4.priority = -1;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ category.addTile(tile4);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify the sorting order is not changed
+ assertThat(category.getTile(0)).isSameAs(tile1);
+ assertThat(category.getTile(1)).isSameAs(tile2);
+ assertThat(category.getTile(2)).isSameAs(tile3);
+ assertThat(category.getTile(3)).isSameAs(tile4);
+ }
+
+ @Test
+ public void sortCategories_samePriority_internalPackageTileShouldTakePrecedence() {
+ // Inject one external tile among internal tiles with same priority.
+ final String testPackage =
+ ShadowApplication.getInstance().getApplicationContext().getPackageName();
+ final String testPackage2 = "com.google.test2";
+ final String testPackage3 = "com.abcde.test3";
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent = new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+ tile1.priority = 1;
+ final Tile tile2 = new Tile();
+ tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 1;
+ final Tile tile3 = new Tile();
+ tile3.intent = new Intent().setComponent(new ComponentName(testPackage3, "class3"));
+ tile3.priority = 1;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ // Sort their priorities
+ mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(),
+ mCategoryByKeyMap);
+
+ // Verify the sorting order is internal first, follow by package name ordering
+ assertThat(category.getTile(0)).isSameAs(tile2);
+ assertThat(category.getTile(1)).isSameAs(tile3);
+ assertThat(category.getTile(2)).isSameAs(tile1);
+ }
+
+ @Test
+ public void filterTiles_noDuplicate_noChange() {
+ // Create some unique tiles
+ final String testPackage =
+ ShadowApplication.getInstance().getApplicationContext().getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile();
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class2"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile();
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class3"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+ assertThat(category.getTilesCount()).isEqualTo(3);
+ }
+
+ @Test
+ public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() {
+ // Create tiles pointing to same intent.
+ final String testPackage =
+ ShadowApplication.getInstance().getApplicationContext().getPackageName();
+ final DashboardCategory category = new DashboardCategory();
+ final Tile tile1 = new Tile();
+ tile1.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile1.priority = 100;
+ final Tile tile2 = new Tile();
+ tile2.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile2.priority = 100;
+ final Tile tile3 = new Tile();
+ tile3.intent =
+ new Intent().setComponent(new ComponentName(testPackage, "class1"));
+ tile3.priority = 50;
+ category.addTile(tile1);
+ category.addTile(tile2);
+ category.addTile(tile3);
+ mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+ mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+ assertThat(category.getTilesCount()).isEqualTo(1);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index bf1e0ff..e541b9f 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -53,7 +53,6 @@
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
import com.android.settingslib.drawer.CategoryKey;
-import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;