1/* 2 * Copyright (C) 2012 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 17package com.android.server.pm; 18 19import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 23 24import static org.hamcrest.CoreMatchers.is; 25import static org.hamcrest.CoreMatchers.not; 26import static org.hamcrest.CoreMatchers.notNullValue; 27import static org.hamcrest.CoreMatchers.nullValue; 28import static org.junit.Assert.assertEquals; 29import static org.junit.Assert.assertNotSame; 30import static org.junit.Assert.assertNull; 31import static org.junit.Assert.assertSame; 32import static org.junit.Assert.assertThat; 33import static org.junit.Assert.assertTrue; 34import static org.junit.Assert.fail; 35 36import android.annotation.NonNull; 37import android.content.pm.ApplicationInfo; 38import android.content.pm.PackageParser; 39import android.content.pm.PackageUserState; 40import android.content.pm.UserInfo; 41import android.os.UserHandle; 42import android.os.UserManagerInternal; 43import android.security.keystore.ArrayUtils; 44import android.support.test.InstrumentationRegistry; 45import android.support.test.runner.AndroidJUnit4; 46import android.test.suitebuilder.annotation.SmallTest; 47import android.util.ArrayMap; 48import android.util.ArraySet; 49import android.util.Log; 50import android.util.LongSparseArray; 51 52import com.android.internal.os.AtomicFile; 53import com.android.server.LocalServices; 54 55import org.junit.Before; 56import org.junit.Test; 57import org.junit.runner.RunWith; 58 59import java.io.File; 60import java.io.FileOutputStream; 61import java.io.IOException; 62import java.security.PublicKey; 63import java.util.ArrayList; 64import java.util.Arrays; 65import java.util.List; 66 67@RunWith(AndroidJUnit4.class) 68@SmallTest 69public class PackageManagerSettingsTests { 70 private static final String PACKAGE_NAME_2 = "com.google.app2"; 71 private static final String PACKAGE_NAME_3 = "com.android.app3"; 72 private static final String PACKAGE_NAME_1 = "com.google.app1"; 73 public static final String TAG = "PackageManagerSettingsTests"; 74 protected final String PREFIX = "android.content.pm"; 75 76 /** make sure our initialized KeySetManagerService metadata matches packages.xml */ 77 @Test 78 public void testReadKeySetSettings() 79 throws ReflectiveOperationException, IllegalAccessException { 80 /* write out files and read */ 81 writeOldFiles(); 82 Settings settings = 83 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 84 assertThat(settings.readLPw(createFakeUsers()), is(true)); 85 verifyKeySetMetaData(settings); 86 } 87 88 /** read in data, write it out, and read it back in. Verify same. */ 89 @Test 90 public void testWriteKeySetSettings() 91 throws ReflectiveOperationException, IllegalAccessException { 92 // write out files and read 93 writeOldFiles(); 94 Settings settings = 95 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 96 assertThat(settings.readLPw(createFakeUsers()), is(true)); 97 98 // write out, read back in and verify the same 99 settings.writeLPr(); 100 assertThat(settings.readLPw(createFakeUsers()), is(true)); 101 verifyKeySetMetaData(settings); 102 } 103 104 @Test 105 public void testSettingsReadOld() { 106 // Write the package files and make sure they're parsed properly the first time 107 writeOldFiles(); 108 Settings settings = 109 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 110 assertThat(settings.readLPw(createFakeUsers()), is(true)); 111 assertThat(settings.getPackageLPr(PACKAGE_NAME_3), is(notNullValue())); 112 assertThat(settings.getPackageLPr(PACKAGE_NAME_1), is(notNullValue())); 113 114 PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_1); 115 assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DEFAULT)); 116 assertThat(ps.getNotLaunched(0), is(true)); 117 118 ps = settings.getPackageLPr(PACKAGE_NAME_2); 119 assertThat(ps.getStopped(0), is(false)); 120 assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER)); 121 assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT)); 122 } 123 124 @Test 125 public void testNewPackageRestrictionsFile() throws ReflectiveOperationException { 126 // Write the package files and make sure they're parsed properly the first time 127 writeOldFiles(); 128 Settings settings = 129 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 130 assertThat(settings.readLPw(createFakeUsers()), is(true)); 131 settings.writeLPr(); 132 133 // Create Settings again to make it read from the new files 134 settings = new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 135 assertThat(settings.readLPw(createFakeUsers()), is(true)); 136 137 PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_2); 138 assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER)); 139 assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT)); 140 } 141 142 @Test 143 public void testEnableDisable() { 144 // Write the package files and make sure they're parsed properly the first time 145 writeOldFiles(); 146 Settings settings = 147 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 148 assertThat(settings.readLPw(createFakeUsers()), is(true)); 149 150 // Enable/Disable a package 151 PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_1); 152 ps.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null); 153 ps.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 1, null); 154 assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED)); 155 assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_ENABLED)); 156 157 // Enable/Disable a component 158 ArraySet<String> components = new ArraySet<String>(); 159 String component1 = PACKAGE_NAME_1 + "/.Component1"; 160 components.add(component1); 161 ps.setDisabledComponents(components, 0); 162 ArraySet<String> componentsDisabled = ps.getDisabledComponents(0); 163 assertThat(componentsDisabled.size(), is(1)); 164 assertThat(componentsDisabled.toArray()[0], is(component1)); 165 boolean hasEnabled = 166 ps.getEnabledComponents(0) != null && ps.getEnabledComponents(1).size() > 0; 167 assertThat(hasEnabled, is(false)); 168 169 // User 1 should not have any disabled components 170 boolean hasDisabled = 171 ps.getDisabledComponents(1) != null && ps.getDisabledComponents(1).size() > 0; 172 assertThat(hasDisabled, is(false)); 173 ps.setEnabledComponents(components, 1); 174 assertThat(ps.getEnabledComponents(1).size(), is(1)); 175 hasEnabled = ps.getEnabledComponents(0) != null && ps.getEnabledComponents(0).size() > 0; 176 assertThat(hasEnabled, is(false)); 177 } 178 179 private static final String PACKAGE_NAME = "com.android.bar"; 180 private static final String REAL_PACKAGE_NAME = "com.android.foo"; 181 private static final String PARENT_PACKAGE_NAME = "com.android.bar.parent"; 182 private static final String CHILD_PACKAGE_NAME_01 = "com.android.bar.child01"; 183 private static final String CHILD_PACKAGE_NAME_02 = "com.android.bar.child02"; 184 private static final String CHILD_PACKAGE_NAME_03 = "com.android.bar.child03"; 185 private static final File INITIAL_CODE_PATH = 186 new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-1"); 187 private static final File UPDATED_CODE_PATH = 188 new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-2"); 189 private static final int INITIAL_VERSION_CODE = 10023; 190 private static final int UPDATED_VERSION_CODE = 10025; 191 192 @Test 193 public void testPackageStateCopy01() { 194 final List<String> childPackageNames = new ArrayList<>(); 195 childPackageNames.add(CHILD_PACKAGE_NAME_01); 196 childPackageNames.add(CHILD_PACKAGE_NAME_02); 197 childPackageNames.add(CHILD_PACKAGE_NAME_03); 198 final PackageSetting origPkgSetting01 = new PackageSetting( 199 PACKAGE_NAME, 200 REAL_PACKAGE_NAME, 201 INITIAL_CODE_PATH /*codePath*/, 202 INITIAL_CODE_PATH /*resourcePath*/, 203 null /*legacyNativeLibraryPathString*/, 204 "x86_64" /*primaryCpuAbiString*/, 205 "x86" /*secondaryCpuAbiString*/, 206 null /*cpuAbiOverrideString*/, 207 INITIAL_VERSION_CODE, 208 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, 209 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, 210 PARENT_PACKAGE_NAME, 211 childPackageNames, 212 0, 213 null /*usesStaticLibraries*/, 214 null /*usesStaticLibrariesVersions*/); 215 final PackageSetting testPkgSetting01 = new PackageSetting(origPkgSetting01); 216 verifySettingCopy(origPkgSetting01, testPkgSetting01); 217 } 218 219 @Test 220 public void testPackageStateCopy02() { 221 final List<String> childPackageNames = new ArrayList<>(); 222 childPackageNames.add(CHILD_PACKAGE_NAME_01); 223 childPackageNames.add(CHILD_PACKAGE_NAME_02); 224 childPackageNames.add(CHILD_PACKAGE_NAME_03); 225 final PackageSetting origPkgSetting01 = new PackageSetting( 226 PACKAGE_NAME /*pkgName*/, 227 REAL_PACKAGE_NAME /*realPkgName*/, 228 INITIAL_CODE_PATH /*codePath*/, 229 INITIAL_CODE_PATH /*resourcePath*/, 230 null /*legacyNativeLibraryPathString*/, 231 "x86_64" /*primaryCpuAbiString*/, 232 "x86" /*secondaryCpuAbiString*/, 233 null /*cpuAbiOverrideString*/, 234 INITIAL_VERSION_CODE, 235 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, 236 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, 237 PARENT_PACKAGE_NAME, 238 childPackageNames, 239 0, 240 null /*usesStaticLibraries*/, 241 null /*usesStaticLibrariesVersions*/); 242 final PackageSetting testPkgSetting01 = new PackageSetting( 243 PACKAGE_NAME /*pkgName*/, 244 REAL_PACKAGE_NAME /*realPkgName*/, 245 UPDATED_CODE_PATH /*codePath*/, 246 UPDATED_CODE_PATH /*resourcePath*/, 247 null /*legacyNativeLibraryPathString*/, 248 null /*primaryCpuAbiString*/, 249 null /*secondaryCpuAbiString*/, 250 null /*cpuAbiOverrideString*/, 251 UPDATED_VERSION_CODE, 252 0 /*pkgFlags*/, 253 0 /*pkgPrivateFlags*/, 254 null /*parentPkgName*/, 255 null /*childPkgNames*/, 256 0, 257 null /*usesStaticLibraries*/, 258 null /*usesStaticLibrariesVersions*/); 259 testPkgSetting01.copyFrom(origPkgSetting01); 260 verifySettingCopy(origPkgSetting01, testPkgSetting01); 261 } 262 263 /** Update package */ 264 @Test 265 public void testUpdatePackageSetting01() throws PackageManagerException { 266 final PackageSetting testPkgSetting01 = 267 createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 268 testPkgSetting01.setInstalled(false /*installed*/, 0 /*userId*/); 269 assertThat(testPkgSetting01.pkgFlags, is(0)); 270 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 271 final PackageSetting oldPkgSetting01 = new PackageSetting(testPkgSetting01); 272 Settings.updatePackageSetting( 273 testPkgSetting01, 274 null /*disabledPkg*/, 275 null /*sharedUser*/, 276 UPDATED_CODE_PATH /*codePath*/, 277 null /*legacyNativeLibraryPath*/, 278 "arm64-v8a" /*primaryCpuAbi*/, 279 "armeabi" /*secondaryCpuAbi*/, 280 0 /*pkgFlags*/, 281 0 /*pkgPrivateFlags*/, 282 null /*childPkgNames*/, 283 UserManagerService.getInstance(), 284 null /*usesStaticLibraries*/, 285 null /*usesStaticLibrariesVersions*/); 286 assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a")); 287 assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi")); 288 assertThat(testPkgSetting01.origPackage, is(nullValue())); 289 assertThat(testPkgSetting01.pkgFlags, is(0)); 290 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 291 final PackageUserState userState = testPkgSetting01.readUserState(0); 292 final PackageUserState oldUserState = oldPkgSetting01.readUserState(0); 293 verifyUserState(userState, oldUserState, false /*userStateChanged*/, false /*notLaunched*/, 294 false /*stopped*/, false /*installed*/); 295 } 296 297 /** Update package; package now on /system, install for user '0' */ 298 @Test 299 public void testUpdatePackageSetting02() throws PackageManagerException { 300 final PackageSetting testPkgSetting01 = 301 createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 302 testPkgSetting01.setInstalled(false /*installed*/, 0 /*userId*/); 303 assertThat(testPkgSetting01.pkgFlags, is(0)); 304 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 305 final PackageSetting oldPkgSetting01 = new PackageSetting(testPkgSetting01); 306 Settings.updatePackageSetting( 307 testPkgSetting01, 308 null /*disabledPkg*/, 309 null /*sharedUser*/, 310 UPDATED_CODE_PATH /*codePath*/, 311 null /*legacyNativeLibraryPath*/, 312 "arm64-v8a" /*primaryCpuAbi*/, 313 "armeabi" /*secondaryCpuAbi*/, 314 ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/, 315 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/, 316 null /*childPkgNames*/, 317 UserManagerService.getInstance(), 318 null /*usesStaticLibraries*/, 319 null /*usesStaticLibrariesVersions*/); 320 assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a")); 321 assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi")); 322 assertThat(testPkgSetting01.origPackage, is(nullValue())); 323 assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM)); 324 assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)); 325 final PackageUserState userState = testPkgSetting01.readUserState(0); 326 final PackageUserState oldUserState = oldPkgSetting01.readUserState(0); 327 // WARNING: When creating a shallow copy of the PackageSetting we do NOT create 328 // new contained objects. For example, this means that changes to the user state 329 // in testPkgSetting01 will also change the user state in its copy. 330 verifyUserState(userState, oldUserState, false /*userStateChanged*/, false /*notLaunched*/, 331 false /*stopped*/, true /*installed*/); 332 } 333 334 /** Update package; changing shared user throws exception */ 335 @Test 336 public void testUpdatePackageSetting03() { 337 final Settings testSettings01 = new Settings(new Object() /*lock*/); 338 final SharedUserSetting testUserSetting01 = createSharedUserSetting( 339 testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); 340 final PackageSetting testPkgSetting01 = 341 createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 342 try { 343 Settings.updatePackageSetting( 344 testPkgSetting01, 345 null /*disabledPkg*/, 346 testUserSetting01 /*sharedUser*/, 347 UPDATED_CODE_PATH /*codePath*/, 348 null /*legacyNativeLibraryPath*/, 349 "arm64-v8a" /*primaryCpuAbi*/, 350 "armeabi" /*secondaryCpuAbi*/, 351 0 /*pkgFlags*/, 352 0 /*pkgPrivateFlags*/, 353 null /*childPkgNames*/, 354 UserManagerService.getInstance(), 355 null /*usesStaticLibraries*/, 356 null /*usesStaticLibrariesVersions*/); 357 fail("Expected a PackageManagerException"); 358 } catch (PackageManagerException expected) { 359 } 360 } 361 362 /** Create a new PackageSetting based on an original package setting */ 363 @Test 364 public void testCreateNewSetting01() { 365 final PackageSetting originalPkgSetting01 = 366 createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 367 final PackageSignatures originalSignatures = originalPkgSetting01.signatures; 368 final PackageSetting testPkgSetting01 = Settings.createNewSetting( 369 REAL_PACKAGE_NAME, 370 originalPkgSetting01 /*originalPkg*/, 371 null /*disabledPkg*/, 372 null /*realPkgName*/, 373 null /*sharedUser*/, 374 UPDATED_CODE_PATH /*codePath*/, 375 UPDATED_CODE_PATH /*resourcePath*/, 376 null /*legacyNativeLibraryPath*/, 377 "arm64-v8a" /*primaryCpuAbi*/, 378 "armeabi" /*secondaryCpuAbi*/, 379 UPDATED_VERSION_CODE /*versionCode*/, 380 ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/, 381 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/, 382 null /*installUser*/, 383 false /*allowInstall*/, 384 false /*instantApp*/, 385 null /*parentPkgName*/, 386 null /*childPkgNames*/, 387 UserManagerService.getInstance(), 388 null /*usesStaticLibraries*/, 389 null /*usesStaticLibrariesVersions*/); 390 assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH)); 391 assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); 392 assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM)); 393 assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)); 394 assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a")); 395 assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH)); 396 assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi")); 397 assertSame(testPkgSetting01.origPackage, originalPkgSetting01); 398 // signatures object must be different 399 assertNotSame(testPkgSetting01.signatures, originalSignatures); 400 assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE)); 401 final PackageUserState userState = testPkgSetting01.readUserState(0); 402 verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/, 403 false /*notLaunched*/, false /*stopped*/, true /*installed*/); 404 } 405 406 /** Create a new non-system PackageSetting */ 407 @Test 408 public void testCreateNewSetting02() { 409 final PackageSetting testPkgSetting01 = Settings.createNewSetting( 410 PACKAGE_NAME, 411 null /*originalPkg*/, 412 null /*disabledPkg*/, 413 null /*realPkgName*/, 414 null /*sharedUser*/, 415 INITIAL_CODE_PATH /*codePath*/, 416 INITIAL_CODE_PATH /*resourcePath*/, 417 null /*legacyNativeLibraryPath*/, 418 "x86_64" /*primaryCpuAbiString*/, 419 "x86" /*secondaryCpuAbiString*/, 420 INITIAL_VERSION_CODE /*versionCode*/, 421 0 /*pkgFlags*/, 422 0 /*pkgPrivateFlags*/, 423 UserHandle.SYSTEM /*installUser*/, 424 true /*allowInstall*/, 425 false /*instantApp*/, 426 null /*parentPkgName*/, 427 null /*childPkgNames*/, 428 UserManagerService.getInstance(), 429 null /*usesStaticLibraries*/, 430 null /*usesStaticLibrariesVersions*/); 431 assertThat(testPkgSetting01.appId, is(0)); 432 assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH)); 433 assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); 434 assertThat(testPkgSetting01.origPackage, is(nullValue())); 435 assertThat(testPkgSetting01.pkgFlags, is(0)); 436 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 437 assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64")); 438 assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH)); 439 assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86")); 440 assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE)); 441 // by default, the package is considered stopped 442 final PackageUserState userState = testPkgSetting01.readUserState(0); 443 verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/, 444 true /*notLaunched*/, true /*stopped*/, true /*installed*/); 445 } 446 447 /** Create PackageSetting for a shared user */ 448 @Test 449 public void testCreateNewSetting03() { 450 final Settings testSettings01 = new Settings(new Object() /*lock*/); 451 final SharedUserSetting testUserSetting01 = createSharedUserSetting( 452 testSettings01, "TestUser", 10064, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/); 453 final PackageSetting testPkgSetting01 = Settings.createNewSetting( 454 PACKAGE_NAME, 455 null /*originalPkg*/, 456 null /*disabledPkg*/, 457 null /*realPkgName*/, 458 testUserSetting01 /*sharedUser*/, 459 INITIAL_CODE_PATH /*codePath*/, 460 INITIAL_CODE_PATH /*resourcePath*/, 461 null /*legacyNativeLibraryPath*/, 462 "x86_64" /*primaryCpuAbiString*/, 463 "x86" /*secondaryCpuAbiString*/, 464 INITIAL_VERSION_CODE /*versionCode*/, 465 0 /*pkgFlags*/, 466 0 /*pkgPrivateFlags*/, 467 null /*installUser*/, 468 false /*allowInstall*/, 469 false /*instantApp*/, 470 null /*parentPkgName*/, 471 null /*childPkgNames*/, 472 UserManagerService.getInstance(), 473 null /*usesStaticLibraries*/, 474 null /*usesStaticLibrariesVersions*/); 475 assertThat(testPkgSetting01.appId, is(10064)); 476 assertThat(testPkgSetting01.codePath, is(INITIAL_CODE_PATH)); 477 assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); 478 assertThat(testPkgSetting01.origPackage, is(nullValue())); 479 assertThat(testPkgSetting01.pkgFlags, is(0)); 480 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 481 assertThat(testPkgSetting01.primaryCpuAbiString, is("x86_64")); 482 assertThat(testPkgSetting01.resourcePath, is(INITIAL_CODE_PATH)); 483 assertThat(testPkgSetting01.secondaryCpuAbiString, is("x86")); 484 assertThat(testPkgSetting01.versionCode, is(INITIAL_VERSION_CODE)); 485 final PackageUserState userState = testPkgSetting01.readUserState(0); 486 verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/, 487 false /*notLaunched*/, false /*stopped*/, true /*installed*/); 488 } 489 490 /** Create a new PackageSetting based on a disabled package setting */ 491 @Test 492 public void testCreateNewSetting04() { 493 final PackageSetting disabledPkgSetting01 = 494 createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 495 disabledPkgSetting01.appId = 10064; 496 final PackageSignatures disabledSignatures = disabledPkgSetting01.signatures; 497 final PackageSetting testPkgSetting01 = Settings.createNewSetting( 498 PACKAGE_NAME, 499 null /*originalPkg*/, 500 disabledPkgSetting01 /*disabledPkg*/, 501 null /*realPkgName*/, 502 null /*sharedUser*/, 503 UPDATED_CODE_PATH /*codePath*/, 504 UPDATED_CODE_PATH /*resourcePath*/, 505 null /*legacyNativeLibraryPath*/, 506 "arm64-v8a" /*primaryCpuAbi*/, 507 "armeabi" /*secondaryCpuAbi*/, 508 UPDATED_VERSION_CODE /*versionCode*/, 509 0 /*pkgFlags*/, 510 0 /*pkgPrivateFlags*/, 511 null /*installUser*/, 512 false /*allowInstall*/, 513 false /*instantApp*/, 514 null /*parentPkgName*/, 515 null /*childPkgNames*/, 516 UserManagerService.getInstance(), 517 null /*usesStaticLibraries*/, 518 null /*usesStaticLibrariesVersions*/); 519 assertThat(testPkgSetting01.appId, is(10064)); 520 assertThat(testPkgSetting01.codePath, is(UPDATED_CODE_PATH)); 521 assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); 522 assertThat(testPkgSetting01.origPackage, is(nullValue())); 523 assertThat(testPkgSetting01.pkgFlags, is(0)); 524 assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); 525 assertThat(testPkgSetting01.primaryCpuAbiString, is("arm64-v8a")); 526 assertThat(testPkgSetting01.resourcePath, is(UPDATED_CODE_PATH)); 527 assertThat(testPkgSetting01.secondaryCpuAbiString, is("armeabi")); 528 assertNotSame(testPkgSetting01.signatures, disabledSignatures); 529 assertThat(testPkgSetting01.versionCode, is(UPDATED_VERSION_CODE)); 530 final PackageUserState userState = testPkgSetting01.readUserState(0); 531 verifyUserState(userState, null /*oldUserState*/, false /*userStateChanged*/, 532 false /*notLaunched*/, false /*stopped*/, true /*installed*/); 533 } 534 535 @Test 536 public void testInsertPackageSetting() { 537 final PackageSetting ps = createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/); 538 final PackageParser.Package pkg = new PackageParser.Package(PACKAGE_NAME); 539 pkg.applicationInfo.setCodePath(ps.codePathString); 540 pkg.applicationInfo.setResourcePath(ps.resourcePathString); 541 final Settings settings = 542 new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object()); 543 pkg.usesStaticLibraries = new ArrayList<>( 544 Arrays.asList("foo.bar1", "foo.bar2", "foo.bar3")); 545 pkg.usesStaticLibrariesVersions = new int[] {2, 4, 6}; 546 settings.insertPackageSettingLPw(ps, pkg); 547 assertEquals(pkg, ps.pkg); 548 assertArrayEquals(pkg.usesStaticLibraries.toArray(new String[0]), ps.usesStaticLibraries); 549 assertArrayEquals(pkg.usesStaticLibrariesVersions, ps.usesStaticLibrariesVersions); 550 551 pkg.usesStaticLibraries = null; 552 pkg.usesStaticLibrariesVersions = null; 553 settings.insertPackageSettingLPw(ps, pkg); 554 assertEquals(pkg, ps.pkg); 555 assertNull("Actual: " + Arrays.toString(ps.usesStaticLibraries), ps.usesStaticLibraries); 556 assertNull("Actual: " + Arrays.toString(ps.usesStaticLibrariesVersions), 557 ps.usesStaticLibrariesVersions); 558 } 559 560 private <T> void assertArrayEquals(T[] a, T[] b) { 561 assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b), 562 Arrays.equals(a, b)); 563 } 564 565 private void assertArrayEquals(int[] a, int[] b) { 566 assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b), 567 Arrays.equals(a, b)); 568 } 569 570 private void verifyUserState(PackageUserState userState, PackageUserState oldUserState, 571 boolean userStateChanged) { 572 verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/, 573 false /*stopped*/, true /*installed*/); 574 } 575 576 private void verifyUserState(PackageUserState userState, PackageUserState oldUserState, 577 boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) { 578 assertThat(userState.enabled, is(0)); 579 assertThat(userState.hidden, is(false)); 580 assertThat(userState.installed, is(installed)); 581 assertThat(userState.notLaunched, is(notLaunched)); 582 assertThat(userState.stopped, is(stopped)); 583 assertThat(userState.suspended, is(false)); 584 if (oldUserState != null) { 585 assertThat(userState.equals(oldUserState), is(not(userStateChanged))); 586 } 587 } 588 589 private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) { 590 assertThat(origPkgSetting, is(not(testPkgSetting))); 591 assertThat(origPkgSetting.appId, is(testPkgSetting.appId)); 592 // different but equal objects 593 assertNotSame(origPkgSetting.childPackageNames, testPkgSetting.childPackageNames); 594 assertThat(origPkgSetting.childPackageNames, is(testPkgSetting.childPackageNames)); 595 assertSame(origPkgSetting.codePath, testPkgSetting.codePath); 596 assertThat(origPkgSetting.codePath, is(testPkgSetting.codePath)); 597 assertSame(origPkgSetting.codePathString, testPkgSetting.codePathString); 598 assertThat(origPkgSetting.codePathString, is(testPkgSetting.codePathString)); 599 assertSame(origPkgSetting.cpuAbiOverrideString, testPkgSetting.cpuAbiOverrideString); 600 assertThat(origPkgSetting.cpuAbiOverrideString, is(testPkgSetting.cpuAbiOverrideString)); 601 assertThat(origPkgSetting.firstInstallTime, is(testPkgSetting.firstInstallTime)); 602 assertSame(origPkgSetting.installerPackageName, testPkgSetting.installerPackageName); 603 assertThat(origPkgSetting.installerPackageName, is(testPkgSetting.installerPackageName)); 604 assertThat(origPkgSetting.installPermissionsFixed, 605 is(testPkgSetting.installPermissionsFixed)); 606 assertThat(origPkgSetting.installStatus, is(testPkgSetting.installStatus)); 607 assertThat(origPkgSetting.isOrphaned, is(testPkgSetting.isOrphaned)); 608 assertSame(origPkgSetting.keySetData, testPkgSetting.keySetData); 609 assertThat(origPkgSetting.keySetData, is(testPkgSetting.keySetData)); 610 assertThat(origPkgSetting.lastUpdateTime, is(testPkgSetting.lastUpdateTime)); 611 assertSame(origPkgSetting.legacyNativeLibraryPathString, 612 testPkgSetting.legacyNativeLibraryPathString); 613 assertThat(origPkgSetting.legacyNativeLibraryPathString, 614 is(testPkgSetting.legacyNativeLibraryPathString)); 615 assertNotSame(origPkgSetting.mPermissionsState, testPkgSetting.mPermissionsState); 616 assertThat(origPkgSetting.mPermissionsState, is(testPkgSetting.mPermissionsState)); 617 assertThat(origPkgSetting.name, is(testPkgSetting.name)); 618 // oldCodePaths is _not_ copied 619 // assertNotSame(origPkgSetting.oldCodePaths, testPkgSetting.oldCodePaths); 620 // assertThat(origPkgSetting.oldCodePaths, is(not(testPkgSetting.oldCodePaths))); 621 assertSame(origPkgSetting.origPackage, testPkgSetting.origPackage); 622 assertThat(origPkgSetting.origPackage, is(testPkgSetting.origPackage)); 623 assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName); 624 assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName)); 625 assertSame(origPkgSetting.pkg, testPkgSetting.pkg); 626 // No equals() method for this object 627 // assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg)); 628 assertThat(origPkgSetting.pkgFlags, is(testPkgSetting.pkgFlags)); 629 assertThat(origPkgSetting.pkgPrivateFlags, is(testPkgSetting.pkgPrivateFlags)); 630 assertSame(origPkgSetting.primaryCpuAbiString, testPkgSetting.primaryCpuAbiString); 631 assertThat(origPkgSetting.primaryCpuAbiString, is(testPkgSetting.primaryCpuAbiString)); 632 assertThat(origPkgSetting.realName, is(testPkgSetting.realName)); 633 assertSame(origPkgSetting.resourcePath, testPkgSetting.resourcePath); 634 assertThat(origPkgSetting.resourcePath, is(testPkgSetting.resourcePath)); 635 assertSame(origPkgSetting.resourcePathString, testPkgSetting.resourcePathString); 636 assertThat(origPkgSetting.resourcePathString, is(testPkgSetting.resourcePathString)); 637 assertSame(origPkgSetting.secondaryCpuAbiString, testPkgSetting.secondaryCpuAbiString); 638 assertThat(origPkgSetting.secondaryCpuAbiString, is(testPkgSetting.secondaryCpuAbiString)); 639 assertSame(origPkgSetting.sharedUser, testPkgSetting.sharedUser); 640 assertThat(origPkgSetting.sharedUser, is(testPkgSetting.sharedUser)); 641 assertSame(origPkgSetting.signatures, testPkgSetting.signatures); 642 assertThat(origPkgSetting.signatures, is(testPkgSetting.signatures)); 643 assertThat(origPkgSetting.timeStamp, is(testPkgSetting.timeStamp)); 644 assertThat(origPkgSetting.uidError, is(testPkgSetting.uidError)); 645 assertNotSame(origPkgSetting.getUserState(), is(testPkgSetting.getUserState())); 646 // No equals() method for SparseArray object 647 // assertThat(origPkgSetting.getUserState(), is(testPkgSetting.getUserState())); 648 assertSame(origPkgSetting.verificationInfo, testPkgSetting.verificationInfo); 649 assertThat(origPkgSetting.verificationInfo, is(testPkgSetting.verificationInfo)); 650 assertThat(origPkgSetting.versionCode, is(testPkgSetting.versionCode)); 651 assertSame(origPkgSetting.volumeUuid, testPkgSetting.volumeUuid); 652 assertThat(origPkgSetting.volumeUuid, is(testPkgSetting.volumeUuid)); 653 } 654 655 private SharedUserSetting createSharedUserSetting(Settings settings, String userName, 656 int sharedUserId, int pkgFlags, int pkgPrivateFlags) { 657 return settings.addSharedUserLPw( 658 userName, 659 sharedUserId, 660 pkgFlags, 661 pkgPrivateFlags); 662 } 663 private PackageSetting createPackageSetting(int sharedUserId, int pkgFlags) { 664 return new PackageSetting( 665 PACKAGE_NAME, 666 REAL_PACKAGE_NAME, 667 INITIAL_CODE_PATH /*codePath*/, 668 INITIAL_CODE_PATH /*resourcePath*/, 669 null /*legacyNativeLibraryPathString*/, 670 "x86_64" /*primaryCpuAbiString*/, 671 "x86" /*secondaryCpuAbiString*/, 672 null /*cpuAbiOverrideString*/, 673 INITIAL_VERSION_CODE, 674 pkgFlags, 675 0 /*privateFlags*/, 676 null /*parentPackageName*/, 677 null /*childPackageNames*/, 678 sharedUserId, 679 null /*usesStaticLibraries*/, 680 null /*usesStaticLibrariesVersions*/); 681 } 682 683 private @NonNull List<UserInfo> createFakeUsers() { 684 ArrayList<UserInfo> users = new ArrayList<>(); 685 users.add(new UserInfo(UserHandle.USER_SYSTEM, "test user", UserInfo.FLAG_INITIALIZED)); 686 return users; 687 } 688 689 private void writeFile(File file, byte[] data) { 690 file.mkdirs(); 691 try { 692 AtomicFile aFile = new AtomicFile(file); 693 FileOutputStream fos = aFile.startWrite(); 694 fos.write(data); 695 aFile.finishWrite(fos); 696 } catch (IOException ioe) { 697 Log.e(TAG, "Cannot write file " + file.getPath()); 698 } 699 } 700 701 private void writePackagesXml() { 702 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.xml"), 703 ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" 704 + "<packages>" 705 + "<last-platform-version internal=\"15\" external=\"0\" fingerprint=\"foo\" />" 706 + "<permission-trees>" 707 + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />" 708 + "</permission-trees>" 709 + "<permissions>" 710 + "<item name=\"android.permission.WRITE_CALL_LOG\" package=\"android\" protection=\"1\" />" 711 + "<item name=\"android.permission.ASEC_ACCESS\" package=\"android\" protection=\"2\" />" 712 + "<item name=\"android.permission.ACCESS_WIMAX_STATE\" package=\"android\" />" 713 + "<item name=\"android.permission.REBOOT\" package=\"android\" protection=\"18\" />" 714 + "</permissions>" 715 + "<package name=\"com.google.app1\" codePath=\"/system/app/app1.apk\" nativeLibraryPath=\"/data/data/com.google.app1/lib\" flags=\"1\" ft=\"1360e2caa70\" it=\"135f2f80d08\" ut=\"1360e2caa70\" version=\"1109\" sharedUserId=\"11000\">" 716 + "<sigs count=\"1\">" 717 + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />" 718 + "</sigs>" 719 + "<proper-signing-keyset identifier=\"1\" />" 720 + "</package>" 721 + "<package name=\"com.google.app2\" codePath=\"/system/app/app2.apk\" nativeLibraryPath=\"/data/data/com.google.app2/lib\" flags=\"1\" ft=\"1360e578718\" it=\"135f2f80d08\" ut=\"1360e578718\" version=\"15\" enabled=\"3\" userId=\"11001\">" 722 + "<sigs count=\"1\">" 723 + "<cert index=\"0\" />" 724 + "</sigs>" 725 + "<proper-signing-keyset identifier=\"1\" />" 726 + "<defined-keyset alias=\"AB\" identifier=\"4\" />" 727 + "</package>" 728 + "<package name=\"com.android.app3\" codePath=\"/system/app/app3.apk\" nativeLibraryPath=\"/data/data/com.android.app3/lib\" flags=\"1\" ft=\"1360e577b60\" it=\"135f2f80d08\" ut=\"1360e577b60\" version=\"15\" userId=\"11030\">" 729 + "<sigs count=\"1\">" 730 + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />" 731 + "</sigs>" 732 + "<proper-signing-keyset identifier=\"2\" />" 733 + "<upgrade-keyset identifier=\"3\" />" 734 + "<defined-keyset alias=\"C\" identifier=\"3\" />" 735 + "</package>" 736 + "<shared-user name=\"com.android.shared1\" userId=\"11000\">" 737 + "<sigs count=\"1\">" 738 + "<cert index=\"1\" />" 739 + "</sigs>" 740 + "<perms>" 741 + "<item name=\"android.permission.REBOOT\" />" 742 + "</perms>" 743 + "</shared-user>" 744 + "<keyset-settings version=\"1\">" 745 + "<keys>" 746 + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />" 747 + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />" 748 + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />" 749 + "</keys>" 750 + "<keysets>" 751 + "<keyset identifier=\"1\">" 752 + "<key-id identifier=\"1\" />" 753 + "</keyset>" 754 + "<keyset identifier=\"2\">" 755 + "<key-id identifier=\"2\" />" 756 + "</keyset>" 757 + "<keyset identifier=\"3\">" 758 + "<key-id identifier=\"3\" />" 759 + "</keyset>" 760 + "<keyset identifier=\"4\">" 761 + "<key-id identifier=\"1\" />" 762 + "<key-id identifier=\"2\" />" 763 + "</keyset>" 764 + "</keysets>" 765 + "<lastIssuedKeyId value=\"3\" />" 766 + "<lastIssuedKeySetId value=\"4\" />" 767 + "</keyset-settings>" 768 + "</packages>").getBytes()); 769 } 770 771 private void writeStoppedPackagesXml() { 772 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"), 773 ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" 774 + "<stopped-packages>" 775 + "<pkg name=\"com.google.app1\" nl=\"1\" />" 776 + "<pkg name=\"com.android.app3\" nl=\"1\" />" 777 + "</stopped-packages>") 778 .getBytes()); 779 } 780 781 private void writePackagesList() { 782 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages.list"), 783 ( "com.google.app1 11000 0 /data/data/com.google.app1 seinfo1" 784 + "com.google.app2 11001 0 /data/data/com.google.app2 seinfo2" 785 + "com.android.app3 11030 0 /data/data/com.android.app3 seinfo3") 786 .getBytes()); 787 } 788 789 private void deleteSystemFolder() { 790 File systemFolder = new File(InstrumentationRegistry.getContext().getFilesDir(), "system"); 791 deleteFolder(systemFolder); 792 } 793 794 private static void deleteFolder(File folder) { 795 File[] files = folder.listFiles(); 796 if (files != null) { 797 for (File file : files) { 798 deleteFolder(file); 799 } 800 } 801 folder.delete(); 802 } 803 804 private void writeOldFiles() { 805 deleteSystemFolder(); 806 writePackagesXml(); 807 writeStoppedPackagesXml(); 808 writePackagesList(); 809 } 810 811 @Before 812 public void createUserManagerServiceRef() throws ReflectiveOperationException { 813 InstrumentationRegistry.getInstrumentation().runOnMainSync((Runnable) () -> { 814 try { 815 // unregister the user manager from the local service 816 LocalServices.removeServiceForTest(UserManagerInternal.class); 817 new UserManagerService(InstrumentationRegistry.getContext()); 818 } catch (Exception e) { 819 e.printStackTrace(); 820 fail("Could not create user manager service; " + e); 821 } 822 }); 823 } 824 825 private void verifyKeySetMetaData(Settings settings) 826 throws ReflectiveOperationException, IllegalAccessException { 827 ArrayMap<String, PackageSetting> packages = settings.mPackages; 828 KeySetManagerService ksms = settings.mKeySetManagerService; 829 830 /* verify keyset and public key ref counts */ 831 assertThat(KeySetUtils.getKeySetRefCount(ksms, 1), is(2)); 832 assertThat(KeySetUtils.getKeySetRefCount(ksms, 2), is(1)); 833 assertThat(KeySetUtils.getKeySetRefCount(ksms, 3), is(1)); 834 assertThat(KeySetUtils.getKeySetRefCount(ksms, 4), is(1)); 835 assertThat(KeySetUtils.getPubKeyRefCount(ksms, 1), is(2)); 836 assertThat(KeySetUtils.getPubKeyRefCount(ksms, 2), is(2)); 837 assertThat(KeySetUtils.getPubKeyRefCount(ksms, 3), is(1)); 838 839 /* verify public keys properly read */ 840 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 841 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 842 PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC); 843 assertThat(KeySetUtils.getPubKey(ksms, 1), is(keyA)); 844 assertThat(KeySetUtils.getPubKey(ksms, 2), is(keyB)); 845 assertThat(KeySetUtils.getPubKey(ksms, 3), is(keyC)); 846 847 /* verify mapping is correct (ks -> pub keys) */ 848 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms); 849 ArraySet<Long> mapping = ksMapping.get(1); 850 assertThat(mapping.size(), is(1)); 851 assertThat(mapping.contains(new Long(1)), is(true)); 852 mapping = ksMapping.get(2); 853 assertThat(mapping.size(), is(1)); 854 assertThat(mapping.contains(new Long(2)), is(true)); 855 mapping = ksMapping.get(3); 856 assertThat(mapping.size(), is(1)); 857 assertThat(mapping.contains(new Long(3)), is(true)); 858 mapping = ksMapping.get(4); 859 assertThat(mapping.size(), is(2)); 860 assertThat(mapping.contains(new Long(1)), is(true)); 861 assertThat(mapping.contains(new Long(2)), is(true)); 862 863 /* verify lastIssuedIds are consistent */ 864 assertThat(KeySetUtils.getLastIssuedKeyId(ksms), is(3L)); 865 assertThat(KeySetUtils.getLastIssuedKeySetId(ksms), is(4L)); 866 867 /* verify packages have been given the appropriate information */ 868 PackageSetting ps = packages.get("com.google.app1"); 869 assertThat(ps.keySetData.getProperSigningKeySet(), is(1L)); 870 ps = packages.get("com.google.app2"); 871 assertThat(ps.keySetData.getProperSigningKeySet(), is(1L)); 872 assertThat(ps.keySetData.getAliases().get("AB"), is(4L)); 873 ps = packages.get("com.android.app3"); 874 assertThat(ps.keySetData.getProperSigningKeySet(), is(2L)); 875 assertThat(ps.keySetData.getAliases().get("C"), is(3L)); 876 assertThat(ps.keySetData.getUpgradeKeySets().length, is(1)); 877 assertThat(ps.keySetData.getUpgradeKeySets()[0], is(3L)); 878 } 879} 880