CategoryManager.java revision 31f4c5444490cd7db7c9089e9ca3e8a2904c6d5b
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; 2022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.ArrayMap; 2122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.Log; 2222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.Pair; 2322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 245adc26695fb4282125d4b6b641e04820a028d87bFan Zhangimport com.android.settingslib.applications.InterestingConfigChanges; 255adc26695fb4282125d4b6b641e04820a028d87bFan Zhang 2631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.ArrayList; 2731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.HashMap; 2822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.List; 2922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Map; 3031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.Map.Entry; 3122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Set; 3222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 3322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangpublic class CategoryManager { 3422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 3522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private static final String TAG = "CategoryManager"; 3622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 3722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private static CategoryManager sInstance; 385adc26695fb4282125d4b6b641e04820a028d87bFan Zhang private final InterestingConfigChanges mInterestingConfigChanges; 3922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang // Tile cache (key: <packageName, activityName>, value: tile) 4122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private final Map<Pair<String, String>, Tile> mTileByComponentCache; 4222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang // Tile cache (key: category key, value: category) 4422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private final Map<String, DashboardCategory> mCategoryByKeyMap; 4522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 4622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang private List<DashboardCategory> mCategories; 4722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 485adc26695fb4282125d4b6b641e04820a028d87bFan Zhang public static CategoryManager get(Context context) { 4922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (sInstance == null) { 505adc26695fb4282125d4b6b641e04820a028d87bFan Zhang sInstance = new CategoryManager(context); 5122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 5222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang return sInstance; 5322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 5422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 555adc26695fb4282125d4b6b641e04820a028d87bFan Zhang CategoryManager(Context context) { 5622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mTileByComponentCache = new ArrayMap<>(); 5722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap = new ArrayMap<>(); 585adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mInterestingConfigChanges = new InterestingConfigChanges(); 595adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mInterestingConfigChanges.applyNewConfig(context.getResources()); 6022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 6122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 62c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) { 6322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang tryInitCategories(context); 6422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 6545c891b7c5fb6eab719cb9a92c38bbdb25b28ab3Fan Zhang return mCategoryByKeyMap.get(categoryKey); 6622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 6722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 68c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized List<DashboardCategory> getCategories(Context context) { 6922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang tryInitCategories(context); 7022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang return mCategories; 7122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 7222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 73c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized void reloadAllCategories(Context context) { 745adc26695fb4282125d4b6b641e04820a028d87bFan Zhang final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig( 755adc26695fb4282125d4b6b641e04820a028d87bFan Zhang context.getResources()); 76c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang mCategories = null; 775adc26695fb4282125d4b6b641e04820a028d87bFan Zhang tryInitCategories(context, forceClearCache); 7822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 7922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 80c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) { 8122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (mCategories == null) { 8222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang Log.w(TAG, "Category is null, skipping blacklist update"); 8322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 8422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang for (int i = 0; i < mCategories.size(); i++) { 8522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang DashboardCategory category = mCategories.get(i); 8622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang for (int j = 0; j < category.tiles.size(); j++) { 8722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang Tile tile = category.tiles.get(j); 8822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (tileBlacklist.contains(tile.intent.getComponent())) { 8922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang category.tiles.remove(j--); 9022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 9422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 95c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang private synchronized void tryInitCategories(Context context) { 965adc26695fb4282125d4b6b641e04820a028d87bFan Zhang // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange 975adc26695fb4282125d4b6b641e04820a028d87bFan Zhang // happens. 985adc26695fb4282125d4b6b641e04820a028d87bFan Zhang tryInitCategories(context, false /* forceClearCache */); 995adc26695fb4282125d4b6b641e04820a028d87bFan Zhang } 1005adc26695fb4282125d4b6b641e04820a028d87bFan Zhang 1015adc26695fb4282125d4b6b641e04820a028d87bFan Zhang private synchronized void tryInitCategories(Context context, boolean forceClearCache) { 10222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang if (mCategories == null) { 1035adc26695fb4282125d4b6b641e04820a028d87bFan Zhang if (forceClearCache) { 1045adc26695fb4282125d4b6b641e04820a028d87bFan Zhang mTileByComponentCache.clear(); 1055adc26695fb4282125d4b6b641e04820a028d87bFan Zhang } 10622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap.clear(); 10722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategories = TileUtils.getCategories(context, mTileByComponentCache, 10822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang false /* categoryDefinedInManifest */); 10922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang for (DashboardCategory category : mCategories) { 11022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang mCategoryByKeyMap.put(category.key, category); 11122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang backwardCompatCleanupForCategory(); 11322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang } 11522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang 11631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang private synchronized void backwardCompatCleanupForCategory() { 11731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // A package can use a) CategoryKey, b) old category keys, c) both. 11831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Check if a package uses old category key only. 11931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // If yes, map them to new category key. 12031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang 12131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Build a package name -> tile map first. 12231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final Map<String, List<Tile>> packageToTileMap = new HashMap<>(); 12331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Entry<Pair<String, String>, Tile> tileEntry : mTileByComponentCache.entrySet()) { 12431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final String packageName = tileEntry.getKey().first; 12531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang List<Tile> tiles = packageToTileMap.get(packageName); 12631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (tiles == null) { 12731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tiles = new ArrayList<>(); 12831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang packageToTileMap.put(packageName, tiles); 12931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 13031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tiles.add(tileEntry.getValue()); 13131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 13231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang 13331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) { 13431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final List<Tile> tiles = entry.getValue(); 13531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Loop map, find if all tiles from same package uses old key only. 13631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang boolean useNewKey = false; 13731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang boolean useOldKey = false; 13831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Tile tile : tiles) { 13931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) { 14031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang useOldKey = true; 14131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } else { 14231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang useNewKey = true; 14331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang break; 14431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 14531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 14631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // Uses only old key, map them to new keys one by one. 14731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang if (useOldKey && !useNewKey) { 14831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang for (Tile tile : tiles) { 14931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category); 15031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang tile.category = newCategoryKey; 15131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang // move tile to new category. 15231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang final DashboardCategory newCategory = mCategoryByKeyMap.get(newCategoryKey); 15331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang newCategory.tiles.add(tile); 15431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang } 15822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang} 159