Backward-compat for DashboardCategory with app use old keys

- Detect whether an app is using old key, new key, or a mix of both.
-- If app is using new keys, skip. They are already in the new IA.
-- If app is using old/new keys mixed, skip. Using both type of keys
   implies the app wants to support old/new platform.
-- If app is using old keys only, map their tiles to new categories.

Bug: 32382487
Test: new unit tests
Change-Id: I3bbd09c531a97801dc382661a8bb10d0391bc177
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index c1f5660..b27aad9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -15,6 +15,9 @@
  */
 package com.android.settingslib.drawer;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public final class CategoryKey {
 
     // Activities in this category shows up in Settings homepage.
@@ -33,4 +36,14 @@
     public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security";
     public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts";
     public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system";
+
+    public static final Map<String, String> KEY_COMPAT_MAP;
+
+    static {
+        KEY_COMPAT_MAP = new HashMap<>();
+        KEY_COMPAT_MAP.put("com.android.settings.category.wireless", CATEGORY_NETWORK);
+        KEY_COMPAT_MAP.put("com.android.settings.category.device", CATEGORY_SYSTEM);
+        KEY_COMPAT_MAP.put("com.android.settings.category.personal", CATEGORY_SYSTEM);
+        KEY_COMPAT_MAP.put("com.android.settings.category.system", CATEGORY_SYSTEM);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index a51ad76..0313089 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -23,8 +23,11 @@
 
 import com.android.settingslib.applications.InterestingConfigChanges;
 
+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 {
@@ -106,7 +109,50 @@
             for (DashboardCategory category : mCategories) {
                 mCategoryByKeyMap.put(category.key, category);
             }
+            backwardCompatCleanupForCategory();
         }
     }
 
+    private synchronized void backwardCompatCleanupForCategory() {
+        // 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 : mTileByComponentCache.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.
+                    final DashboardCategory newCategory = mCategoryByKeyMap.get(newCategoryKey);
+                    newCategory.tiles.add(tile);
+                }
+            }
+        }
+    }
 }