CategoryManager.java revision fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03a
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;
21fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhangimport android.text.TextUtils;
2222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport android.util.ArrayMap;
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;
29fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhangimport java.util.Collections;
3031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.HashMap;
3122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.List;
3222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Map;
3331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhangimport java.util.Map.Entry;
3422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangimport java.util.Set;
3522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
36fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhangimport static java.lang.String.CASE_INSENSITIVE_ORDER;
37fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang
3822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhangpublic class CategoryManager {
3922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
4022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    private static final String TAG = "CategoryManager";
4122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
4222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    private static CategoryManager sInstance;
435adc26695fb4282125d4b6b641e04820a028d87bFan Zhang    private final InterestingConfigChanges mInterestingConfigChanges;
4422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
4522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    // Tile cache (key: <packageName, activityName>, value: tile)
4622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    private final Map<Pair<String, String>, Tile> mTileByComponentCache;
4722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
4822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    // Tile cache (key: category key, value: category)
4922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    private final Map<String, DashboardCategory> mCategoryByKeyMap;
5022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
5122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    private List<DashboardCategory> mCategories;
5222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
535adc26695fb4282125d4b6b641e04820a028d87bFan Zhang    public static CategoryManager get(Context context) {
5422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        if (sInstance == null) {
555adc26695fb4282125d4b6b641e04820a028d87bFan Zhang            sInstance = new CategoryManager(context);
5622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        }
5722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        return sInstance;
5822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
5922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
605adc26695fb4282125d4b6b641e04820a028d87bFan Zhang    CategoryManager(Context context) {
6122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        mTileByComponentCache = new ArrayMap<>();
6222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        mCategoryByKeyMap = new ArrayMap<>();
635adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        mInterestingConfigChanges = new InterestingConfigChanges();
645adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        mInterestingConfigChanges.applyNewConfig(context.getResources());
6522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
6622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
67c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang    public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
6822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        tryInitCategories(context);
6922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
7045c891b7c5fb6eab719cb9a92c38bbdb25b28ab3Fan Zhang        return mCategoryByKeyMap.get(categoryKey);
7122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
7222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
73c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang    public synchronized List<DashboardCategory> getCategories(Context context) {
7422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        tryInitCategories(context);
7522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        return mCategories;
7622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
7722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
78c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang    public synchronized void reloadAllCategories(Context context) {
795adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig(
805adc26695fb4282125d4b6b641e04820a028d87bFan Zhang                context.getResources());
81c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang        mCategories = null;
825adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        tryInitCategories(context, forceClearCache);
8322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
8422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
85c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang    public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) {
8622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        if (mCategories == null) {
8722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            Log.w(TAG, "Category is null, skipping blacklist update");
8822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        }
8922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        for (int i = 0; i < mCategories.size(); i++) {
9022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            DashboardCategory category = mCategories.get(i);
9122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            for (int j = 0; j < category.tiles.size(); j++) {
9222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                Tile tile = category.tiles.get(j);
9322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                if (tileBlacklist.contains(tile.intent.getComponent())) {
9422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                    category.tiles.remove(j--);
9522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                }
9622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            }
9722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        }
9822a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
9922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
100c8a5b790fa13826b21aee97ed5d1960d785333daFan Zhang    private synchronized void tryInitCategories(Context context) {
1015adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
1025adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        // happens.
1035adc26695fb4282125d4b6b641e04820a028d87bFan Zhang        tryInitCategories(context, false /* forceClearCache */);
1045adc26695fb4282125d4b6b641e04820a028d87bFan Zhang    }
1055adc26695fb4282125d4b6b641e04820a028d87bFan Zhang
1065adc26695fb4282125d4b6b641e04820a028d87bFan Zhang    private synchronized void tryInitCategories(Context context, boolean forceClearCache) {
10722a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        if (mCategories == null) {
1085adc26695fb4282125d4b6b641e04820a028d87bFan Zhang            if (forceClearCache) {
1095adc26695fb4282125d4b6b641e04820a028d87bFan Zhang                mTileByComponentCache.clear();
1105adc26695fb4282125d4b6b641e04820a028d87bFan Zhang            }
11122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            mCategoryByKeyMap.clear();
11222a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            mCategories = TileUtils.getCategories(context, mTileByComponentCache,
11322a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                    false /* categoryDefinedInManifest */);
11422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            for (DashboardCategory category : mCategories) {
11522a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang                mCategoryByKeyMap.put(category.key, category);
11622a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang            }
117914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang            backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
118fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            normalizePriority(context, mCategoryByKeyMap);
11922a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang        }
12022a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang    }
12122a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang
122914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang    @VisibleForTesting
123914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang    synchronized void backwardCompatCleanupForCategory(
124914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang            Map<Pair<String, String>, Tile> tileByComponentCache,
125914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang            Map<String, DashboardCategory> categoryByKeyMap) {
12631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        // A package can use a) CategoryKey, b) old category keys, c) both.
12731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        // Check if a package uses old category key only.
12831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        // If yes, map them to new category key.
12931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang
13031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        // Build a package name -> tile map first.
13131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        final Map<String, List<Tile>> packageToTileMap = new HashMap<>();
132914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang        for (Entry<Pair<String, String>, Tile> tileEntry : tileByComponentCache.entrySet()) {
13331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            final String packageName = tileEntry.getKey().first;
13431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            List<Tile> tiles = packageToTileMap.get(packageName);
13531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            if (tiles == null) {
13631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                tiles = new ArrayList<>();
13731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                packageToTileMap.put(packageName, tiles);
13831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            }
13931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            tiles.add(tileEntry.getValue());
14031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        }
14131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang
14231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) {
14331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            final List<Tile> tiles = entry.getValue();
14431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            // Loop map, find if all tiles from same package uses old key only.
14531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            boolean useNewKey = false;
14631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            boolean useOldKey = false;
14731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            for (Tile tile : tiles) {
14831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) {
14931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    useOldKey = true;
15031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                } else {
15131f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    useNewKey = true;
15231f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    break;
15331f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                }
15431f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            }
15531f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            // Uses only old key, map them to new keys one by one.
15631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            if (useOldKey && !useNewKey) {
15731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                for (Tile tile : tiles) {
15831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category);
15931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    tile.category = newCategoryKey;
16031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    // move tile to new category.
161914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang                    DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey);
162914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang                    if (newCategory == null) {
163914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang                        newCategory = new DashboardCategory();
164914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang                        categoryByKeyMap.put(newCategoryKey, newCategory);
165914afbfbd048721fb9ece683b9e881b79a01e34eFan Zhang                    }
16631f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                    newCategory.tiles.add(tile);
16731f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang                }
16831f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang            }
16931f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang        }
17031f4c5444490cd7db7c9089e9ca3e8a2904c6d5bFan Zhang    }
171fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang
172fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    /**
173fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * Normalize priority values on tiles across injected from all apps to make sure they don't set
174fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * the same priority value. However internal tiles' priority remains unchanged.
175fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * <p/>
176fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * A list of tiles are considered normalized when their priority value increases in a linear
177fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * scan.
178fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     */
179fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    @VisibleForTesting
180fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    synchronized void normalizePriority(Context context,
181fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            Map<String, DashboardCategory> categoryByKeyMap) {
182fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
183fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            normalizePriorityForExternalTiles(context, categoryEntry.getValue());
184fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        }
185fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    }
186fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang
187fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    /**
188fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * Normalize priority value for tiles within a single {@code DashboardCategory}.
189fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     *
190fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     * @see #normalizePriority(Context, Map)
191fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang     */
192fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    private synchronized void normalizePriorityForExternalTiles(Context context,
193fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            DashboardCategory dashboardCategory) {
194fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        final String skipPackageName = context.getPackageName();
195fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang
196fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        // Sort tiles based on [package, priority within package]
197fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        Collections.sort(dashboardCategory.tiles, (tile1, tile2) -> {
198fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            final String package1 = tile1.intent.getComponent().getPackageName();
199fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            final String package2 = tile2.intent.getComponent().getPackageName();
200fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            final int packageCompare = CASE_INSENSITIVE_ORDER.compare(package1, package2);
201fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            // First sort by package name
202fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            if (packageCompare != 0) {
203fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                return packageCompare;
204fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            } else if (TextUtils.equals(package1, skipPackageName)) {
205fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                return 0;
206fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            }
207fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            // Then sort by priority
208fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            return tile1.priority - tile2.priority;
209fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        });
210fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        // Update priority for all items so no package define the same priority value.
211fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        final int count = dashboardCategory.tiles.size();
212fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        for (int i = 0; i < count; i++) {
213fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            final String packageName =
214fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                    dashboardCategory.tiles.get(i).intent.getComponent().getPackageName();
215fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            if (TextUtils.equals(packageName, skipPackageName)) {
216fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                // We skip this tile because it's a intent pointing to our own app. We trust the
217fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                // priority is set correctly, so don't normalize.
218fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang                continue;
219fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            }
220fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang            dashboardCategory.tiles.get(i).priority = i;
221fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang
222fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang        }
223fc76ab3cbf1794d2d72a92c87afc1cf9f62cc03aFan Zhang    }
22422a56d775d047a1926f2a6d9c855c802d561d487Fan Zhang}
225