1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settingslib.drawer; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.util.Pair; 23 24 import com.android.settingslib.SettingLibRobolectricTestRunner; 25 import com.android.settingslib.TestConfig; 26 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.robolectric.annotation.Config; 31 import org.robolectric.shadows.ShadowApplication; 32 33 import java.util.HashMap; 34 import java.util.Map; 35 36 import static com.google.common.truth.Truth.assertThat; 37 38 @RunWith(SettingLibRobolectricTestRunner.class) 39 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 40 public class CategoryManagerTest { 41 42 private Context mContext; 43 private CategoryManager mCategoryManager; 44 private Map<Pair<String, String>, Tile> mTileByComponentCache; 45 private Map<String, DashboardCategory> mCategoryByKeyMap; 46 47 @Before 48 public void setUp() { 49 mContext = ShadowApplication.getInstance().getApplicationContext(); 50 mTileByComponentCache = new HashMap<>(); 51 mCategoryByKeyMap = new HashMap<>(); 52 mCategoryManager = CategoryManager.get(mContext); 53 } 54 55 @Test 56 public void getInstance_shouldBeSingleton() { 57 assertThat(mCategoryManager).isSameAs(CategoryManager.get(mContext)); 58 } 59 60 @Test 61 public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() { 62 final Tile tile1 = new Tile(); 63 final Tile tile2 = new Tile(); 64 tile1.category = CategoryKey.CATEGORY_ACCOUNT; 65 tile2.category = CategoryKey.CATEGORY_ACCOUNT; 66 final DashboardCategory category = new DashboardCategory(); 67 category.addTile(tile1); 68 category.addTile(tile2); 69 mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category); 70 mTileByComponentCache.put(new Pair<>("PACKAGE", "1"), tile1); 71 mTileByComponentCache.put(new Pair<>("PACKAGE", "2"), tile2); 72 73 mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap); 74 75 assertThat(mCategoryByKeyMap.size()).isEqualTo(1); 76 assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT)).isNotNull(); 77 } 78 79 @Test 80 public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() { 81 final Tile tile1 = new Tile(); 82 final Tile tile2 = new Tile(); 83 final String oldCategory = "com.android.settings.category.wireless"; 84 tile1.category = CategoryKey.CATEGORY_ACCOUNT; 85 tile2.category = oldCategory; 86 final DashboardCategory category1 = new DashboardCategory(); 87 category1.addTile(tile1); 88 final DashboardCategory category2 = new DashboardCategory(); 89 category2.addTile(tile2); 90 mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1); 91 mCategoryByKeyMap.put(oldCategory, category2); 92 mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1); 93 mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS2"), tile2); 94 95 mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap); 96 97 assertThat(mCategoryByKeyMap.size()).isEqualTo(2); 98 assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT).tiles.size()).isEqualTo(1); 99 assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1); 100 } 101 102 @Test 103 public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() { 104 final Tile tile1 = new Tile(); 105 final String oldCategory = "com.android.settings.category.wireless"; 106 tile1.category = oldCategory; 107 final DashboardCategory category1 = new DashboardCategory(); 108 category1.addTile(tile1); 109 mCategoryByKeyMap.put(oldCategory, category1); 110 mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1); 111 112 mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap); 113 114 // Added 1 more category to category map. 115 assertThat(mCategoryByKeyMap.size()).isEqualTo(2); 116 // The new category map has CATEGORY_NETWORK type now, which contains 1 tile. 117 assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_NETWORK).tiles.size()).isEqualTo(1); 118 // Old category still exists. 119 assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1); 120 } 121 122 @Test 123 public void sortCategories_singlePackage_shouldReorderBasedOnPriority() { 124 // Create some fake tiles that are not sorted. 125 final String testPackage = "com.android.test"; 126 final DashboardCategory category = new DashboardCategory(); 127 final Tile tile1 = new Tile(); 128 tile1.intent = 129 new Intent().setComponent(new ComponentName(testPackage, "class1")); 130 tile1.priority = 100; 131 final Tile tile2 = new Tile(); 132 tile2.intent = 133 new Intent().setComponent(new ComponentName(testPackage, "class2")); 134 tile2.priority = 50; 135 final Tile tile3 = new Tile(); 136 tile3.intent = 137 new Intent().setComponent(new ComponentName(testPackage, "class3")); 138 tile3.priority = 200; 139 category.tiles.add(tile1); 140 category.tiles.add(tile2); 141 category.tiles.add(tile3); 142 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 143 144 // Sort their priorities 145 mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(), 146 mCategoryByKeyMap); 147 148 // Verify they are now sorted. 149 assertThat(category.tiles.get(0)).isSameAs(tile3); 150 assertThat(category.tiles.get(1)).isSameAs(tile1); 151 assertThat(category.tiles.get(2)).isSameAs(tile2); 152 } 153 154 @Test 155 public void sortCategories_multiPackage_shouldReorderBasedOnPackageAndPriority() { 156 // Create some fake tiles that are not sorted. 157 final String testPackage1 = "com.android.test1"; 158 final String testPackage2 = "com.android.test2"; 159 final DashboardCategory category = new DashboardCategory(); 160 final Tile tile1 = new Tile(); 161 tile1.intent = 162 new Intent().setComponent(new ComponentName(testPackage2, "class1")); 163 tile1.priority = 100; 164 final Tile tile2 = new Tile(); 165 tile2.intent = 166 new Intent().setComponent(new ComponentName(testPackage1, "class2")); 167 tile2.priority = 100; 168 final Tile tile3 = new Tile(); 169 tile3.intent = 170 new Intent().setComponent(new ComponentName(testPackage1, "class3")); 171 tile3.priority = 50; 172 category.tiles.add(tile1); 173 category.tiles.add(tile2); 174 category.tiles.add(tile3); 175 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 176 177 // Sort their priorities 178 mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(), 179 mCategoryByKeyMap); 180 181 // Verify they are now sorted. 182 assertThat(category.tiles.get(0)).isSameAs(tile2); 183 assertThat(category.tiles.get(1)).isSameAs(tile1); 184 assertThat(category.tiles.get(2)).isSameAs(tile3); 185 } 186 187 @Test 188 public void sortCategories_internalPackageTiles_shouldSkipTileForInternalPackage() { 189 // Create some fake tiles that are not sorted. 190 final String testPackage = 191 ShadowApplication.getInstance().getApplicationContext().getPackageName(); 192 final DashboardCategory category = new DashboardCategory(); 193 final Tile tile1 = new Tile(); 194 tile1.intent = 195 new Intent().setComponent(new ComponentName(testPackage, "class1")); 196 tile1.priority = 100; 197 final Tile tile2 = new Tile(); 198 tile2.intent = 199 new Intent().setComponent(new ComponentName(testPackage, "class2")); 200 tile2.priority = 100; 201 final Tile tile3 = new Tile(); 202 tile3.intent = 203 new Intent().setComponent(new ComponentName(testPackage, "class3")); 204 tile3.priority = 50; 205 category.tiles.add(tile1); 206 category.tiles.add(tile2); 207 category.tiles.add(tile3); 208 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 209 210 // Sort their priorities 211 mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(), 212 mCategoryByKeyMap); 213 214 // Verify the sorting order is not changed 215 assertThat(category.tiles.get(0)).isSameAs(tile1); 216 assertThat(category.tiles.get(1)).isSameAs(tile2); 217 assertThat(category.tiles.get(2)).isSameAs(tile3); 218 } 219 220 @Test 221 public void sortCategories_internalAndExternalPackageTiles_shouldRetainPriorityOrdering() { 222 // Inject one external tile among internal tiles. 223 final String testPackage = 224 ShadowApplication.getInstance().getApplicationContext().getPackageName(); 225 final String testPackage2 = "com.google.test2"; 226 final DashboardCategory category = new DashboardCategory(); 227 final Tile tile1 = new Tile(); 228 tile1.intent = new Intent().setComponent(new ComponentName(testPackage, "class1")); 229 tile1.priority = 2; 230 final Tile tile2 = new Tile(); 231 tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2")); 232 tile2.priority = 1; 233 final Tile tile3 = new Tile(); 234 tile3.intent = new Intent().setComponent(new ComponentName(testPackage2, "class0")); 235 tile3.priority = 0; 236 final Tile tile4 = new Tile(); 237 tile4.intent = new Intent().setComponent(new ComponentName(testPackage, "class3")); 238 tile4.priority = -1; 239 category.tiles.add(tile1); 240 category.tiles.add(tile2); 241 category.tiles.add(tile3); 242 category.tiles.add(tile4); 243 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 244 245 // Sort their priorities 246 mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(), 247 mCategoryByKeyMap); 248 249 // Verify the sorting order is not changed 250 assertThat(category.tiles.get(0)).isSameAs(tile1); 251 assertThat(category.tiles.get(1)).isSameAs(tile2); 252 assertThat(category.tiles.get(2)).isSameAs(tile3); 253 assertThat(category.tiles.get(3)).isSameAs(tile4); 254 } 255 256 @Test 257 public void sortCategories_samePriority_internalPackageTileShouldTakePrecedence() { 258 // Inject one external tile among internal tiles with same priority. 259 final String testPackage = 260 ShadowApplication.getInstance().getApplicationContext().getPackageName(); 261 final String testPackage2 = "com.google.test2"; 262 final String testPackage3 = "com.abcde.test3"; 263 final DashboardCategory category = new DashboardCategory(); 264 final Tile tile1 = new Tile(); 265 tile1.intent = new Intent().setComponent(new ComponentName(testPackage2, "class1")); 266 tile1.priority = 1; 267 final Tile tile2 = new Tile(); 268 tile2.intent = new Intent().setComponent(new ComponentName(testPackage, "class2")); 269 tile2.priority = 1; 270 final Tile tile3 = new Tile(); 271 tile3.intent = new Intent().setComponent(new ComponentName(testPackage3, "class3")); 272 tile3.priority = 1; 273 category.tiles.add(tile1); 274 category.tiles.add(tile2); 275 category.tiles.add(tile3); 276 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 277 278 // Sort their priorities 279 mCategoryManager.sortCategories(ShadowApplication.getInstance().getApplicationContext(), 280 mCategoryByKeyMap); 281 282 // Verify the sorting order is internal first, follow by package name ordering 283 assertThat(category.tiles.get(0)).isSameAs(tile2); 284 assertThat(category.tiles.get(1)).isSameAs(tile3); 285 assertThat(category.tiles.get(2)).isSameAs(tile1); 286 } 287 288 @Test 289 public void filterTiles_noDuplicate_noChange() { 290 // Create some unique tiles 291 final String testPackage = 292 ShadowApplication.getInstance().getApplicationContext().getPackageName(); 293 final DashboardCategory category = new DashboardCategory(); 294 final Tile tile1 = new Tile(); 295 tile1.intent = 296 new Intent().setComponent(new ComponentName(testPackage, "class1")); 297 tile1.priority = 100; 298 final Tile tile2 = new Tile(); 299 tile2.intent = 300 new Intent().setComponent(new ComponentName(testPackage, "class2")); 301 tile2.priority = 100; 302 final Tile tile3 = new Tile(); 303 tile3.intent = 304 new Intent().setComponent(new ComponentName(testPackage, "class3")); 305 tile3.priority = 50; 306 category.tiles.add(tile1); 307 category.tiles.add(tile2); 308 category.tiles.add(tile3); 309 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 310 311 mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap); 312 313 assertThat(category.tiles.size()).isEqualTo(3); 314 } 315 316 @Test 317 public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() { 318 // Create tiles pointing to same intent. 319 final String testPackage = 320 ShadowApplication.getInstance().getApplicationContext().getPackageName(); 321 final DashboardCategory category = new DashboardCategory(); 322 final Tile tile1 = new Tile(); 323 tile1.intent = 324 new Intent().setComponent(new ComponentName(testPackage, "class1")); 325 tile1.priority = 100; 326 final Tile tile2 = new Tile(); 327 tile2.intent = 328 new Intent().setComponent(new ComponentName(testPackage, "class1")); 329 tile2.priority = 100; 330 final Tile tile3 = new Tile(); 331 tile3.intent = 332 new Intent().setComponent(new ComponentName(testPackage, "class1")); 333 tile3.priority = 50; 334 category.tiles.add(tile1); 335 category.tiles.add(tile2); 336 category.tiles.add(tile3); 337 mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category); 338 339 mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap); 340 341 assertThat(category.tiles.size()).isEqualTo(1); 342 } 343 } 344