122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang/** 222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * Copyright (C) 2016 The Android Open Source Project 322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * 422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * you may not use this file except in compliance with the License. 622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * You may obtain a copy of the License at 722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * 8c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang * http://www.apache.org/licenses/LICENSE-2.0 922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * 1022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * Unless required by applicable law or agreed to in writing, software 1122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * distributed under the License is distributed on an "AS IS" BASIS, 1222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * See the License for the specific language governing permissions and 1422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang * limitations under the License. 1522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang */ 1622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangpackage com.android.settingslib.drawer; 1722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 1822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.content.ComponentName; 1922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.content.Context; 20914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhangimport android.support.annotation.VisibleForTesting; 2122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.ArrayMap; 225fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhangimport android.util.ArraySet; 2322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.Log; 2422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.Pair; 2522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 265adc26695fb4282125d4b6b641e04820a028d87bFan Zhangimport com.android.settingslib.applications.InterestingConfigChanges; 275adc26695fb4282125d4b6b641e04820a028d87bFan Zhang 2831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.ArrayList; 2931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.HashMap; 3022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.List; 3122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Map; 3231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.Map.Entry; 3322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Set; 3422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 35fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhangimport static java.lang.String.CASE_INSENSITIVE_ORDER; 36fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang 3722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangpublic class CategoryManager { 3822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 3922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private static final String TAG = "CategoryManager"; 4022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private static CategoryManager sInstance; 425adc26695fb4282125d4b6b641e04820a028d87bFan Zhang private final InterestingConfigChanges mInterestingConfigChanges; 4322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang // Tile cache (key: <packageName, activityName>, value: tile) 4522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private final Map<Pair<String, String>, Tile> mTileByComponentCache; 4622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang // Tile cache (key: category key, value: category) 4822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private final Map<String, DashboardCategory> mCategoryByKeyMap; 4922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 5022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private List<DashboardCategory> mCategories; 51485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling private String mExtraAction; 5222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 535adc26695fb4282125d4b6b641e04820a028d87bFan Zhang public static CategoryManager get(Context context) { 54485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling return get(context, null); 55485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling } 56485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling 57485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling public static CategoryManager get(Context context, String action) { 5822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (sInstance == null) { 59485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling sInstance = new CategoryManager(context, action); 6022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 6122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang return sInstance; 6222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 6322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 64485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling CategoryManager(Context context, String action) { 6522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mTileByComponentCache = new ArrayMap<>(); 6622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap = new ArrayMap<>(); 675adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mInterestingConfigChanges = new InterestingConfigChanges(); 685adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mInterestingConfigChanges.applyNewConfig(context.getResources()); 69485df11f7770edc6c7d0f87ade5b2e0aa40e7e59Doris Ling mExtraAction = action; 7022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 7122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 72c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) { 738f06ab0774d44c49fbb5b122b7266192c49271c0roger xue return getTilesByCategory(context, categoryKey, TileUtils.SETTING_PKG); 748f06ab0774d44c49fbb5b122b7266192c49271c0roger xue } 758f06ab0774d44c49fbb5b122b7266192c49271c0roger xue 768f06ab0774d44c49fbb5b122b7266192c49271c0roger xue public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey, 778f06ab0774d44c49fbb5b122b7266192c49271c0roger xue String settingPkg) { 788f06ab0774d44c49fbb5b122b7266192c49271c0roger xue tryInitCategories(context, settingPkg); 7922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 8045c891b7c5fb6eab719cb9a92c38bbdb25b28ab3Fan Zhang return mCategoryByKeyMap.get(categoryKey); 8122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 8222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 83c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized List<DashboardCategory> getCategories(Context context) { 848f06ab0774d44c49fbb5b122b7266192c49271c0roger xue return getCategories(context, TileUtils.SETTING_PKG); 858f06ab0774d44c49fbb5b122b7266192c49271c0roger xue } 868f06ab0774d44c49fbb5b122b7266192c49271c0roger xue 878f06ab0774d44c49fbb5b122b7266192c49271c0roger xue public synchronized List<DashboardCategory> getCategories(Context context, String settingPkg) { 888f06ab0774d44c49fbb5b122b7266192c49271c0roger xue tryInitCategories(context, settingPkg); 8922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang return mCategories; 9022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 928f06ab0774d44c49fbb5b122b7266192c49271c0roger xue public synchronized void reloadAllCategories(Context context, String settingPkg) { 935adc26695fb4282125d4b6b641e04820a028d87bFan Zhang final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig( 945adc26695fb4282125d4b6b641e04820a028d87bFan Zhang context.getResources()); 95c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang mCategories = null; 968f06ab0774d44c49fbb5b122b7266192c49271c0roger xue tryInitCategories(context, forceClearCache, settingPkg); 9722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 99c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) { 10022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (mCategories == null) { 10122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang Log.w(TAG, "Category is null, skipping blacklist update"); 10222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 10322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang for (int i = 0; i < mCategories.size(); i++) { 10422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang DashboardCategory category = mCategories.get(i); 105b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling for (int j = 0; j < category.getTilesCount(); j++) { 106b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling Tile tile = category.getTile(j); 10722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (tileBlacklist.contains(tile.intent.getComponent())) { 108b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling category.removeTile(j--); 10922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 1148f06ab0774d44c49fbb5b122b7266192c49271c0roger xue private synchronized void tryInitCategories(Context context, String settingPkg) { 1155adc26695fb4282125d4b6b641e04820a028d87bFan Zhang // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange 1165adc26695fb4282125d4b6b641e04820a028d87bFan Zhang // happens. 1178f06ab0774d44c49fbb5b122b7266192c49271c0roger xue tryInitCategories(context, false /* forceClearCache */, settingPkg); 1185adc26695fb4282125d4b6b641e04820a028d87bFan Zhang } 1195adc26695fb4282125d4b6b641e04820a028d87bFan Zhang 1208f06ab0774d44c49fbb5b122b7266192c49271c0roger xue private synchronized void tryInitCategories(Context context, boolean forceClearCache, 1218f06ab0774d44c49fbb5b122b7266192c49271c0roger xue String settingPkg) { 12222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (mCategories == null) { 1235adc26695fb4282125d4b6b641e04820a028d87bFan Zhang if (forceClearCache) { 1245adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mTileByComponentCache.clear(); 1255adc26695fb4282125d4b6b641e04820a028d87bFan Zhang } 12622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap.clear(); 12722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategories = TileUtils.getCategories(context, mTileByComponentCache, 1288f06ab0774d44c49fbb5b122b7266192c49271c0roger xue false /* categoryDefinedInManifest */, mExtraAction, settingPkg); 12922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang for (DashboardCategory category : mCategories) { 13022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap.put(category.key, category); 13122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 132914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap); 133ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling sortCategories(context, mCategoryByKeyMap); 1345fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang filterDuplicateTiles(mCategoryByKeyMap); 13522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 13622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 13722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 138914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang @VisibleForTesting 139914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang synchronized void backwardCompatCleanupForCategory( 140914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang Map<Pair<String, String>, Tile> tileByComponentCache, 141914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang Map<String, DashboardCategory> categoryByKeyMap) { 14231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // A package can use a) CategoryKey, b) old category keys, c) both. 14331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Check if a package uses old category key only. 14431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // If yes, map them to new category key. 14531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang 14631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Build a package name -> tile map first. 14731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final Map<String, List<Tile>> packageToTileMap = new HashMap<>(); 148914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang for (Entry<Pair<String, String>, Tile> tileEntry : tileByComponentCache.entrySet()) { 14931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final String packageName = tileEntry.getKey().first; 15031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang List<Tile> tiles = packageToTileMap.get(packageName); 15131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (tiles == null) { 15231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tiles = new ArrayList<>(); 15331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang packageToTileMap.put(packageName, tiles); 15431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tiles.add(tileEntry.getValue()); 15631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang 15831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) { 15931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final List<Tile> tiles = entry.getValue(); 16031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Loop map, find if all tiles from same package uses old key only. 16131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang boolean useNewKey = false; 16231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang boolean useOldKey = false; 16331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Tile tile : tiles) { 16431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) { 16531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang useOldKey = true; 16631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } else { 16731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang useNewKey = true; 16831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang break; 16931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 17031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 17131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Uses only old key, map them to new keys one by one. 17231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (useOldKey && !useNewKey) { 17331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Tile tile : tiles) { 17431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category); 17531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tile.category = newCategoryKey; 17631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // move tile to new category. 177914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey); 178914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang if (newCategory == null) { 179914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang newCategory = new DashboardCategory(); 180914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang categoryByKeyMap.put(newCategoryKey, newCategory); 181914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang } 182b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling newCategory.addTile(tile); 18331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 18431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 18531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 18631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 187fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang 188fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang /** 189ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling * Sort the tiles injected from all apps such that if they have the same priority value, 190ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling * they wil lbe sorted by package name. 191fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang * <p/> 192ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling * A list of tiles are considered sorted when their priority value decreases in a linear 193fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang * scan. 194fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang */ 195fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang @VisibleForTesting 196ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling synchronized void sortCategories(Context context, 197fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang Map<String, DashboardCategory> categoryByKeyMap) { 198fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) { 199b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling categoryEntry.getValue().sortTiles(context.getPackageName()); 200fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang } 201fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang } 202fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang 203fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang /** 2045fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang * Filter out duplicate tiles from category. Duplicate tiles are the ones pointing to the 2055fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang * same intent. 2065fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang */ 2075fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang @VisibleForTesting 2085fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang synchronized void filterDuplicateTiles(Map<String, DashboardCategory> categoryByKeyMap) { 2095fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) { 2105fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang final DashboardCategory category = categoryEntry.getValue(); 211b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling final int count = category.getTilesCount(); 2125fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang final Set<ComponentName> components = new ArraySet<>(); 2135fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang for (int i = count - 1; i >= 0; i--) { 214b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling final Tile tile = category.getTile(i); 2155fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang if (tile.intent == null) { 2165fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang continue; 2175fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } 2185fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang final ComponentName tileComponent = tile.intent.getComponent(); 2195fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang if (components.contains(tileComponent)) { 220b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling category.removeTile(i); 2215fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } else { 2225fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang components.add(tileComponent); 2235fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } 2245fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } 2255fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } 2265fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang } 2275fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang 2285fa4af08c603607d7df7470dc10d3af2d2f04137Fan Zhang /** 229ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling * Sort priority value for tiles within a single {@code DashboardCategory}. 230fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang * 231ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling * @see #sortCategories(Context, Map) 232fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang */ 233ce31159be781f5b94ed24013fcf1db7b9aa0cf4aDoris Ling private synchronized void sortCategoriesForExternalTiles(Context context, 234fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang DashboardCategory dashboardCategory) { 235b8d2cd41e9472d6f860f35ee9a073b89ba9507f0Doris Ling dashboardCategory.sortTiles(context.getPackageName()); 236fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang 237fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang } 23822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang} 239