1 /* 2 * Copyright (C) 2006 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 android.content.pm; 18 19 import static android.system.OsConstants.*; 20 21 import com.android.frameworks.coretests.R; 22 import com.android.internal.content.PackageHelper; 23 24 import android.app.PackageInstallObserver; 25 import android.content.BroadcastReceiver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentFilter; 29 import android.content.pm.KeySet; 30 import android.content.pm.PackageInfo; 31 import android.content.pm.PackageManager; 32 import android.content.pm.PackageManager.NameNotFoundException; 33 import android.content.pm.PackageParser.PackageParserException; 34 import android.content.res.Resources; 35 import android.content.res.Resources.NotFoundException; 36 import android.net.Uri; 37 import android.os.Binder; 38 import android.os.Bundle; 39 import android.os.Environment; 40 import android.os.FileUtils; 41 import android.os.IBinder; 42 import android.os.Process; 43 import android.os.RemoteException; 44 import android.os.ServiceManager; 45 import android.os.StatFs; 46 import android.os.SystemClock; 47 import android.os.UserManager; 48 import android.os.storage.IMountService; 49 import android.os.storage.StorageListener; 50 import android.os.storage.StorageManager; 51 import android.os.storage.StorageResultCode; 52 import android.provider.Settings; 53 import android.provider.Settings.SettingNotFoundException; 54 import android.system.ErrnoException; 55 import android.system.Os; 56 import android.system.StructStat; 57 import android.test.AndroidTestCase; 58 import android.test.suitebuilder.annotation.LargeTest; 59 import android.test.suitebuilder.annotation.SmallTest; 60 import android.util.DisplayMetrics; 61 import android.util.Log; 62 63 import java.io.File; 64 import java.io.IOException; 65 import java.io.InputStream; 66 import java.util.HashSet; 67 import java.util.List; 68 import java.util.Set; 69 70 import java.util.concurrent.CountDownLatch; 71 import java.util.concurrent.TimeUnit; 72 73 public class PackageManagerTests extends AndroidTestCase { 74 private static final boolean localLOGV = true; 75 76 public static final String TAG = "PackageManagerTests"; 77 78 public final long MAX_WAIT_TIME = 25 * 1000; 79 80 public final long WAIT_TIME_INCR = 5 * 1000; 81 82 private static final String APP_LIB_DIR_PREFIX = "/data/app-lib/"; 83 84 private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec/"; 85 86 private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO; 87 88 private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL; 89 90 private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL; 91 92 private boolean mOrigState; 93 94 void failStr(String errMsg) { 95 Log.w(TAG, "errMsg=" + errMsg); 96 fail(errMsg); 97 } 98 99 void failStr(Exception e) { 100 failStr(e.getMessage()); 101 } 102 103 @Override 104 protected void setUp() throws Exception { 105 super.setUp(); 106 mOrigState = checkMediaState(Environment.MEDIA_MOUNTED); 107 if (!mountMedia()) { 108 Log.i(TAG, "sdcard not mounted? Some of these tests might fail"); 109 } 110 } 111 112 @Override 113 protected void tearDown() throws Exception { 114 // Restore media state. 115 boolean newState = checkMediaState(Environment.MEDIA_MOUNTED); 116 if (newState != mOrigState) { 117 if (mOrigState) { 118 mountMedia(); 119 } else { 120 unmountMedia(); 121 } 122 } 123 super.tearDown(); 124 } 125 126 private class TestInstallObserver extends PackageInstallObserver { 127 public int returnCode; 128 129 private boolean doneFlag = false; 130 131 public void packageInstalled(String packageName, Bundle extras, int returnCode) { 132 synchronized (this) { 133 this.returnCode = returnCode; 134 doneFlag = true; 135 notifyAll(); 136 } 137 } 138 139 public boolean isDone() { 140 return doneFlag; 141 } 142 } 143 144 abstract class GenericReceiver extends BroadcastReceiver { 145 private boolean doneFlag = false; 146 147 boolean received = false; 148 149 Intent intent; 150 151 IntentFilter filter; 152 153 abstract boolean notifyNow(Intent intent); 154 155 @Override 156 public void onReceive(Context context, Intent intent) { 157 if (notifyNow(intent)) { 158 synchronized (this) { 159 received = true; 160 doneFlag = true; 161 this.intent = intent; 162 notifyAll(); 163 } 164 } 165 } 166 167 public boolean isDone() { 168 return doneFlag; 169 } 170 171 public void setFilter(IntentFilter filter) { 172 this.filter = filter; 173 } 174 } 175 176 class InstallReceiver extends GenericReceiver { 177 String pkgName; 178 179 InstallReceiver(String pkgName) { 180 this.pkgName = pkgName; 181 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 182 filter.addDataScheme("package"); 183 super.setFilter(filter); 184 } 185 186 public boolean notifyNow(Intent intent) { 187 String action = intent.getAction(); 188 if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) { 189 return false; 190 } 191 Uri data = intent.getData(); 192 String installedPkg = data.getEncodedSchemeSpecificPart(); 193 if (pkgName.equals(installedPkg)) { 194 return true; 195 } 196 return false; 197 } 198 } 199 200 private PackageManager getPm() { 201 return mContext.getPackageManager(); 202 } 203 204 private IPackageManager getIPm() { 205 IPackageManager ipm = IPackageManager.Stub.asInterface( 206 ServiceManager.getService("package")); 207 return ipm; 208 } 209 210 public void invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver, 211 boolean shouldSucceed) { 212 TestInstallObserver observer = new TestInstallObserver(); 213 mContext.registerReceiver(receiver, receiver.filter); 214 try { 215 // Wait on observer 216 synchronized (observer) { 217 synchronized (receiver) { 218 getPm().installPackage(packageURI, observer, flags, null); 219 long waitTime = 0; 220 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 221 try { 222 observer.wait(WAIT_TIME_INCR); 223 waitTime += WAIT_TIME_INCR; 224 } catch (InterruptedException e) { 225 Log.i(TAG, "Interrupted during sleep", e); 226 } 227 } 228 if (!observer.isDone()) { 229 fail("Timed out waiting for packageInstalled callback"); 230 } 231 232 if (shouldSucceed) { 233 if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) { 234 fail("Package installation should have succeeded, but got code " 235 + observer.returnCode); 236 } 237 } else { 238 if (observer.returnCode == PackageManager.INSTALL_SUCCEEDED) { 239 fail("Package installation should fail"); 240 } 241 242 /* 243 * We'll never expect get a notification since we 244 * shouldn't succeed. 245 */ 246 return; 247 } 248 249 // Verify we received the broadcast 250 waitTime = 0; 251 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) { 252 try { 253 receiver.wait(WAIT_TIME_INCR); 254 waitTime += WAIT_TIME_INCR; 255 } catch (InterruptedException e) { 256 Log.i(TAG, "Interrupted during sleep", e); 257 } 258 } 259 if (!receiver.isDone()) { 260 fail("Timed out waiting for PACKAGE_ADDED notification"); 261 } 262 } 263 } 264 } finally { 265 mContext.unregisterReceiver(receiver); 266 } 267 } 268 269 public void invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult) { 270 TestInstallObserver observer = new TestInstallObserver(); 271 try { 272 // Wait on observer 273 synchronized (observer) { 274 getPm().installPackage(packageURI, observer, flags, null); 275 long waitTime = 0; 276 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 277 try { 278 observer.wait(WAIT_TIME_INCR); 279 waitTime += WAIT_TIME_INCR; 280 } catch (InterruptedException e) { 281 Log.i(TAG, "Interrupted during sleep", e); 282 } 283 } 284 if (!observer.isDone()) { 285 fail("Timed out waiting for packageInstalled callback"); 286 } 287 assertEquals(expectedResult, observer.returnCode); 288 } 289 } finally { 290 } 291 } 292 293 Uri getInstallablePackage(int fileResId, File outFile) { 294 Resources res = mContext.getResources(); 295 InputStream is = null; 296 try { 297 is = res.openRawResource(fileResId); 298 } catch (NotFoundException e) { 299 failStr("Failed to load resource with id: " + fileResId); 300 } 301 FileUtils.setPermissions(outFile.getPath(), 302 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, 303 -1, -1); 304 assertTrue(FileUtils.copyToFile(is, outFile)); 305 FileUtils.setPermissions(outFile.getPath(), 306 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, 307 -1, -1); 308 return Uri.fromFile(outFile); 309 } 310 311 private PackageParser.Package parsePackage(Uri packageURI) throws PackageParserException { 312 final String archiveFilePath = packageURI.getPath(); 313 PackageParser packageParser = new PackageParser(); 314 File sourceFile = new File(archiveFilePath); 315 PackageParser.Package pkg = packageParser.parseMonolithicPackage(sourceFile, 0); 316 packageParser = null; 317 return pkg; 318 } 319 320 private boolean checkSd(long pkgLen) { 321 String status = Environment.getExternalStorageState(); 322 if (!status.equals(Environment.MEDIA_MOUNTED)) { 323 return false; 324 } 325 long sdSize = -1; 326 StatFs sdStats = new StatFs(Environment.getExternalStorageDirectory().getPath()); 327 sdSize = (long) sdStats.getAvailableBlocks() * (long) sdStats.getBlockSize(); 328 // TODO check for thresholds here 329 return pkgLen <= sdSize; 330 331 } 332 333 private boolean checkInt(long pkgLen) { 334 StatFs intStats = new StatFs(Environment.getDataDirectory().getPath()); 335 long intSize = (long) intStats.getBlockCount() * (long) intStats.getBlockSize(); 336 long iSize = (long) intStats.getAvailableBlocks() * (long) intStats.getBlockSize(); 337 // TODO check for thresholds here? 338 return pkgLen <= iSize; 339 } 340 341 private static final int INSTALL_LOC_INT = 1; 342 343 private static final int INSTALL_LOC_SD = 2; 344 345 private static final int INSTALL_LOC_ERR = -1; 346 347 private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) { 348 // Flags explicitly over ride everything else. 349 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { 350 return INSTALL_LOC_SD; 351 } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { 352 return INSTALL_LOC_INT; 353 } 354 // Manifest option takes precedence next 355 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 356 if (checkSd(pkgLen)) { 357 return INSTALL_LOC_SD; 358 } 359 if (checkInt(pkgLen)) { 360 return INSTALL_LOC_INT; 361 } 362 return INSTALL_LOC_ERR; 363 } 364 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 365 if (checkInt(pkgLen)) { 366 return INSTALL_LOC_INT; 367 } 368 return INSTALL_LOC_ERR; 369 } 370 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) { 371 // Check for free memory internally 372 if (checkInt(pkgLen)) { 373 return INSTALL_LOC_INT; 374 } 375 // Check for free memory externally 376 if (checkSd(pkgLen)) { 377 return INSTALL_LOC_SD; 378 } 379 return INSTALL_LOC_ERR; 380 } 381 // Check for settings preference. 382 boolean checkSd = false; 383 int userPref = getDefaultInstallLoc(); 384 if (userPref == APP_INSTALL_DEVICE) { 385 if (checkInt(pkgLen)) { 386 return INSTALL_LOC_INT; 387 } 388 return INSTALL_LOC_ERR; 389 } else if (userPref == APP_INSTALL_SDCARD) { 390 if (checkSd(pkgLen)) { 391 return INSTALL_LOC_SD; 392 } 393 return INSTALL_LOC_ERR; 394 } 395 // Default system policy for apps with no manifest option specified. 396 // Check for free memory internally 397 if (checkInt(pkgLen)) { 398 return INSTALL_LOC_INT; 399 } 400 return INSTALL_LOC_ERR; 401 } 402 403 private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) { 404 try { 405 String pkgName = pkg.packageName; 406 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); 407 assertNotNull(info); 408 assertEquals(pkgName, info.packageName); 409 File dataDir = Environment.getDataDirectory(); 410 String appInstallPath = new File(dataDir, "app").getPath(); 411 String drmInstallPath = new File(dataDir, "app-private").getPath(); 412 File srcDir = new File(info.sourceDir); 413 String srcPath = srcDir.getParent(); 414 File publicSrcDir = new File(info.publicSourceDir); 415 String publicSrcPath = publicSrcDir.getParent(); 416 long pkgLen = new File(info.sourceDir).length(); 417 418 int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); 419 if (rLoc == INSTALL_LOC_INT) { 420 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 421 assertTrue("The application should be installed forward locked", 422 (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 423 assertStartsWith("The APK path should point to the ASEC", 424 SECURE_CONTAINERS_PREFIX, srcPath); 425 assertStartsWith("The public APK path should point to the ASEC", 426 SECURE_CONTAINERS_PREFIX, publicSrcPath); 427 assertStartsWith("The native library path should point to the ASEC", 428 SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir); 429 try { 430 String compatLib = new File(info.dataDir + "/lib").getCanonicalPath(); 431 assertEquals("The compatibility lib directory should be a symbolic link to " 432 + info.nativeLibraryDir, 433 info.nativeLibraryDir, compatLib); 434 } catch (IOException e) { 435 fail("compat check: Can't read " + info.dataDir + "/lib"); 436 } 437 } else { 438 assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 439 assertEquals(srcPath, appInstallPath); 440 assertEquals(publicSrcPath, appInstallPath); 441 assertStartsWith("Native library should point to shared lib directory", 442 new File(APP_LIB_DIR_PREFIX, info.packageName).getPath(), 443 info.nativeLibraryDir); 444 assertDirOwnerGroupPerms( 445 "Native library directory should be owned by system:system and 0755", 446 Process.SYSTEM_UID, Process.SYSTEM_UID, 447 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, 448 info.nativeLibraryDir); 449 } 450 assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 451 452 // Make sure the native library dir is not a symlink 453 final File nativeLibDir = new File(info.nativeLibraryDir); 454 assertTrue("Native library dir should exist at " + info.nativeLibraryDir, 455 nativeLibDir.exists()); 456 try { 457 assertEquals("Native library dir should not be a symlink", 458 info.nativeLibraryDir, nativeLibDir.getCanonicalPath()); 459 } catch (IOException e) { 460 fail("Can't read " + nativeLibDir.getPath()); 461 } 462 } else if (rLoc == INSTALL_LOC_SD) { 463 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 464 assertTrue("The application should be installed forward locked", 465 (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 466 } else { 467 assertFalse("The application should not be installed forward locked", 468 (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 469 } 470 assertTrue("Application flags (" + info.flags 471 + ") should contain FLAG_EXTERNAL_STORAGE", 472 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 473 // Might need to check: 474 // ((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) 475 assertStartsWith("The APK path should point to the ASEC", 476 SECURE_CONTAINERS_PREFIX, srcPath); 477 assertStartsWith("The public APK path should point to the ASEC", 478 SECURE_CONTAINERS_PREFIX, publicSrcPath); 479 assertStartsWith("The native library path should point to the ASEC", 480 SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir); 481 482 // Make sure the native library in /data/data/<app>/lib is a 483 // symlink to the ASEC 484 final File nativeLibSymLink = new File(info.dataDir, "lib"); 485 assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), 486 nativeLibSymLink.exists()); 487 try { 488 assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " 489 + info.nativeLibraryDir, info.nativeLibraryDir, 490 nativeLibSymLink.getCanonicalPath()); 491 } catch (IOException e) { 492 fail("Can't read " + nativeLibSymLink.getPath()); 493 } 494 } else { 495 // TODO handle error. Install should have failed. 496 fail("Install should have failed"); 497 } 498 } catch (NameNotFoundException e) { 499 failStr("failed with exception : " + e); 500 } 501 } 502 503 private void assertDirOwnerGroupPerms(String reason, int uid, int gid, int perms, String path) { 504 final StructStat stat; 505 506 try { 507 stat = Os.lstat(path); 508 } catch (ErrnoException e) { 509 throw new AssertionError(reason + "\n" + "Got: " + path + " does not exist"); 510 } 511 512 StringBuilder sb = new StringBuilder(); 513 514 if (!S_ISDIR(stat.st_mode)) { 515 sb.append("\nExpected type: "); 516 sb.append(S_IFDIR); 517 sb.append("\ngot type: "); 518 sb.append((stat.st_mode & S_IFMT)); 519 } 520 521 if (stat.st_uid != uid) { 522 sb.append("\nExpected owner: "); 523 sb.append(uid); 524 sb.append("\nGot owner: "); 525 sb.append(stat.st_uid); 526 } 527 528 if (stat.st_gid != gid) { 529 sb.append("\nExpected group: "); 530 sb.append(gid); 531 sb.append("\nGot group: "); 532 sb.append(stat.st_gid); 533 } 534 535 if ((stat.st_mode & ~S_IFMT) != perms) { 536 sb.append("\nExpected permissions: "); 537 sb.append(Integer.toOctalString(perms)); 538 sb.append("\nGot permissions: "); 539 sb.append(Integer.toOctalString(stat.st_mode & ~S_IFMT)); 540 } 541 542 if (sb.length() > 0) { 543 throw new AssertionError(reason + sb.toString()); 544 } 545 } 546 547 private static void assertStartsWith(String prefix, String actual) { 548 assertStartsWith("", prefix, actual); 549 } 550 551 private static void assertStartsWith(String description, String prefix, String actual) { 552 if (!actual.startsWith(prefix)) { 553 StringBuilder sb = new StringBuilder(description); 554 sb.append("\nExpected prefix: "); 555 sb.append(prefix); 556 sb.append("\n got: "); 557 sb.append(actual); 558 sb.append('\n'); 559 throw new AssertionError(sb.toString()); 560 } 561 } 562 563 private void assertNotInstalled(String pkgName) { 564 try { 565 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); 566 fail(pkgName + " shouldnt be installed"); 567 } catch (NameNotFoundException e) { 568 } 569 570 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 571 List<UserInfo> users = um.getUsers(); 572 for (UserInfo user : users) { 573 String dataDir = PackageManager.getDataDirForUser(user.id, pkgName); 574 assertFalse("Application data directory should not exist: " + dataDir, 575 new File(dataDir).exists()); 576 } 577 } 578 579 class InstallParams { 580 Uri packageURI; 581 582 PackageParser.Package pkg; 583 584 InstallParams(String outFileName, int rawResId) throws PackageParserException { 585 this.pkg = getParsedPackage(outFileName, rawResId); 586 this.packageURI = Uri.fromFile(new File(pkg.codePath)); 587 } 588 589 InstallParams(PackageParser.Package pkg) { 590 this.packageURI = Uri.fromFile(new File(pkg.codePath)); 591 this.pkg = pkg; 592 } 593 594 long getApkSize() { 595 File file = new File(pkg.codePath); 596 return file.length(); 597 } 598 } 599 600 private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) throws Exception { 601 return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, false, -1, 602 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 603 } 604 605 static final String PERM_PACKAGE = "package"; 606 607 static final String PERM_DEFINED = "defined"; 608 609 static final String PERM_UNDEFINED = "undefined"; 610 611 static final String PERM_USED = "used"; 612 613 static final String PERM_NOTUSED = "notused"; 614 615 private void assertPermissions(String[] cmds) { 616 final PackageManager pm = getPm(); 617 String pkg = null; 618 PackageInfo pkgInfo = null; 619 String mode = PERM_DEFINED; 620 int i = 0; 621 while (i < cmds.length) { 622 String cmd = cmds[i++]; 623 if (cmd == PERM_PACKAGE) { 624 pkg = cmds[i++]; 625 try { 626 pkgInfo = pm.getPackageInfo(pkg, 627 PackageManager.GET_PERMISSIONS 628 | PackageManager.GET_UNINSTALLED_PACKAGES); 629 } catch (NameNotFoundException e) { 630 pkgInfo = null; 631 } 632 } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED 633 || cmd == PERM_USED || cmd == PERM_NOTUSED) { 634 mode = cmds[i++]; 635 } else { 636 if (mode == PERM_DEFINED) { 637 try { 638 PermissionInfo pi = pm.getPermissionInfo(cmd, 0); 639 assertNotNull(pi); 640 assertEquals(pi.packageName, pkg); 641 assertEquals(pi.name, cmd); 642 assertNotNull(pkgInfo); 643 boolean found = false; 644 for (int j = 0; j < pkgInfo.permissions.length && !found; j++) { 645 if (pkgInfo.permissions[j].name.equals(cmd)) { 646 found = true; 647 } 648 } 649 if (!found) { 650 fail("Permission not found: " + cmd); 651 } 652 } catch (NameNotFoundException e) { 653 throw new RuntimeException(e); 654 } 655 } else if (mode == PERM_UNDEFINED) { 656 try { 657 pm.getPermissionInfo(cmd, 0); 658 throw new RuntimeException("Permission exists: " + cmd); 659 } catch (NameNotFoundException e) { 660 } 661 if (pkgInfo != null) { 662 boolean found = false; 663 for (int j = 0; j < pkgInfo.permissions.length && !found; j++) { 664 if (pkgInfo.permissions[j].name.equals(cmd)) { 665 found = true; 666 } 667 } 668 if (found) { 669 fail("Permission still exists: " + cmd); 670 } 671 } 672 } else if (mode == PERM_USED || mode == PERM_NOTUSED) { 673 boolean found = false; 674 for (int j = 0; j < pkgInfo.requestedPermissions.length && !found; j++) { 675 if (pkgInfo.requestedPermissions[j].equals(cmd)) { 676 found = true; 677 } 678 } 679 if (!found) { 680 fail("Permission not requested: " + cmd); 681 } 682 if (mode == PERM_USED) { 683 if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_GRANTED) { 684 fail("Permission not granted: " + cmd); 685 } 686 } else { 687 if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_DENIED) { 688 fail("Permission granted: " + cmd); 689 } 690 } 691 } 692 } 693 } 694 } 695 696 private PackageParser.Package getParsedPackage(String outFileName, int rawResId) 697 throws PackageParserException { 698 PackageManager pm = mContext.getPackageManager(); 699 File filesDir = mContext.getFilesDir(); 700 File outFile = new File(filesDir, outFileName); 701 Uri packageURI = getInstallablePackage(rawResId, outFile); 702 PackageParser.Package pkg = parsePackage(packageURI); 703 return pkg; 704 } 705 706 /* 707 * Utility function that reads a apk bundled as a raw resource 708 * copies it into own data directory and invokes 709 * PackageManager api to install it. 710 */ 711 private void installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail, 712 int result, int expInstallLocation) throws Exception { 713 PackageManager pm = mContext.getPackageManager(); 714 PackageParser.Package pkg = ip.pkg; 715 Uri packageURI = ip.packageURI; 716 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) { 717 // Make sure the package doesn't exist 718 try { 719 ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName, 720 PackageManager.GET_UNINSTALLED_PACKAGES); 721 GenericReceiver receiver = new DeleteReceiver(pkg.packageName); 722 invokeDeletePackage(pkg.packageName, 0, receiver); 723 } catch (NameNotFoundException e) { 724 } 725 } 726 try { 727 if (fail) { 728 invokeInstallPackageFail(packageURI, flags, result); 729 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) { 730 assertNotInstalled(pkg.packageName); 731 } 732 } else { 733 InstallReceiver receiver = new InstallReceiver(pkg.packageName); 734 invokeInstallPackage(packageURI, flags, receiver, true); 735 // Verify installed information 736 assertInstall(pkg, flags, expInstallLocation); 737 } 738 } finally { 739 if (cleanUp) { 740 cleanUpInstall(ip); 741 } 742 } 743 } 744 745 /* 746 * Utility function that reads a apk bundled as a raw resource 747 * copies it into own data directory and invokes 748 * PackageManager api to install it. 749 */ 750 private InstallParams installFromRawResource(String outFileName, int rawResId, int flags, 751 boolean cleanUp, boolean fail, int result, int expInstallLocation) throws Exception { 752 InstallParams ip = new InstallParams(outFileName, rawResId); 753 installFromRawResource(ip, flags, cleanUp, fail, result, expInstallLocation); 754 return ip; 755 } 756 757 @LargeTest 758 public void testInstallNormalInternal() throws Exception { 759 sampleInstallFromRawResource(0, true); 760 } 761 762 @LargeTest 763 public void testInstallFwdLockedInternal() throws Exception { 764 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true); 765 } 766 767 @LargeTest 768 public void testInstallSdcard() throws Exception { 769 // Do not run on devices with emulated external storage. 770 if (Environment.isExternalStorageEmulated()) { 771 return; 772 } 773 774 mountMedia(); 775 sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true); 776 } 777 778 /* ------------------------- Test replacing packages -------------- */ 779 class ReplaceReceiver extends GenericReceiver { 780 String pkgName; 781 782 final static int INVALID = -1; 783 784 final static int REMOVED = 1; 785 786 final static int ADDED = 2; 787 788 final static int REPLACED = 3; 789 790 int removed = INVALID; 791 792 // for updated system apps only 793 boolean update = false; 794 795 ReplaceReceiver(String pkgName) { 796 this.pkgName = pkgName; 797 filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 798 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 799 if (update) { 800 filter.addAction(Intent.ACTION_PACKAGE_REPLACED); 801 } 802 filter.addDataScheme("package"); 803 super.setFilter(filter); 804 } 805 806 public boolean notifyNow(Intent intent) { 807 String action = intent.getAction(); 808 Uri data = intent.getData(); 809 String installedPkg = data.getEncodedSchemeSpecificPart(); 810 if (pkgName == null || !pkgName.equals(installedPkg)) { 811 return false; 812 } 813 if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 814 removed = REMOVED; 815 } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 816 if (removed != REMOVED) { 817 return false; 818 } 819 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 820 if (!replacing) { 821 return false; 822 } 823 removed = ADDED; 824 if (!update) { 825 return true; 826 } 827 } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 828 if (removed != ADDED) { 829 return false; 830 } 831 removed = REPLACED; 832 return true; 833 } 834 return false; 835 } 836 } 837 838 /* 839 * Utility function that reads a apk bundled as a raw resource 840 * copies it into own data directory and invokes 841 * PackageManager api to install first and then replace it 842 * again. 843 */ 844 private void sampleReplaceFromRawResource(int flags) throws Exception { 845 InstallParams ip = sampleInstallFromRawResource(flags, false); 846 boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0); 847 Log.i(TAG, "replace=" + replace); 848 GenericReceiver receiver; 849 if (replace) { 850 receiver = new ReplaceReceiver(ip.pkg.packageName); 851 Log.i(TAG, "Creating replaceReceiver"); 852 } else { 853 receiver = new InstallReceiver(ip.pkg.packageName); 854 } 855 try { 856 invokeInstallPackage(ip.packageURI, flags, receiver, replace); 857 if (replace) { 858 assertInstall(ip.pkg, flags, ip.pkg.installLocation); 859 } 860 } finally { 861 cleanUpInstall(ip); 862 } 863 } 864 865 @LargeTest 866 public void testReplaceFailNormalInternal() throws Exception { 867 sampleReplaceFromRawResource(0); 868 } 869 870 @LargeTest 871 public void testReplaceFailFwdLockedInternal() throws Exception { 872 sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK); 873 } 874 875 @LargeTest 876 public void testReplaceFailSdcard() throws Exception { 877 // Do not run on devices with emulated external storage. 878 if (Environment.isExternalStorageEmulated()) { 879 return; 880 } 881 882 sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL); 883 } 884 885 @LargeTest 886 public void testReplaceNormalInternal() throws Exception { 887 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING); 888 } 889 890 @LargeTest 891 public void testReplaceFwdLockedInternal() throws Exception { 892 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING 893 | PackageManager.INSTALL_FORWARD_LOCK); 894 } 895 896 @LargeTest 897 public void testReplaceSdcard() throws Exception { 898 // Do not run on devices with emulated external storage. 899 if (Environment.isExternalStorageEmulated()) { 900 return; 901 } 902 903 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING 904 | PackageManager.INSTALL_EXTERNAL); 905 } 906 907 /* -------------- Delete tests --- */ 908 private static class DeleteObserver extends IPackageDeleteObserver.Stub { 909 private CountDownLatch mLatch = new CountDownLatch(1); 910 911 private int mReturnCode; 912 913 private final String mPackageName; 914 915 private String mObservedPackage; 916 917 public DeleteObserver(String packageName) { 918 mPackageName = packageName; 919 } 920 921 public boolean isSuccessful() { 922 return mReturnCode == PackageManager.DELETE_SUCCEEDED; 923 } 924 925 public void packageDeleted(String packageName, int returnCode) throws RemoteException { 926 mObservedPackage = packageName; 927 928 mReturnCode = returnCode; 929 930 mLatch.countDown(); 931 } 932 933 public void waitForCompletion(long timeoutMillis) { 934 final long deadline = SystemClock.uptimeMillis() + timeoutMillis; 935 936 long waitTime = timeoutMillis; 937 while (waitTime > 0) { 938 try { 939 boolean done = mLatch.await(waitTime, TimeUnit.MILLISECONDS); 940 if (done) { 941 assertEquals(mPackageName, mObservedPackage); 942 return; 943 } 944 } catch (InterruptedException e) { 945 // TODO Auto-generated catch block 946 e.printStackTrace(); 947 } 948 waitTime = deadline - SystemClock.uptimeMillis(); 949 } 950 951 throw new AssertionError("Timeout waiting for package deletion"); 952 } 953 } 954 955 class DeleteReceiver extends GenericReceiver { 956 String pkgName; 957 958 DeleteReceiver(String pkgName) { 959 this.pkgName = pkgName; 960 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 961 filter.addDataScheme("package"); 962 super.setFilter(filter); 963 } 964 965 public boolean notifyNow(Intent intent) { 966 String action = intent.getAction(); 967 if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 968 return false; 969 } 970 Uri data = intent.getData(); 971 String installedPkg = data.getEncodedSchemeSpecificPart(); 972 if (pkgName.equals(installedPkg)) { 973 return true; 974 } 975 return false; 976 } 977 } 978 979 public boolean invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver) 980 throws Exception { 981 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 982 PackageManager.GET_UNINSTALLED_PACKAGES); 983 984 mContext.registerReceiver(receiver, receiver.filter); 985 try { 986 DeleteObserver observer = new DeleteObserver(pkgName); 987 988 getPm().deletePackage(pkgName, observer, flags | PackageManager.DELETE_ALL_USERS); 989 observer.waitForCompletion(MAX_WAIT_TIME); 990 991 assertUninstalled(info); 992 993 // Verify we received the broadcast 994 // TODO replace this with a CountDownLatch 995 synchronized (receiver) { 996 long waitTime = 0; 997 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) { 998 receiver.wait(WAIT_TIME_INCR); 999 waitTime += WAIT_TIME_INCR; 1000 } 1001 if (!receiver.isDone()) { 1002 throw new Exception("Timed out waiting for PACKAGE_REMOVED notification"); 1003 } 1004 } 1005 return receiver.received; 1006 } finally { 1007 mContext.unregisterReceiver(receiver); 1008 } 1009 } 1010 1011 private static void assertUninstalled(ApplicationInfo info) throws Exception { 1012 File nativeLibraryFile = new File(info.nativeLibraryDir); 1013 assertFalse("Native library directory should be erased", nativeLibraryFile.exists()); 1014 } 1015 1016 public void deleteFromRawResource(int iFlags, int dFlags) throws Exception { 1017 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 1018 boolean retainData = ((dFlags & PackageManager.DELETE_KEEP_DATA) != 0); 1019 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 1020 try { 1021 assertTrue(invokeDeletePackage(ip.pkg.packageName, dFlags, receiver)); 1022 ApplicationInfo info = null; 1023 Log.i(TAG, "okay4"); 1024 try { 1025 info = getPm().getApplicationInfo(ip.pkg.packageName, 1026 PackageManager.GET_UNINSTALLED_PACKAGES); 1027 } catch (NameNotFoundException e) { 1028 info = null; 1029 } 1030 if (retainData) { 1031 assertNotNull(info); 1032 assertEquals(info.packageName, ip.pkg.packageName); 1033 File file = new File(info.dataDir); 1034 assertTrue(file.exists()); 1035 } else { 1036 assertNull(info); 1037 } 1038 } catch (Exception e) { 1039 failStr(e); 1040 } finally { 1041 cleanUpInstall(ip); 1042 } 1043 } 1044 1045 @LargeTest 1046 public void testDeleteNormalInternal() throws Exception { 1047 deleteFromRawResource(0, 0); 1048 } 1049 1050 @LargeTest 1051 public void testDeleteFwdLockedInternal() throws Exception { 1052 deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0); 1053 } 1054 1055 @LargeTest 1056 public void testDeleteSdcard() throws Exception { 1057 // Do not run on devices with emulated external storage. 1058 if (Environment.isExternalStorageEmulated()) { 1059 return; 1060 } 1061 1062 deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0); 1063 } 1064 1065 @LargeTest 1066 public void testDeleteNormalInternalRetainData() throws Exception { 1067 deleteFromRawResource(0, PackageManager.DELETE_KEEP_DATA); 1068 } 1069 1070 @LargeTest 1071 public void testDeleteFwdLockedInternalRetainData() throws Exception { 1072 deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DELETE_KEEP_DATA); 1073 } 1074 1075 @LargeTest 1076 public void testDeleteSdcardRetainData() throws Exception { 1077 // Do not run on devices with emulated external storage. 1078 if (Environment.isExternalStorageEmulated()) { 1079 return; 1080 } 1081 1082 deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DELETE_KEEP_DATA); 1083 } 1084 1085 /* sdcard mount/unmount tests ***** */ 1086 1087 class SdMountReceiver extends GenericReceiver { 1088 String pkgNames[]; 1089 1090 boolean status = true; 1091 1092 SdMountReceiver(String[] pkgNames) { 1093 this.pkgNames = pkgNames; 1094 IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 1095 super.setFilter(filter); 1096 } 1097 1098 public boolean notifyNow(Intent intent) { 1099 Log.i(TAG, "okay 1"); 1100 String action = intent.getAction(); 1101 if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 1102 return false; 1103 } 1104 String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1105 for (String pkg : pkgNames) { 1106 boolean found = false; 1107 for (String rpkg : rpkgList) { 1108 if (rpkg.equals(pkg)) { 1109 found = true; 1110 break; 1111 } 1112 } 1113 if (!found) { 1114 status = false; 1115 return true; 1116 } 1117 } 1118 return true; 1119 } 1120 } 1121 1122 class SdUnMountReceiver extends GenericReceiver { 1123 String pkgNames[]; 1124 1125 boolean status = true; 1126 1127 SdUnMountReceiver(String[] pkgNames) { 1128 this.pkgNames = pkgNames; 1129 IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 1130 super.setFilter(filter); 1131 } 1132 1133 public boolean notifyNow(Intent intent) { 1134 String action = intent.getAction(); 1135 if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 1136 return false; 1137 } 1138 String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1139 for (String pkg : pkgNames) { 1140 boolean found = false; 1141 for (String rpkg : rpkgList) { 1142 if (rpkg.equals(pkg)) { 1143 found = true; 1144 break; 1145 } 1146 } 1147 if (!found) { 1148 status = false; 1149 return true; 1150 } 1151 } 1152 return true; 1153 } 1154 } 1155 1156 IMountService getMs() { 1157 IBinder service = ServiceManager.getService("mount"); 1158 if (service != null) { 1159 return IMountService.Stub.asInterface(service); 1160 } else { 1161 Log.e(TAG, "Can't get mount service"); 1162 } 1163 return null; 1164 } 1165 1166 boolean checkMediaState(String desired) { 1167 try { 1168 String mPath = Environment.getExternalStorageDirectory().getPath(); 1169 String actual = getMs().getVolumeState(mPath); 1170 if (desired.equals(actual)) { 1171 return true; 1172 } else { 1173 return false; 1174 } 1175 } catch (RemoteException e) { 1176 Log.e(TAG, "Exception while checking media state", e); 1177 return false; 1178 } 1179 } 1180 1181 boolean mountMedia() { 1182 // We can't mount emulated storage. 1183 if (Environment.isExternalStorageEmulated()) { 1184 return true; 1185 } 1186 1187 if (checkMediaState(Environment.MEDIA_MOUNTED)) { 1188 return true; 1189 } 1190 1191 final String path = Environment.getExternalStorageDirectory().toString(); 1192 StorageListener observer = new StorageListener(Environment.MEDIA_MOUNTED); 1193 StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 1194 sm.registerListener(observer); 1195 try { 1196 // Wait on observer 1197 synchronized (observer) { 1198 int ret = getMs().mountVolume(path); 1199 if (ret != StorageResultCode.OperationSucceeded) { 1200 throw new Exception("Could not mount the media"); 1201 } 1202 long waitTime = 0; 1203 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1204 observer.wait(WAIT_TIME_INCR); 1205 waitTime += WAIT_TIME_INCR; 1206 } 1207 if (!observer.isDone()) { 1208 throw new Exception("Timed out waiting for unmount media notification"); 1209 } 1210 return true; 1211 } 1212 } catch (Exception e) { 1213 Log.e(TAG, "Exception : " + e); 1214 return false; 1215 } finally { 1216 sm.unregisterListener(observer); 1217 } 1218 } 1219 1220 private boolean unmountMedia() { 1221 // We can't unmount emulated storage. 1222 if (Environment.isExternalStorageEmulated()) { 1223 return true; 1224 } 1225 1226 if (checkMediaState(Environment.MEDIA_UNMOUNTED)) { 1227 return true; 1228 } 1229 1230 final String path = Environment.getExternalStorageDirectory().getPath(); 1231 StorageListener observer = new StorageListener(Environment.MEDIA_UNMOUNTED); 1232 StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 1233 sm.registerListener(observer); 1234 try { 1235 // Wait on observer 1236 synchronized (observer) { 1237 getMs().unmountVolume(path, true, false); 1238 long waitTime = 0; 1239 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1240 observer.wait(WAIT_TIME_INCR); 1241 waitTime += WAIT_TIME_INCR; 1242 } 1243 if (!observer.isDone()) { 1244 throw new Exception("Timed out waiting for unmount media notification"); 1245 } 1246 return true; 1247 } 1248 } catch (Exception e) { 1249 Log.e(TAG, "Exception : " + e); 1250 return false; 1251 } finally { 1252 sm.unregisterListener(observer); 1253 } 1254 } 1255 1256 private boolean mountFromRawResource() throws Exception { 1257 // Install pkg on sdcard 1258 InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false); 1259 if (localLOGV) Log.i(TAG, "Installed pkg on sdcard"); 1260 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1261 boolean registeredReceiver = false; 1262 SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName}); 1263 try { 1264 if (localLOGV) Log.i(TAG, "Unmounting media"); 1265 // Unmount media 1266 assertTrue(unmountMedia()); 1267 if (localLOGV) Log.i(TAG, "Unmounted media"); 1268 // Register receiver here 1269 PackageManager pm = getPm(); 1270 mContext.registerReceiver(receiver, receiver.filter); 1271 registeredReceiver = true; 1272 1273 // Wait on receiver 1274 synchronized (receiver) { 1275 if (localLOGV) Log.i(TAG, "Mounting media"); 1276 // Mount media again 1277 assertTrue(mountMedia()); 1278 if (localLOGV) Log.i(TAG, "Mounted media"); 1279 if (localLOGV) Log.i(TAG, "Waiting for notification"); 1280 long waitTime = 0; 1281 // Verify we received the broadcast 1282 waitTime = 0; 1283 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1284 receiver.wait(WAIT_TIME_INCR); 1285 waitTime += WAIT_TIME_INCR; 1286 } 1287 if(!receiver.isDone()) { 1288 failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification"); 1289 } 1290 return receiver.received; 1291 } 1292 } catch (InterruptedException e) { 1293 failStr(e); 1294 return false; 1295 } finally { 1296 if (registeredReceiver) { 1297 mContext.unregisterReceiver(receiver); 1298 } 1299 // Restore original media state 1300 if (origState) { 1301 mountMedia(); 1302 } else { 1303 unmountMedia(); 1304 } 1305 if (localLOGV) Log.i(TAG, "Cleaning up install"); 1306 cleanUpInstall(ip); 1307 } 1308 } 1309 1310 /* 1311 * Install package on sdcard. Unmount and then mount the media. 1312 * (Use PackageManagerService private api for now) 1313 * Make sure the installed package is available. 1314 */ 1315 @LargeTest 1316 public void testMountSdNormalInternal() throws Exception { 1317 // Do not run on devices with emulated external storage. 1318 if (Environment.isExternalStorageEmulated()) { 1319 return; 1320 } 1321 1322 assertTrue(mountFromRawResource()); 1323 } 1324 1325 void cleanUpInstall(InstallParams ip) throws Exception { 1326 if (ip == null) { 1327 return; 1328 } 1329 Runtime.getRuntime().gc(); 1330 1331 final String packageName = ip.pkg.packageName; 1332 Log.i(TAG, "Deleting package : " + packageName); 1333 1334 ApplicationInfo info = null; 1335 try { 1336 info = getPm().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); 1337 } catch (NameNotFoundException ignored) { 1338 } 1339 1340 DeleteObserver observer = new DeleteObserver(packageName); 1341 getPm().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS); 1342 observer.waitForCompletion(MAX_WAIT_TIME); 1343 1344 try { 1345 if (info != null) { 1346 assertUninstalled(info); 1347 } 1348 } finally { 1349 File outFile = new File(ip.pkg.codePath); 1350 if (outFile != null && outFile.exists()) { 1351 outFile.delete(); 1352 } 1353 } 1354 } 1355 1356 private void cleanUpInstall(String pkgName) throws Exception { 1357 if (pkgName == null) { 1358 return; 1359 } 1360 Log.i(TAG, "Deleting package : " + pkgName); 1361 try { 1362 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 1363 PackageManager.GET_UNINSTALLED_PACKAGES); 1364 1365 if (info != null) { 1366 DeleteObserver observer = new DeleteObserver(pkgName); 1367 getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS); 1368 observer.waitForCompletion(MAX_WAIT_TIME); 1369 assertUninstalled(info); 1370 } 1371 } catch (NameNotFoundException e) { 1372 } 1373 } 1374 1375 @LargeTest 1376 public void testManifestInstallLocationInternal() throws Exception { 1377 installFromRawResource("install.apk", R.raw.install_loc_internal, 1378 0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1379 } 1380 1381 @LargeTest 1382 public void testManifestInstallLocationSdcard() throws Exception { 1383 // Do not run on devices with emulated external storage. 1384 if (Environment.isExternalStorageEmulated()) { 1385 return; 1386 } 1387 1388 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1389 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1390 } 1391 1392 @LargeTest 1393 public void testManifestInstallLocationAuto() throws Exception { 1394 installFromRawResource("install.apk", R.raw.install_loc_auto, 1395 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO); 1396 } 1397 1398 @LargeTest 1399 public void testManifestInstallLocationUnspecified() throws Exception { 1400 installFromRawResource("install.apk", R.raw.install_loc_unspecified, 1401 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1402 } 1403 1404 @LargeTest 1405 public void testManifestInstallLocationFwdLockedFlagSdcard() throws Exception { 1406 // Do not run on devices with emulated external storage. 1407 if (Environment.isExternalStorageEmulated()) { 1408 return; 1409 } 1410 1411 installFromRawResource("install.apk", R.raw.install_loc_unspecified, 1412 PackageManager.INSTALL_FORWARD_LOCK | 1413 PackageManager.INSTALL_EXTERNAL, true, false, -1, 1414 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1415 } 1416 1417 @LargeTest 1418 public void testManifestInstallLocationFwdLockedSdcard() throws Exception { 1419 // Do not run on devices with emulated external storage. 1420 if (Environment.isExternalStorageEmulated()) { 1421 return; 1422 } 1423 1424 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1425 PackageManager.INSTALL_FORWARD_LOCK, true, false, -1, 1426 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1427 } 1428 1429 /* 1430 * Install a package on internal flash via PackageManager install flag. Replace 1431 * the package via flag to install on sdcard. Make sure the new flag overrides 1432 * the old install location. 1433 */ 1434 @LargeTest 1435 public void testReplaceFlagInternalSdcard() throws Exception { 1436 // Do not run on devices with emulated external storage. 1437 if (Environment.isExternalStorageEmulated()) { 1438 return; 1439 } 1440 1441 int iFlags = 0; 1442 int rFlags = PackageManager.INSTALL_EXTERNAL; 1443 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 1444 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1445 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1446 try { 1447 invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true); 1448 assertInstall(ip.pkg, rFlags, ip.pkg.installLocation); 1449 } catch (Exception e) { 1450 failStr("Failed with exception : " + e); 1451 } finally { 1452 cleanUpInstall(ip); 1453 } 1454 } 1455 1456 /* 1457 * Install a package on sdcard via PackageManager install flag. Replace 1458 * the package with no flags or manifest option and make sure the old 1459 * install location is retained. 1460 */ 1461 @LargeTest 1462 public void testReplaceFlagSdcardInternal() throws Exception { 1463 // Do not run on devices with emulated external storage. 1464 if (Environment.isExternalStorageEmulated()) { 1465 return; 1466 } 1467 1468 int iFlags = PackageManager.INSTALL_EXTERNAL; 1469 int rFlags = 0; 1470 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 1471 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1472 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1473 try { 1474 invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true); 1475 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 1476 } catch (Exception e) { 1477 failStr("Failed with exception : " + e); 1478 } finally { 1479 cleanUpInstall(ip); 1480 } 1481 } 1482 1483 @LargeTest 1484 public void testManifestInstallLocationReplaceInternalSdcard() throws Exception { 1485 // Do not run on devices with emulated external storage. 1486 if (Environment.isExternalStorageEmulated()) { 1487 return; 1488 } 1489 1490 int iFlags = 0; 1491 int iApk = R.raw.install_loc_internal; 1492 int rFlags = 0; 1493 int rApk = R.raw.install_loc_sdcard; 1494 InstallParams ip = installFromRawResource("install.apk", iApk, 1495 iFlags, false, 1496 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1497 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1498 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1499 try { 1500 InstallParams rp = installFromRawResource("install.apk", rApk, 1501 replaceFlags, false, 1502 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1503 assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation); 1504 } catch (Exception e) { 1505 failStr("Failed with exception : " + e); 1506 } finally { 1507 cleanUpInstall(ip); 1508 } 1509 } 1510 1511 @LargeTest 1512 public void testManifestInstallLocationReplaceSdcardInternal() throws Exception { 1513 // Do not run on devices with emulated external storage. 1514 if (Environment.isExternalStorageEmulated()) { 1515 return; 1516 } 1517 1518 int iFlags = 0; 1519 int iApk = R.raw.install_loc_sdcard; 1520 int rFlags = 0; 1521 int rApk = R.raw.install_loc_unspecified; 1522 InstallParams ip = installFromRawResource("install.apk", iApk, 1523 iFlags, false, 1524 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1525 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1526 try { 1527 InstallParams rp = installFromRawResource("install.apk", rApk, 1528 replaceFlags, false, 1529 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1530 assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation); 1531 } catch (Exception e) { 1532 failStr("Failed with exception : " + e); 1533 } finally { 1534 cleanUpInstall(ip); 1535 } 1536 } 1537 1538 class MoveReceiver extends GenericReceiver { 1539 String pkgName; 1540 1541 final static int INVALID = -1; 1542 1543 final static int REMOVED = 1; 1544 1545 final static int ADDED = 2; 1546 1547 int removed = INVALID; 1548 1549 MoveReceiver(String pkgName) { 1550 this.pkgName = pkgName; 1551 filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 1552 filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 1553 super.setFilter(filter); 1554 } 1555 1556 public boolean notifyNow(Intent intent) { 1557 String action = intent.getAction(); 1558 Log.i(TAG, "MoveReceiver::" + action); 1559 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 1560 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1561 if (list != null) { 1562 for (String pkg : list) { 1563 if (pkg.equals(pkgName)) { 1564 removed = REMOVED; 1565 break; 1566 } 1567 } 1568 } 1569 removed = REMOVED; 1570 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 1571 if (removed != REMOVED) { 1572 return false; 1573 } 1574 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1575 if (list != null) { 1576 for (String pkg : list) { 1577 if (pkg.equals(pkgName)) { 1578 removed = ADDED; 1579 return true; 1580 } 1581 } 1582 } 1583 } 1584 return false; 1585 } 1586 } 1587 1588 private class PackageMoveObserver extends IPackageMoveObserver.Stub { 1589 public int returnCode; 1590 1591 private boolean doneFlag = false; 1592 1593 public String packageName; 1594 1595 public PackageMoveObserver(String pkgName) { 1596 packageName = pkgName; 1597 } 1598 1599 public void packageMoved(String packageName, int returnCode) { 1600 Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode); 1601 if (!packageName.equals(this.packageName)) { 1602 return; 1603 } 1604 synchronized (this) { 1605 this.returnCode = returnCode; 1606 doneFlag = true; 1607 notifyAll(); 1608 } 1609 } 1610 1611 public boolean isDone() { 1612 return doneFlag; 1613 } 1614 } 1615 1616 public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver) 1617 throws Exception { 1618 PackageMoveObserver observer = new PackageMoveObserver(pkgName); 1619 final boolean received = false; 1620 mContext.registerReceiver(receiver, receiver.filter); 1621 try { 1622 // Wait on observer 1623 synchronized (observer) { 1624 synchronized (receiver) { 1625 getPm().movePackage(pkgName, observer, flags); 1626 long waitTime = 0; 1627 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1628 observer.wait(WAIT_TIME_INCR); 1629 waitTime += WAIT_TIME_INCR; 1630 } 1631 if (!observer.isDone()) { 1632 throw new Exception("Timed out waiting for pkgmove callback"); 1633 } 1634 if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) { 1635 return false; 1636 } 1637 // Verify we received the broadcast 1638 waitTime = 0; 1639 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1640 receiver.wait(WAIT_TIME_INCR); 1641 waitTime += WAIT_TIME_INCR; 1642 } 1643 if (!receiver.isDone()) { 1644 throw new Exception("Timed out waiting for MOVE notifications"); 1645 } 1646 return receiver.received; 1647 } 1648 } 1649 } finally { 1650 mContext.unregisterReceiver(receiver); 1651 } 1652 } 1653 1654 private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception { 1655 PackageMoveObserver observer = new PackageMoveObserver(pkgName); 1656 try { 1657 // Wait on observer 1658 synchronized (observer) { 1659 getPm().movePackage(pkgName, observer, flags); 1660 long waitTime = 0; 1661 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 1662 observer.wait(WAIT_TIME_INCR); 1663 waitTime += WAIT_TIME_INCR; 1664 } 1665 if (!observer.isDone()) { 1666 throw new Exception("Timed out waiting for pkgmove callback"); 1667 } 1668 assertEquals(errCode, observer.returnCode); 1669 } 1670 } finally { 1671 } 1672 return true; 1673 } 1674 1675 private int getDefaultInstallLoc() { 1676 int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO; 1677 try { 1678 origDefaultLoc = Settings.Global.getInt(mContext.getContentResolver(), 1679 Settings.Global.DEFAULT_INSTALL_LOCATION); 1680 } catch (SettingNotFoundException e1) { 1681 } 1682 return origDefaultLoc; 1683 } 1684 1685 private void setInstallLoc(int loc) { 1686 Settings.Global.putInt(mContext.getContentResolver(), 1687 Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 1688 } 1689 1690 /* 1691 * Tests for moving apps between internal and external storage 1692 */ 1693 /* 1694 * Utility function that reads a apk bundled as a raw resource 1695 * copies it into own data directory and invokes 1696 * PackageManager api to install first and then replace it 1697 * again. 1698 */ 1699 1700 private void moveFromRawResource(String outFileName, int rawResId, int installFlags, 1701 int moveFlags, boolean cleanUp, boolean fail, int result) throws Exception { 1702 int origDefaultLoc = getDefaultInstallLoc(); 1703 InstallParams ip = null; 1704 try { 1705 setInstallLoc(PackageHelper.APP_INSTALL_AUTO); 1706 // Install first 1707 ip = installFromRawResource("install.apk", rawResId, installFlags, false, 1708 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1709 ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1710 if (fail) { 1711 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); 1712 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1713 assertNotNull(info); 1714 assertEquals(oldAppInfo.flags, info.flags); 1715 } else { 1716 // Create receiver based on expRetCode 1717 MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); 1718 boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, receiver); 1719 assertTrue(retCode); 1720 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1721 assertNotNull("ApplicationInfo for recently installed application should exist", 1722 info); 1723 if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) { 1724 assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set", 1725 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0); 1726 assertStartsWith("Native library dir should be in dataDir", 1727 info.dataDir, info.nativeLibraryDir); 1728 } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0) { 1729 assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set", 1730 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 1731 assertStartsWith("Native library dir should point to ASEC", 1732 SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir); 1733 final File nativeLibSymLink = new File(info.dataDir, "lib"); 1734 assertStartsWith("The data directory should have a 'lib' symlink that points to the ASEC container", 1735 SECURE_CONTAINERS_PREFIX, nativeLibSymLink.getCanonicalPath()); 1736 } 1737 } 1738 } catch (NameNotFoundException e) { 1739 failStr("Pkg hasnt been installed correctly"); 1740 } catch (Exception e) { 1741 failStr("Failed with exception : " + e); 1742 } finally { 1743 if (ip != null) { 1744 cleanUpInstall(ip); 1745 } 1746 // Restore default install location 1747 setInstallLoc(origDefaultLoc); 1748 } 1749 } 1750 1751 private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail, 1752 int result) throws Exception { 1753 moveFromRawResource("install.apk", 1754 R.raw.install, installFlags, moveFlags, true, 1755 fail, result); 1756 } 1757 1758 @LargeTest 1759 public void testMoveAppInternalToExternal() throws Exception { 1760 // Do not run on devices with emulated external storage. 1761 if (Environment.isExternalStorageEmulated()) { 1762 return; 1763 } 1764 1765 int installFlags = PackageManager.INSTALL_INTERNAL; 1766 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1767 boolean fail = false; 1768 int result = PackageManager.MOVE_SUCCEEDED; 1769 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1770 } 1771 1772 @LargeTest 1773 public void testMoveAppInternalToInternal() throws Exception { 1774 int installFlags = PackageManager.INSTALL_INTERNAL; 1775 int moveFlags = PackageManager.MOVE_INTERNAL; 1776 boolean fail = true; 1777 int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; 1778 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1779 } 1780 1781 @LargeTest 1782 public void testMoveAppExternalToExternal() throws Exception { 1783 // Do not run on devices with emulated external storage. 1784 if (Environment.isExternalStorageEmulated()) { 1785 return; 1786 } 1787 1788 int installFlags = PackageManager.INSTALL_EXTERNAL; 1789 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1790 boolean fail = true; 1791 int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; 1792 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1793 } 1794 1795 @LargeTest 1796 public void testMoveAppExternalToInternal() throws Exception { 1797 // Do not run on devices with emulated external storage. 1798 if (Environment.isExternalStorageEmulated()) { 1799 return; 1800 } 1801 1802 int installFlags = PackageManager.INSTALL_EXTERNAL; 1803 int moveFlags = PackageManager.MOVE_INTERNAL; 1804 boolean fail = false; 1805 int result = PackageManager.MOVE_SUCCEEDED; 1806 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1807 } 1808 1809 @LargeTest 1810 public void testMoveAppForwardLocked() throws Exception { 1811 // Do not run on devices with emulated external storage. 1812 if (Environment.isExternalStorageEmulated()) { 1813 return; 1814 } 1815 1816 int installFlags = PackageManager.INSTALL_FORWARD_LOCK; 1817 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1818 boolean fail = false; 1819 int result = PackageManager.MOVE_SUCCEEDED; 1820 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1821 } 1822 1823 @LargeTest 1824 public void testMoveAppFailInternalToExternalDelete() throws Exception { 1825 // Do not run on devices with emulated external storage. 1826 if (Environment.isExternalStorageEmulated()) { 1827 return; 1828 } 1829 1830 int installFlags = 0; 1831 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1832 boolean fail = true; 1833 final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST; 1834 1835 int rawResId = R.raw.install; 1836 int origDefaultLoc = getDefaultInstallLoc(); 1837 InstallParams ip = null; 1838 try { 1839 PackageManager pm = getPm(); 1840 setInstallLoc(PackageHelper.APP_INSTALL_AUTO); 1841 // Install first 1842 ip = installFromRawResource("install.apk", R.raw.install, installFlags, false, 1843 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1844 // Delete the package now retaining data. 1845 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 1846 invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver); 1847 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); 1848 } catch (Exception e) { 1849 failStr(e); 1850 } finally { 1851 if (ip != null) { 1852 cleanUpInstall(ip); 1853 } 1854 // Restore default install location 1855 setInstallLoc(origDefaultLoc); 1856 } 1857 } 1858 1859 /* 1860 * Test that an install error code is returned when media is unmounted 1861 * and package installed on sdcard via package manager flag. 1862 */ 1863 @LargeTest 1864 public void testInstallSdcardUnmount() throws Exception { 1865 // Do not run on devices with emulated external storage. 1866 if (Environment.isExternalStorageEmulated()) { 1867 return; 1868 } 1869 1870 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1871 try { 1872 // Unmount sdcard 1873 assertTrue(unmountMedia()); 1874 // Try to install and make sure an error code is returned. 1875 installFromRawResource("install.apk", R.raw.install, 1876 PackageManager.INSTALL_EXTERNAL, false, 1877 true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE, 1878 PackageInfo.INSTALL_LOCATION_AUTO); 1879 } finally { 1880 // Restore original media state 1881 if (origState) { 1882 mountMedia(); 1883 } else { 1884 unmountMedia(); 1885 } 1886 } 1887 } 1888 1889 /* 1890 * Unmount sdcard. Try installing an app with manifest option to install 1891 * on sdcard. Make sure it gets installed on internal flash. 1892 */ 1893 @LargeTest 1894 public void testInstallManifestSdcardUnmount() throws Exception { 1895 // Do not run on devices with emulated external storage. 1896 if (Environment.isExternalStorageEmulated()) { 1897 return; 1898 } 1899 1900 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1901 try { 1902 // Unmount sdcard 1903 assertTrue(unmountMedia()); 1904 InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard); 1905 installFromRawResource(ip, 0, true, false, -1, 1906 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1907 } finally { 1908 // Restore original media state 1909 if (origState) { 1910 mountMedia(); 1911 } else { 1912 unmountMedia(); 1913 } 1914 } 1915 } 1916 1917 /*---------- Recommended install location tests ----*/ 1918 /* 1919 * PrecedenceSuffixes: 1920 * Flag : FlagI, FlagE, FlagF 1921 * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option. 1922 * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option. 1923 * Existing: Existing suffix absent if not existing. 1924 * User: UserI, UserE, UserA, User suffix absent if not existing. 1925 * 1926 */ 1927 1928 /* 1929 * Install an app on internal flash 1930 */ 1931 @LargeTest 1932 public void testFlagI() throws Exception { 1933 sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true); 1934 } 1935 1936 /* 1937 * Install an app on sdcard. 1938 */ 1939 @LargeTest 1940 public void testFlagE() throws Exception { 1941 // Do not run on devices with emulated external storage. 1942 if (Environment.isExternalStorageEmulated()) { 1943 return; 1944 } 1945 1946 sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true); 1947 } 1948 1949 /* 1950 * Install an app forward-locked. 1951 */ 1952 @LargeTest 1953 public void testFlagF() throws Exception { 1954 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true); 1955 } 1956 1957 /* 1958 * Install an app with both internal and external flags set. should fail 1959 */ 1960 @LargeTest 1961 public void testFlagIE() throws Exception { 1962 installFromRawResource("install.apk", R.raw.install, 1963 PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL, 1964 false, 1965 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1966 PackageInfo.INSTALL_LOCATION_AUTO); 1967 } 1968 1969 /* 1970 * Install an app with both internal and forward-lock flags set. 1971 */ 1972 @LargeTest 1973 public void testFlagIF() throws Exception { 1974 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK 1975 | PackageManager.INSTALL_INTERNAL, true); 1976 } 1977 1978 /* 1979 * Install an app with both external and forward-lock flags set. 1980 */ 1981 @LargeTest 1982 public void testFlagEF() throws Exception { 1983 // Do not run on devices with emulated external storage. 1984 if (Environment.isExternalStorageEmulated()) { 1985 return; 1986 } 1987 1988 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK 1989 | PackageManager.INSTALL_EXTERNAL, true); 1990 } 1991 1992 /* 1993 * Install an app with both internal and external flags set with forward 1994 * lock. Should fail. 1995 */ 1996 @LargeTest 1997 public void testFlagIEF() throws Exception { 1998 installFromRawResource("install.apk", R.raw.install, 1999 PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL | 2000 PackageManager.INSTALL_EXTERNAL, 2001 false, 2002 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 2003 PackageInfo.INSTALL_LOCATION_AUTO); 2004 } 2005 2006 /* 2007 * Install an app with both internal and manifest option set. 2008 * should install on internal. 2009 */ 2010 @LargeTest 2011 public void testFlagIManifestI() throws Exception { 2012 installFromRawResource("install.apk", R.raw.install_loc_internal, 2013 PackageManager.INSTALL_INTERNAL, 2014 true, 2015 false, -1, 2016 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2017 } 2018 /* 2019 * Install an app with both internal and manifest preference for 2020 * preferExternal. Should install on internal. 2021 */ 2022 @LargeTest 2023 public void testFlagIManifestE() throws Exception { 2024 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2025 PackageManager.INSTALL_INTERNAL, 2026 true, 2027 false, -1, 2028 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2029 } 2030 /* 2031 * Install an app with both internal and manifest preference for 2032 * auto. should install internal. 2033 */ 2034 @LargeTest 2035 public void testFlagIManifestA() throws Exception { 2036 installFromRawResource("install.apk", R.raw.install_loc_auto, 2037 PackageManager.INSTALL_INTERNAL, 2038 true, 2039 false, -1, 2040 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2041 } 2042 /* 2043 * Install an app with both external and manifest option set. 2044 * should install externally. 2045 */ 2046 @LargeTest 2047 public void testFlagEManifestI() throws Exception { 2048 // Do not run on devices with emulated external storage. 2049 if (Environment.isExternalStorageEmulated()) { 2050 return; 2051 } 2052 2053 installFromRawResource("install.apk", R.raw.install_loc_internal, 2054 PackageManager.INSTALL_EXTERNAL, 2055 true, 2056 false, -1, 2057 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2058 } 2059 2060 /* 2061 * Install an app with both external and manifest preference for 2062 * preferExternal. Should install externally. 2063 */ 2064 @LargeTest 2065 public void testFlagEManifestE() throws Exception { 2066 // Do not run on devices with emulated external storage. 2067 if (Environment.isExternalStorageEmulated()) { 2068 return; 2069 } 2070 2071 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2072 PackageManager.INSTALL_EXTERNAL, 2073 true, 2074 false, -1, 2075 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2076 } 2077 2078 /* 2079 * Install an app with both external and manifest preference for 2080 * auto. should install on external media. 2081 */ 2082 @LargeTest 2083 public void testFlagEManifestA() throws Exception { 2084 // Do not run on devices with emulated external storage. 2085 if (Environment.isExternalStorageEmulated()) { 2086 return; 2087 } 2088 2089 installFromRawResource("install.apk", R.raw.install_loc_auto, 2090 PackageManager.INSTALL_EXTERNAL, 2091 true, 2092 false, -1, 2093 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2094 } 2095 2096 /* 2097 * Install an app with fwd locked flag set and install location set to 2098 * internal. should install internally. 2099 */ 2100 @LargeTest 2101 public void testFlagFManifestI() throws Exception { 2102 installFromRawResource("install.apk", R.raw.install_loc_internal, 2103 PackageManager.INSTALL_FORWARD_LOCK, 2104 true, 2105 false, -1, 2106 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2107 } 2108 2109 /* 2110 * Install an app with fwd locked flag set and install location set to 2111 * preferExternal. Should install externally. 2112 */ 2113 @LargeTest 2114 public void testFlagFManifestE() throws Exception { 2115 // Do not run on devices with emulated external storage. 2116 if (Environment.isExternalStorageEmulated()) { 2117 return; 2118 } 2119 2120 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2121 PackageManager.INSTALL_FORWARD_LOCK, 2122 true, 2123 false, -1, 2124 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2125 } 2126 2127 /* 2128 * Install an app with fwd locked flag set and install location set to auto. 2129 * should install externally. 2130 */ 2131 @LargeTest 2132 public void testFlagFManifestA() throws Exception { 2133 // Do not run on devices with emulated external storage. 2134 if (Environment.isExternalStorageEmulated()) { 2135 return; 2136 } 2137 2138 installFromRawResource("install.apk", R.raw.install_loc_auto, 2139 PackageManager.INSTALL_FORWARD_LOCK, 2140 true, 2141 false, -1, 2142 PackageInfo.INSTALL_LOCATION_AUTO); 2143 } 2144 2145 /* 2146 * The following test functions verify install location for existing apps. 2147 * ie existing app can be installed internally or externally. If install 2148 * flag is explicitly set it should override current location. If manifest location 2149 * is set, that should over ride current location too. if not the existing install 2150 * location should be honoured. 2151 * testFlagI/E/F/ExistingI/E - 2152 */ 2153 @LargeTest 2154 public void testFlagIExistingI() throws Exception { 2155 int iFlags = PackageManager.INSTALL_INTERNAL; 2156 int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 2157 // First install. 2158 installFromRawResource("install.apk", R.raw.install, 2159 iFlags, 2160 false, 2161 false, -1, 2162 -1); 2163 // Replace now 2164 installFromRawResource("install.apk", R.raw.install, 2165 rFlags, 2166 true, 2167 false, -1, 2168 -1); 2169 } 2170 2171 @LargeTest 2172 public void testFlagIExistingE() throws Exception { 2173 // Do not run on devices with emulated external storage. 2174 if (Environment.isExternalStorageEmulated()) { 2175 return; 2176 } 2177 2178 int iFlags = PackageManager.INSTALL_EXTERNAL; 2179 int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 2180 // First install. 2181 installFromRawResource("install.apk", R.raw.install, 2182 iFlags, 2183 false, 2184 false, -1, 2185 -1); 2186 // Replace now 2187 installFromRawResource("install.apk", R.raw.install, 2188 rFlags, 2189 true, 2190 false, -1, 2191 -1); 2192 } 2193 2194 @LargeTest 2195 public void testFlagEExistingI() throws Exception { 2196 // Do not run on devices with emulated external storage. 2197 if (Environment.isExternalStorageEmulated()) { 2198 return; 2199 } 2200 2201 int iFlags = PackageManager.INSTALL_INTERNAL; 2202 int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 2203 // First install. 2204 installFromRawResource("install.apk", R.raw.install, 2205 iFlags, 2206 false, 2207 false, -1, 2208 -1); 2209 // Replace now 2210 installFromRawResource("install.apk", R.raw.install, 2211 rFlags, 2212 true, 2213 false, -1, 2214 -1); 2215 } 2216 2217 @LargeTest 2218 public void testFlagEExistingE() throws Exception { 2219 // Do not run on devices with emulated external storage. 2220 if (Environment.isExternalStorageEmulated()) { 2221 return; 2222 } 2223 2224 int iFlags = PackageManager.INSTALL_EXTERNAL; 2225 int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 2226 // First install. 2227 installFromRawResource("install.apk", R.raw.install, 2228 iFlags, 2229 false, 2230 false, -1, 2231 -1); 2232 // Replace now 2233 installFromRawResource("install.apk", R.raw.install, 2234 rFlags, 2235 true, 2236 false, -1, 2237 -1); 2238 } 2239 2240 @LargeTest 2241 public void testFlagFExistingI() throws Exception { 2242 int iFlags = PackageManager.INSTALL_INTERNAL; 2243 int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING; 2244 // First install. 2245 installFromRawResource("install.apk", R.raw.install, 2246 iFlags, 2247 false, 2248 false, -1, 2249 -1); 2250 // Replace now 2251 installFromRawResource("install.apk", R.raw.install, 2252 rFlags, 2253 true, 2254 false, -1, 2255 -1); 2256 } 2257 2258 @LargeTest 2259 public void testFlagFExistingE() throws Exception { 2260 // Do not run on devices with emulated external storage. 2261 if (Environment.isExternalStorageEmulated()) { 2262 return; 2263 } 2264 2265 int iFlags = PackageManager.INSTALL_EXTERNAL; 2266 int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING; 2267 // First install. 2268 installFromRawResource("install.apk", R.raw.install, 2269 iFlags, 2270 false, 2271 false, -1, 2272 -1); 2273 // Replace now 2274 installFromRawResource("install.apk", R.raw.install, 2275 rFlags, 2276 true, 2277 false, -1, 2278 -1); 2279 } 2280 2281 /* 2282 * The following set of tests verify the installation of apps with 2283 * install location attribute set to internalOnly, preferExternal and auto. 2284 * The manifest option should dictate the install location. 2285 * public void testManifestI/E/A 2286 * TODO out of memory fall back behaviour. 2287 */ 2288 @LargeTest 2289 public void testManifestI() throws Exception { 2290 installFromRawResource("install.apk", R.raw.install_loc_internal, 2291 0, 2292 true, 2293 false, -1, 2294 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2295 } 2296 2297 @LargeTest 2298 public void testManifestE() throws Exception { 2299 // Do not run on devices with emulated external storage. 2300 if (Environment.isExternalStorageEmulated()) { 2301 return; 2302 } 2303 2304 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2305 0, 2306 true, 2307 false, -1, 2308 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2309 } 2310 2311 @LargeTest 2312 public void testManifestA() throws Exception { 2313 installFromRawResource("install.apk", R.raw.install_loc_auto, 2314 0, 2315 true, 2316 false, -1, 2317 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2318 } 2319 2320 /* 2321 * The following set of tests verify the installation of apps 2322 * with install location attribute set to internalOnly, preferExternal and auto 2323 * for already existing apps. The manifest option should take precedence. 2324 * TODO add out of memory fall back behaviour. 2325 * testManifestI/E/AExistingI/E 2326 */ 2327 @LargeTest 2328 public void testManifestIExistingI() throws Exception { 2329 int iFlags = PackageManager.INSTALL_INTERNAL; 2330 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2331 // First install. 2332 installFromRawResource("install.apk", R.raw.install, 2333 iFlags, 2334 false, 2335 false, -1, 2336 -1); 2337 // Replace now 2338 installFromRawResource("install.apk", R.raw.install_loc_internal, 2339 rFlags, 2340 true, 2341 false, -1, 2342 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2343 } 2344 2345 @LargeTest 2346 public void testManifestIExistingE() throws Exception { 2347 // Do not run on devices with emulated external storage. 2348 if (Environment.isExternalStorageEmulated()) { 2349 return; 2350 } 2351 2352 int iFlags = PackageManager.INSTALL_EXTERNAL; 2353 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2354 // First install. 2355 installFromRawResource("install.apk", R.raw.install, 2356 iFlags, 2357 false, 2358 false, -1, 2359 -1); 2360 // Replace now 2361 installFromRawResource("install.apk", R.raw.install_loc_internal, 2362 rFlags, 2363 true, 2364 false, -1, 2365 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2366 } 2367 2368 @LargeTest 2369 public void testManifestEExistingI() throws Exception { 2370 // Do not run on devices with emulated external storage. 2371 if (Environment.isExternalStorageEmulated()) { 2372 return; 2373 } 2374 2375 int iFlags = PackageManager.INSTALL_INTERNAL; 2376 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2377 // First install. 2378 installFromRawResource("install.apk", R.raw.install, 2379 iFlags, 2380 false, 2381 false, -1, 2382 -1); 2383 // Replace now 2384 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2385 rFlags, 2386 true, 2387 false, -1, 2388 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2389 } 2390 2391 @LargeTest 2392 public void testManifestEExistingE() throws Exception { 2393 // Do not run on devices with emulated external storage. 2394 if (Environment.isExternalStorageEmulated()) { 2395 return; 2396 } 2397 2398 int iFlags = PackageManager.INSTALL_EXTERNAL; 2399 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2400 // First install. 2401 installFromRawResource("install.apk", R.raw.install, 2402 iFlags, 2403 false, 2404 false, -1, 2405 -1); 2406 // Replace now 2407 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 2408 rFlags, 2409 true, 2410 false, -1, 2411 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2412 } 2413 2414 @LargeTest 2415 public void testManifestAExistingI() throws Exception { 2416 int iFlags = PackageManager.INSTALL_INTERNAL; 2417 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2418 // First install. 2419 installFromRawResource("install.apk", R.raw.install, 2420 iFlags, 2421 false, 2422 false, -1, 2423 -1); 2424 // Replace now 2425 installFromRawResource("install.apk", R.raw.install_loc_auto, 2426 rFlags, 2427 true, 2428 false, -1, 2429 PackageInfo.INSTALL_LOCATION_AUTO); 2430 } 2431 2432 @LargeTest 2433 public void testManifestAExistingE() throws Exception { 2434 // Do not run on devices with emulated external storage. 2435 if (Environment.isExternalStorageEmulated()) { 2436 return; 2437 } 2438 2439 int iFlags = PackageManager.INSTALL_EXTERNAL; 2440 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2441 // First install. 2442 installFromRawResource("install.apk", R.raw.install, 2443 iFlags, 2444 false, 2445 false, -1, 2446 -1); 2447 // Replace now 2448 installFromRawResource("install.apk", R.raw.install_loc_auto, 2449 rFlags, 2450 true, 2451 false, -1, 2452 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2453 } 2454 2455 /* 2456 * The following set of tests check install location for existing 2457 * application based on user setting. 2458 */ 2459 private int getExpectedInstallLocation(int userSetting) { 2460 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2461 boolean enable = getUserSettingSetInstallLocation(); 2462 if (enable) { 2463 if (userSetting == PackageHelper.APP_INSTALL_AUTO) { 2464 iloc = PackageInfo.INSTALL_LOCATION_AUTO; 2465 } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) { 2466 iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL; 2467 } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) { 2468 iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY; 2469 } 2470 } 2471 return iloc; 2472 } 2473 2474 private void setExistingXUserX(int userSetting, int iFlags, int iloc) throws Exception { 2475 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2476 // First install. 2477 installFromRawResource("install.apk", R.raw.install, 2478 iFlags, 2479 false, 2480 false, -1, 2481 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2482 int origSetting = getDefaultInstallLoc(); 2483 try { 2484 // Set user setting 2485 setInstallLoc(userSetting); 2486 // Replace now 2487 installFromRawResource("install.apk", R.raw.install, 2488 rFlags, 2489 true, 2490 false, -1, 2491 iloc); 2492 } finally { 2493 setInstallLoc(origSetting); 2494 } 2495 } 2496 @LargeTest 2497 public void testExistingIUserI() throws Exception { 2498 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2499 int iFlags = PackageManager.INSTALL_INTERNAL; 2500 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2501 } 2502 2503 @LargeTest 2504 public void testExistingIUserE() throws Exception { 2505 // Do not run on devices with emulated external storage. 2506 if (Environment.isExternalStorageEmulated()) { 2507 return; 2508 } 2509 2510 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2511 int iFlags = PackageManager.INSTALL_INTERNAL; 2512 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2513 } 2514 2515 @LargeTest 2516 public void testExistingIUserA() throws Exception { 2517 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2518 int iFlags = PackageManager.INSTALL_INTERNAL; 2519 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2520 } 2521 2522 @LargeTest 2523 public void testExistingEUserI() throws Exception { 2524 // Do not run on devices with emulated external storage. 2525 if (Environment.isExternalStorageEmulated()) { 2526 return; 2527 } 2528 2529 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2530 int iFlags = PackageManager.INSTALL_EXTERNAL; 2531 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2532 } 2533 2534 @LargeTest 2535 public void testExistingEUserE() throws Exception { 2536 // Do not run on devices with emulated external storage. 2537 if (Environment.isExternalStorageEmulated()) { 2538 return; 2539 } 2540 2541 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2542 int iFlags = PackageManager.INSTALL_EXTERNAL; 2543 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2544 } 2545 2546 @LargeTest 2547 public void testExistingEUserA() throws Exception { 2548 // Do not run on devices with emulated external storage. 2549 if (Environment.isExternalStorageEmulated()) { 2550 return; 2551 } 2552 2553 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2554 int iFlags = PackageManager.INSTALL_EXTERNAL; 2555 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2556 } 2557 2558 /* 2559 * The following set of tests verify that the user setting defines 2560 * the install location. 2561 * 2562 */ 2563 private boolean getUserSettingSetInstallLocation() { 2564 try { 2565 return Settings.Global.getInt( 2566 mContext.getContentResolver(), Settings.Global.SET_INSTALL_LOCATION) != 0; 2567 } catch (SettingNotFoundException e1) { 2568 } 2569 return false; 2570 } 2571 2572 private void setUserSettingSetInstallLocation(boolean value) { 2573 Settings.Global.putInt(mContext.getContentResolver(), 2574 Settings.Global.SET_INSTALL_LOCATION, value ? 1 : 0); 2575 } 2576 2577 private void setUserX(boolean enable, int userSetting, int iloc) throws Exception { 2578 boolean origUserSetting = getUserSettingSetInstallLocation(); 2579 int origSetting = getDefaultInstallLoc(); 2580 try { 2581 setUserSettingSetInstallLocation(enable); 2582 // Set user setting 2583 setInstallLoc(userSetting); 2584 // Replace now 2585 installFromRawResource("install.apk", R.raw.install, 2586 0, 2587 true, 2588 false, -1, 2589 iloc); 2590 } finally { 2591 // Restore original setting 2592 setUserSettingSetInstallLocation(origUserSetting); 2593 setInstallLoc(origSetting); 2594 } 2595 } 2596 @LargeTest 2597 public void testUserI() throws Exception { 2598 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2599 int iloc = getExpectedInstallLocation(userSetting); 2600 setUserX(true, userSetting, iloc); 2601 } 2602 2603 @LargeTest 2604 public void testUserE() throws Exception { 2605 // Do not run on devices with emulated external storage. 2606 if (Environment.isExternalStorageEmulated()) { 2607 return; 2608 } 2609 2610 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2611 int iloc = getExpectedInstallLocation(userSetting); 2612 setUserX(true, userSetting, iloc); 2613 } 2614 2615 @LargeTest 2616 public void testUserA() throws Exception { 2617 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2618 int iloc = getExpectedInstallLocation(userSetting); 2619 setUserX(true, userSetting, iloc); 2620 } 2621 2622 /* 2623 * The following set of tests turn on/off the basic 2624 * user setting for turning on install location. 2625 */ 2626 @LargeTest 2627 public void testUserPrefOffUserI() throws Exception { 2628 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2629 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2630 setUserX(false, userSetting, iloc); 2631 } 2632 2633 @LargeTest 2634 public void testUserPrefOffUserE() throws Exception { 2635 // Do not run on devices with emulated external storage. 2636 if (Environment.isExternalStorageEmulated()) { 2637 return; 2638 } 2639 2640 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2641 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2642 setUserX(false, userSetting, iloc); 2643 } 2644 2645 @LargeTest 2646 public void testUserPrefOffA() throws Exception { 2647 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2648 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2649 setUserX(false, userSetting, iloc); 2650 } 2651 2652 static final String BASE_PERMISSIONS_DEFINED[] = new String[] { 2653 PERM_PACKAGE, "com.android.unit_tests.install_decl_perm", 2654 PERM_DEFINED, 2655 "com.android.frameworks.coretests.NORMAL", 2656 "com.android.frameworks.coretests.DANGEROUS", 2657 "com.android.frameworks.coretests.SIGNATURE", 2658 }; 2659 2660 static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] { 2661 PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm", 2662 PERM_UNDEFINED, 2663 "com.android.frameworks.coretests.NORMAL", 2664 "com.android.frameworks.coretests.DANGEROUS", 2665 "com.android.frameworks.coretests.SIGNATURE", 2666 }; 2667 2668 static final String BASE_PERMISSIONS_USED[] = new String[] { 2669 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2670 PERM_USED, 2671 "com.android.frameworks.coretests.NORMAL", 2672 "com.android.frameworks.coretests.DANGEROUS", 2673 "com.android.frameworks.coretests.SIGNATURE", 2674 }; 2675 2676 static final String BASE_PERMISSIONS_NOTUSED[] = new String[] { 2677 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2678 PERM_NOTUSED, 2679 "com.android.frameworks.coretests.NORMAL", 2680 "com.android.frameworks.coretests.DANGEROUS", 2681 "com.android.frameworks.coretests.SIGNATURE", 2682 }; 2683 2684 static final String BASE_PERMISSIONS_SIGUSED[] = new String[] { 2685 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2686 PERM_USED, 2687 "com.android.frameworks.coretests.SIGNATURE", 2688 PERM_NOTUSED, 2689 "com.android.frameworks.coretests.NORMAL", 2690 "com.android.frameworks.coretests.DANGEROUS", 2691 }; 2692 2693 /* 2694 * Ensure that permissions are properly declared. 2695 */ 2696 @LargeTest 2697 public void testInstallDeclaresPermissions() throws Exception { 2698 InstallParams ip = null; 2699 InstallParams ip2 = null; 2700 try { 2701 // **: Upon installing a package, are its declared permissions published? 2702 2703 int iFlags = PackageManager.INSTALL_INTERNAL; 2704 int iApk = R.raw.install_decl_perm; 2705 ip = installFromRawResource("install.apk", iApk, 2706 iFlags, false, 2707 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2708 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2709 assertPermissions(BASE_PERMISSIONS_DEFINED); 2710 2711 // **: Upon installing package, are its permissions granted? 2712 2713 int i2Flags = PackageManager.INSTALL_INTERNAL; 2714 int i2Apk = R.raw.install_use_perm_good; 2715 ip2 = installFromRawResource("install2.apk", i2Apk, 2716 i2Flags, false, 2717 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2718 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2719 assertPermissions(BASE_PERMISSIONS_USED); 2720 2721 // **: Upon removing but not deleting, are permissions retained? 2722 2723 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 2724 2725 try { 2726 invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver); 2727 } catch (Exception e) { 2728 failStr(e); 2729 } 2730 assertPermissions(BASE_PERMISSIONS_DEFINED); 2731 assertPermissions(BASE_PERMISSIONS_USED); 2732 2733 // **: Upon re-installing, are permissions retained? 2734 2735 ip = installFromRawResource("install.apk", iApk, 2736 iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false, 2737 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2738 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2739 assertPermissions(BASE_PERMISSIONS_DEFINED); 2740 assertPermissions(BASE_PERMISSIONS_USED); 2741 2742 // **: Upon deleting package, are all permissions removed? 2743 2744 try { 2745 invokeDeletePackage(ip.pkg.packageName, 0, receiver); 2746 ip = null; 2747 } catch (Exception e) { 2748 failStr(e); 2749 } 2750 assertPermissions(BASE_PERMISSIONS_UNDEFINED); 2751 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2752 2753 // **: Delete package using permissions; nothing to check here. 2754 2755 GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName); 2756 try { 2757 invokeDeletePackage(ip2.pkg.packageName, 0, receiver); 2758 ip2 = null; 2759 } catch (Exception e) { 2760 failStr(e); 2761 } 2762 2763 // **: Re-install package using permissions; no permissions can be granted. 2764 2765 ip2 = installFromRawResource("install2.apk", i2Apk, 2766 i2Flags, false, 2767 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2768 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2769 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2770 2771 // **: Upon installing declaring package, are sig permissions granted 2772 // to other apps (but not other perms)? 2773 2774 ip = installFromRawResource("install.apk", iApk, 2775 iFlags, false, 2776 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2777 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2778 assertPermissions(BASE_PERMISSIONS_DEFINED); 2779 assertPermissions(BASE_PERMISSIONS_SIGUSED); 2780 2781 // **: Re-install package using permissions; are all permissions granted? 2782 2783 ip2 = installFromRawResource("install2.apk", i2Apk, 2784 i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false, 2785 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2786 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2787 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2788 2789 // **: Upon deleting package, are all permissions removed? 2790 2791 try { 2792 invokeDeletePackage(ip.pkg.packageName, 0, receiver); 2793 ip = null; 2794 } catch (Exception e) { 2795 failStr(e); 2796 } 2797 assertPermissions(BASE_PERMISSIONS_UNDEFINED); 2798 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2799 2800 // **: Delete package using permissions; nothing to check here. 2801 2802 try { 2803 invokeDeletePackage(ip2.pkg.packageName, 0, receiver); 2804 ip2 = null; 2805 } catch (Exception e) { 2806 failStr(e); 2807 } 2808 2809 } finally { 2810 if (ip2 != null) { 2811 cleanUpInstall(ip2); 2812 } 2813 if (ip != null) { 2814 cleanUpInstall(ip); 2815 } 2816 } 2817 } 2818 2819 /* 2820 * Ensure that permissions are properly declared. 2821 */ 2822 @LargeTest 2823 public void testInstallOnSdPermissionsUnmount() throws Exception { 2824 InstallParams ip = null; 2825 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2826 try { 2827 // **: Upon installing a package, are its declared permissions published? 2828 int iFlags = PackageManager.INSTALL_INTERNAL; 2829 int iApk = R.raw.install_decl_perm; 2830 ip = installFromRawResource("install.apk", iApk, 2831 iFlags, false, 2832 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2833 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2834 assertPermissions(BASE_PERMISSIONS_DEFINED); 2835 // Unmount media here 2836 assertTrue(unmountMedia()); 2837 // Mount media again 2838 mountMedia(); 2839 //Check permissions now 2840 assertPermissions(BASE_PERMISSIONS_DEFINED); 2841 } finally { 2842 if (ip != null) { 2843 cleanUpInstall(ip); 2844 } 2845 } 2846 } 2847 2848 /* This test creates a stale container via MountService and then installs 2849 * a package and verifies that the stale container is cleaned up and install 2850 * is successful. 2851 * Please note that this test is very closely tied to the framework's 2852 * naming convention for secure containers. 2853 */ 2854 @LargeTest 2855 public void testInstallSdcardStaleContainer() throws Exception { 2856 // Do not run on devices with emulated external storage. 2857 if (Environment.isExternalStorageEmulated()) { 2858 return; 2859 } 2860 2861 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2862 try { 2863 // Mount media first 2864 mountMedia(); 2865 String outFileName = "install.apk"; 2866 int rawResId = R.raw.install; 2867 PackageManager pm = mContext.getPackageManager(); 2868 File filesDir = mContext.getFilesDir(); 2869 File outFile = new File(filesDir, outFileName); 2870 Uri packageURI = getInstallablePackage(rawResId, outFile); 2871 PackageParser.Package pkg = parsePackage(packageURI); 2872 assertNotNull(pkg); 2873 // Install an app on sdcard. 2874 installFromRawResource(outFileName, rawResId, 2875 PackageManager.INSTALL_EXTERNAL, false, 2876 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2877 // Unmount sdcard 2878 unmountMedia(); 2879 // Delete the app on sdcard to leave a stale container on sdcard. 2880 GenericReceiver receiver = new DeleteReceiver(pkg.packageName); 2881 assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver)); 2882 mountMedia(); 2883 // Reinstall the app and make sure it gets installed. 2884 installFromRawResource(outFileName, rawResId, 2885 PackageManager.INSTALL_EXTERNAL, true, 2886 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2887 } catch (Exception e) { 2888 failStr(e.getMessage()); 2889 } finally { 2890 if (origMediaState) { 2891 mountMedia(); 2892 } else { 2893 unmountMedia(); 2894 } 2895 2896 } 2897 } 2898 2899 /* This test installs an application on sdcard and unmounts media. 2900 * The app is then re-installed on internal storage. The sdcard is mounted 2901 * and verified that the re-installation on internal storage takes precedence. 2902 */ 2903 @LargeTest 2904 public void testInstallSdcardStaleContainerReinstall() throws Exception { 2905 // Do not run on devices with emulated external storage. 2906 if (Environment.isExternalStorageEmulated()) { 2907 return; 2908 } 2909 2910 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2911 try { 2912 // Mount media first 2913 mountMedia(); 2914 String outFileName = "install.apk"; 2915 int rawResId = R.raw.install; 2916 PackageManager pm = mContext.getPackageManager(); 2917 File filesDir = mContext.getFilesDir(); 2918 File outFile = new File(filesDir, outFileName); 2919 Uri packageURI = getInstallablePackage(rawResId, outFile); 2920 PackageParser.Package pkg = parsePackage(packageURI); 2921 assertNotNull(pkg); 2922 // Install an app on sdcard. 2923 installFromRawResource(outFileName, rawResId, 2924 PackageManager.INSTALL_EXTERNAL, false, 2925 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2926 // Unmount sdcard 2927 unmountMedia(); 2928 // Reinstall the app and make sure it gets installed on internal storage. 2929 installFromRawResource(outFileName, rawResId, 2930 PackageManager.INSTALL_REPLACE_EXISTING, false, 2931 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2932 mountMedia(); 2933 // Verify that the app installed is on internal storage. 2934 assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2935 } catch (Exception e) { 2936 failStr(e.getMessage()); 2937 } finally { 2938 if (origMediaState) { 2939 mountMedia(); 2940 } else { 2941 unmountMedia(); 2942 } 2943 } 2944 } 2945 2946 /* 2947 * The following series of tests are related to upgrading apps with 2948 * different certificates. 2949 */ 2950 private int APP1_UNSIGNED = R.raw.install_app1_unsigned; 2951 2952 private int APP1_CERT1 = R.raw.install_app1_cert1; 2953 2954 private int APP1_CERT2 = R.raw.install_app1_cert2; 2955 2956 private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2; 2957 2958 private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4; 2959 2960 private int APP1_CERT3 = R.raw.install_app1_cert3; 2961 2962 private int APP2_UNSIGNED = R.raw.install_app2_unsigned; 2963 2964 private int APP2_CERT1 = R.raw.install_app2_cert1; 2965 2966 private int APP2_CERT2 = R.raw.install_app2_cert2; 2967 2968 private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2; 2969 2970 private int APP2_CERT3 = R.raw.install_app2_cert3; 2971 2972 private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, 2973 int retCode) throws Exception { 2974 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2975 String apk1Name = "install1.apk"; 2976 String apk2Name = "install2.apk"; 2977 PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1); 2978 try { 2979 InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false, 2980 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2981 installFromRawResource(apk2Name, apk2, rFlags, false, 2982 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2983 return ip; 2984 } catch (Exception e) { 2985 failStr(e.getMessage()); 2986 } finally { 2987 if (cleanUp) { 2988 cleanUpInstall(pkg1.packageName); 2989 } 2990 } 2991 return null; 2992 } 2993 2994 /* 2995 * Test that an app signed with two certificates can be upgraded by the 2996 * same app signed with two certificates. 2997 */ 2998 @LargeTest 2999 public void testReplaceMatchAllCerts() throws Exception { 3000 replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1); 3001 } 3002 3003 /* 3004 * Test that an app signed with two certificates cannot be upgraded 3005 * by an app signed with a different certificate. 3006 */ 3007 @LargeTest 3008 public void testReplaceMatchNoCerts1() throws Exception { 3009 replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true, 3010 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3011 } 3012 3013 /* 3014 * Test that an app signed with two certificates cannot be upgraded 3015 * by an app signed with a different certificate. 3016 */ 3017 @LargeTest 3018 public void testReplaceMatchNoCerts2() throws Exception { 3019 replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true, 3020 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3021 } 3022 3023 /* 3024 * Test that an app signed with two certificates cannot be upgraded by 3025 * an app signed with a subset of initial certificates. 3026 */ 3027 @LargeTest 3028 public void testReplaceMatchSomeCerts1() throws Exception { 3029 replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true, 3030 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3031 } 3032 3033 /* 3034 * Test that an app signed with two certificates cannot be upgraded by 3035 * an app signed with the last certificate. 3036 */ 3037 @LargeTest 3038 public void testReplaceMatchSomeCerts2() throws Exception { 3039 replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true, 3040 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3041 } 3042 3043 /* 3044 * Test that an app signed with a certificate can be upgraded by app 3045 * signed with a superset of certificates. 3046 */ 3047 @LargeTest 3048 public void testReplaceMatchMoreCerts() throws Exception { 3049 replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true, 3050 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3051 } 3052 3053 /* 3054 * Test that an app signed with a certificate can be upgraded by app 3055 * signed with a superset of certificates. Then verify that the an app 3056 * signed with the original set of certs cannot upgrade the new one. 3057 */ 3058 @LargeTest 3059 public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception { 3060 InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true, 3061 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3062 try { 3063 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 3064 installFromRawResource("install.apk", APP1_CERT1, rFlags, false, 3065 false, -1, 3066 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3067 } catch (Exception e) { 3068 failStr(e.getMessage()); 3069 } finally { 3070 if (ip != null) { 3071 cleanUpInstall(ip); 3072 } 3073 } 3074 } 3075 3076 /** 3077 * The following tests are related to testing KeySets-based key rotation 3078 */ 3079 /* 3080 * Check if an apk which does not specify an upgrade-keyset may be upgraded 3081 * by an apk which does 3082 */ 3083 public void testNoKSToUpgradeKS() throws Exception { 3084 replaceCerts(R.raw.keyset_sa_unone, R.raw.keyset_sa_ua, true, false, -1); 3085 } 3086 3087 /* 3088 * Check if an apk which does specify an upgrade-keyset may be downgraded to 3089 * an apk which does not 3090 */ 3091 public void testUpgradeKSToNoKS() throws Exception { 3092 replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_unone, true, false, -1); 3093 } 3094 3095 /* 3096 * Check if an apk signed by a key other than the upgrade keyset can update 3097 * an app 3098 */ 3099 public void testUpgradeKSWithWrongKey() throws Exception { 3100 replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true, 3101 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3102 } 3103 3104 /* 3105 * Check if an apk signed by its signing key, which is not an upgrade key, 3106 * can upgrade an app. 3107 */ 3108 public void testUpgradeKSWithWrongSigningKey() throws Exception { 3109 replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true, 3110 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3111 } 3112 3113 /* 3114 * Check if an apk signed by its upgrade key, which is not its signing key, 3115 * can upgrade an app. 3116 */ 3117 public void testUpgradeKSWithUpgradeKey() throws Exception { 3118 replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sb_ub, true, false, -1); 3119 } 3120 /* 3121 * Check if an apk signed by its upgrade key, which is its signing key, can 3122 * upgrade an app. 3123 */ 3124 public void testUpgradeKSWithSigningUpgradeKey() throws Exception { 3125 replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_ua, true, false, -1); 3126 } 3127 3128 /* 3129 * Check if an apk signed by multiple keys, one of which is its upgrade key, 3130 * can upgrade an app. 3131 */ 3132 public void testMultipleUpgradeKSWithUpgradeKey() throws Exception { 3133 replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sab_ua, true, false, -1); 3134 } 3135 3136 /* 3137 * Check if an apk signed by multiple keys, one of which is its signing key, 3138 * but none of which is an upgrade key, can upgrade an app. 3139 */ 3140 public void testMultipleUpgradeKSWithSigningKey() throws Exception { 3141 replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true, 3142 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 3143 } 3144 3145 /* 3146 * Check if an apk which defines multiple (two) upgrade keysets is 3147 * upgrade-able by either. 3148 */ 3149 public void testUpgradeKSWithMultipleUpgradeKeySets() throws Exception { 3150 replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sa_ua, true, false, -1); 3151 replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sb_ub, true, false, -1); 3152 } 3153 3154 /* 3155 * Check if an apk's sigs are changed after upgrading with a non-signing 3156 * key. 3157 * 3158 * TODO: consider checking against hard-coded Signatures in the Sig-tests 3159 */ 3160 public void testSigChangeAfterUpgrade() throws Exception { 3161 // install original apk and grab sigs 3162 installFromRawResource("tmp.apk", R.raw.keyset_sa_ub, 3163 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3164 PackageManager pm = getPm(); 3165 String pkgName = "com.android.frameworks.coretests.keysets"; 3166 PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3167 assertTrue("Package should only have one signature, sig A", 3168 pi.signatures.length == 1); 3169 String sigBefore = pi.signatures[0].toCharsString(); 3170 // install apk signed by different upgrade KeySet 3171 installFromRawResource("tmp2.apk", R.raw.keyset_sb_ub, 3172 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3173 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3174 pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3175 assertTrue("Package should only have one signature, sig B", 3176 pi.signatures.length == 1); 3177 String sigAfter = pi.signatures[0].toCharsString(); 3178 assertFalse("Package signatures did not change after upgrade!", 3179 sigBefore.equals(sigAfter)); 3180 cleanUpInstall(pkgName); 3181 } 3182 3183 /* 3184 * Check if an apk's sig is the same after upgrading with a signing 3185 * key. 3186 */ 3187 public void testSigSameAfterUpgrade() throws Exception { 3188 // install original apk and grab sigs 3189 installFromRawResource("tmp.apk", R.raw.keyset_sa_ua, 3190 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3191 PackageManager pm = getPm(); 3192 String pkgName = "com.android.frameworks.coretests.keysets"; 3193 PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3194 assertTrue("Package should only have one signature, sig A", 3195 pi.signatures.length == 1); 3196 String sigBefore = pi.signatures[0].toCharsString(); 3197 // install apk signed by same upgrade KeySet 3198 installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua, 3199 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3200 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3201 pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3202 assertTrue("Package should only have one signature, sig A", 3203 pi.signatures.length == 1); 3204 String sigAfter = pi.signatures[0].toCharsString(); 3205 assertTrue("Package signatures changed after upgrade!", 3206 sigBefore.equals(sigAfter)); 3207 cleanUpInstall(pkgName); 3208 } 3209 3210 /* 3211 * Check if an apk's sigs are the same after upgrading with an app with 3212 * a subset of the original signing keys. 3213 */ 3214 public void testSigRemovedAfterUpgrade() throws Exception { 3215 // install original apk and grab sigs 3216 installFromRawResource("tmp.apk", R.raw.keyset_sab_ua, 3217 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3218 PackageManager pm = getPm(); 3219 String pkgName = "com.android.frameworks.coretests.keysets"; 3220 PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3221 assertTrue("Package should have two signatures, sig A and sig B", 3222 pi.signatures.length == 2); 3223 Set<String> sigsBefore = new HashSet<String>(); 3224 for (int i = 0; i < pi.signatures.length; i++) { 3225 sigsBefore.add(pi.signatures[i].toCharsString()); 3226 } 3227 // install apk signed subset upgrade KeySet 3228 installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua, 3229 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3230 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3231 pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3232 assertTrue("Package should only have one signature, sig A", 3233 pi.signatures.length == 1); 3234 String sigAfter = pi.signatures[0].toCharsString(); 3235 assertTrue("Original package signatures did not contain new sig", 3236 sigsBefore.contains(sigAfter)); 3237 cleanUpInstall(pkgName); 3238 } 3239 3240 /* 3241 * Check if an apk's sigs are added to after upgrading with an app with 3242 * a superset of the original signing keys. 3243 */ 3244 public void testSigAddedAfterUpgrade() throws Exception { 3245 // install original apk and grab sigs 3246 installFromRawResource("tmp.apk", R.raw.keyset_sa_ua, 3247 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3248 PackageManager pm = getPm(); 3249 String pkgName = "com.android.frameworks.coretests.keysets"; 3250 PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3251 assertTrue("Package should only have one signature, sig A", 3252 pi.signatures.length == 1); 3253 String sigBefore = pi.signatures[0].toCharsString(); 3254 // install apk signed subset upgrade KeySet 3255 installFromRawResource("tmp2.apk", R.raw.keyset_sab_ua, 3256 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3257 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3258 pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); 3259 assertTrue("Package should have two signatures, sig A and sig B", 3260 pi.signatures.length == 2); 3261 Set<String> sigsAfter = new HashSet<String>(); 3262 for (int i = 0; i < pi.signatures.length; i++) { 3263 sigsAfter.add(pi.signatures[i].toCharsString()); 3264 } 3265 assertTrue("Package signatures did not change after upgrade!", 3266 sigsAfter.contains(sigBefore)); 3267 cleanUpInstall(pkgName); 3268 } 3269 3270 /* 3271 * Check if an apk gains signature-level permission after changing to the a 3272 * new signature, for which a permission should be granted. 3273 */ 3274 public void testUpgradeSigPermGained() throws Exception { 3275 // install apk which defines permission 3276 installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone, 3277 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3278 // install apk which uses permission but does not have sig 3279 installFromRawResource("permUse.apk", R.raw.keyset_permuse_sb_ua_ub, 3280 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3281 // verify that package does not have perm before 3282 PackageManager pm = getPm(); 3283 String permPkgName = "com.android.frameworks.coretests.keysets_permdef"; 3284 String pkgName = "com.android.frameworks.coretests.keysets"; 3285 String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm"; 3286 assertFalse("keyset permission granted to app without same signature!", 3287 pm.checkPermission(permName, pkgName) 3288 == PackageManager.PERMISSION_GRANTED); 3289 // upgrade to apk with perm signature 3290 installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sa_ua_ub, 3291 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3292 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3293 assertTrue("keyset permission not granted to app after upgrade to same sig", 3294 pm.checkPermission(permName, pkgName) 3295 == PackageManager.PERMISSION_GRANTED); 3296 cleanUpInstall(permPkgName); 3297 cleanUpInstall(pkgName); 3298 } 3299 3300 /* 3301 * Check if an apk loses signature-level permission after changing to the a 3302 * new signature, from one which a permission should be granted. 3303 */ 3304 public void testUpgradeSigPermLost() throws Exception { 3305 // install apk which defines permission 3306 installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone, 3307 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3308 // install apk which uses permission, signed by same sig 3309 installFromRawResource("permUse.apk", R.raw.keyset_permuse_sa_ua_ub, 3310 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3311 // verify that package does not have perm before 3312 PackageManager pm = getPm(); 3313 String permPkgName = "com.android.frameworks.coretests.keysets_permdef"; 3314 String pkgName = "com.android.frameworks.coretests.keysets"; 3315 String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm"; 3316 assertTrue("keyset permission not granted to app with same sig", 3317 pm.checkPermission(permName, pkgName) 3318 == PackageManager.PERMISSION_GRANTED); 3319 // upgrade to apk without perm signature 3320 installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sb_ua_ub, 3321 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1, 3322 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3323 3324 assertFalse("keyset permission not revoked from app which upgraded to a " 3325 + "different signature", 3326 pm.checkPermission(permName, pkgName) 3327 == PackageManager.PERMISSION_GRANTED); 3328 cleanUpInstall(permPkgName); 3329 cleanUpInstall(pkgName); 3330 } 3331 3332 /** 3333 * The following tests are related to testing KeySets-based API 3334 */ 3335 3336 /* 3337 * testGetSigningKeySetNull - ensure getSigningKeySet() returns null on null 3338 * input and when calling a package other than that which made the call. 3339 */ 3340 public void testGetSigningKeySet() throws Exception { 3341 PackageManager pm = getPm(); 3342 String mPkgName = mContext.getPackageName(); 3343 String otherPkgName = "com.android.frameworks.coretests.keysets_api"; 3344 KeySet ks; 3345 try { 3346 ks = pm.getSigningKeySet(null); 3347 assertTrue(false); // should have thrown 3348 } catch (NullPointerException e) { 3349 } 3350 try { 3351 ks = pm.getSigningKeySet("keysets.test.bogus.package"); 3352 assertTrue(false); // should have thrown 3353 } catch (IllegalArgumentException e) { 3354 } 3355 installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api, 3356 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3357 try { 3358 ks = pm.getSigningKeySet(otherPkgName); 3359 assertTrue(false); // should have thrown 3360 } catch (SecurityException e) { 3361 } 3362 cleanUpInstall(otherPkgName); 3363 ks = pm.getSigningKeySet(mContext.getPackageName()); 3364 assertNotNull(ks); 3365 } 3366 3367 /* 3368 * testGetKeySetByAlias - same as getSigningKeySet, but for keysets defined 3369 * by this package. 3370 */ 3371 public void testGetKeySetByAlias() throws Exception { 3372 PackageManager pm = getPm(); 3373 String mPkgName = mContext.getPackageName(); 3374 String otherPkgName = "com.android.frameworks.coretests.keysets_api"; 3375 KeySet ks; 3376 try { 3377 ks = pm.getKeySetByAlias(null, null); 3378 assertTrue(false); // should have thrown 3379 } catch (NullPointerException e) { 3380 } 3381 try { 3382 ks = pm.getKeySetByAlias(null, "keysetBogus"); 3383 assertTrue(false); // should have thrown 3384 } catch (NullPointerException e) { 3385 } 3386 try { 3387 ks = pm.getKeySetByAlias("keysets.test.bogus.package", null); 3388 assertTrue(false); // should have thrown 3389 } catch (NullPointerException e) { 3390 } 3391 try { 3392 ks = pm.getKeySetByAlias("keysets.test.bogus.package", "A"); 3393 assertTrue(false); // should have thrown 3394 } catch(IllegalArgumentException e) { 3395 } 3396 try { 3397 ks = pm.getKeySetByAlias(mPkgName, "keysetBogus"); 3398 assertTrue(false); // should have thrown 3399 } catch(IllegalArgumentException e) { 3400 } 3401 installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api, 3402 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3403 try { 3404 ks = pm.getKeySetByAlias(otherPkgName, "A"); 3405 assertTrue(false); // should have thrown 3406 } catch (SecurityException e) { 3407 } 3408 cleanUpInstall(otherPkgName); 3409 ks = pm.getKeySetByAlias(mPkgName, "A"); 3410 assertNotNull(ks); 3411 } 3412 3413 public void testIsSignedBy() throws Exception { 3414 PackageManager pm = getPm(); 3415 String mPkgName = mContext.getPackageName(); 3416 String otherPkgName = "com.android.frameworks.coretests.keysets_api"; 3417 KeySet mSigningKS = pm.getSigningKeySet(mPkgName); 3418 KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A"); 3419 3420 try { 3421 assertFalse(pm.isSignedBy(null, null)); 3422 assertTrue(false); // should have thrown 3423 } catch (NullPointerException e) { 3424 } 3425 try { 3426 assertFalse(pm.isSignedBy(null, mSigningKS)); 3427 assertTrue(false); // should have thrown 3428 } catch (NullPointerException e) { 3429 } 3430 try { 3431 assertFalse(pm.isSignedBy(mPkgName, null)); 3432 assertTrue(false); // should have thrown 3433 } catch (NullPointerException e) { 3434 } 3435 try { 3436 assertFalse(pm.isSignedBy("keysets.test.bogus.package", mDefinedKS)); 3437 } catch(IllegalArgumentException e) { 3438 } 3439 assertFalse(pm.isSignedBy(mPkgName, mDefinedKS)); 3440 assertFalse(pm.isSignedBy(mPkgName, new KeySet(new Binder()))); 3441 assertTrue(pm.isSignedBy(mPkgName, mSigningKS)); 3442 3443 installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api, 3444 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3445 assertFalse(pm.isSignedBy(otherPkgName, mDefinedKS)); 3446 assertTrue(pm.isSignedBy(otherPkgName, mSigningKS)); 3447 cleanUpInstall(otherPkgName); 3448 3449 installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api, 3450 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3451 assertTrue(pm.isSignedBy(otherPkgName, mDefinedKS)); 3452 assertTrue(pm.isSignedBy(otherPkgName, mSigningKS)); 3453 cleanUpInstall(otherPkgName); 3454 } 3455 3456 public void testIsSignedByExactly() throws Exception { 3457 PackageManager pm = getPm(); 3458 String mPkgName = mContext.getPackageName(); 3459 String otherPkgName = "com.android.frameworks.coretests.keysets_api"; 3460 KeySet mSigningKS = pm.getSigningKeySet(mPkgName); 3461 KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A"); 3462 try { 3463 assertFalse(pm.isSignedBy(null, null)); 3464 assertTrue(false); // should have thrown 3465 } catch (NullPointerException e) { 3466 } 3467 try { 3468 assertFalse(pm.isSignedBy(null, mSigningKS)); 3469 assertTrue(false); // should have thrown 3470 } catch (NullPointerException e) { 3471 } 3472 try { 3473 assertFalse(pm.isSignedBy(mPkgName, null)); 3474 assertTrue(false); // should have thrown 3475 } catch (NullPointerException e) { 3476 } 3477 try { 3478 assertFalse(pm.isSignedByExactly("keysets.test.bogus.package", mDefinedKS)); 3479 } catch(IllegalArgumentException e) { 3480 } 3481 assertFalse(pm.isSignedByExactly(mPkgName, mDefinedKS)); 3482 assertFalse(pm.isSignedByExactly(mPkgName, new KeySet(new Binder()))); 3483 assertTrue(pm.isSignedByExactly(mPkgName, mSigningKS)); 3484 3485 installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api, 3486 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3487 assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS)); 3488 assertTrue(pm.isSignedByExactly(otherPkgName, mSigningKS)); 3489 cleanUpInstall(otherPkgName); 3490 3491 installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api, 3492 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3493 assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS)); 3494 assertFalse(pm.isSignedByExactly(otherPkgName, mSigningKS)); 3495 cleanUpInstall(otherPkgName); 3496 } 3497 3498 3499 3500 /** 3501 * The following tests are related to testing the checkSignatures api. 3502 */ 3503 private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception { 3504 checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult); 3505 } 3506 3507 @LargeTest 3508 public void testCheckSignaturesAllMatch() throws Exception { 3509 int apk1 = APP1_CERT1_CERT2; 3510 int apk2 = APP2_CERT1_CERT2; 3511 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 3512 } 3513 3514 @LargeTest 3515 public void testCheckSignaturesNoMatch() throws Exception { 3516 int apk1 = APP1_CERT1; 3517 int apk2 = APP2_CERT2; 3518 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 3519 } 3520 3521 @LargeTest 3522 public void testCheckSignaturesSomeMatch1() throws Exception { 3523 int apk1 = APP1_CERT1_CERT2; 3524 int apk2 = APP2_CERT1; 3525 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 3526 } 3527 3528 @LargeTest 3529 public void testCheckSignaturesSomeMatch2() throws Exception { 3530 int apk1 = APP1_CERT1_CERT2; 3531 int apk2 = APP2_CERT2; 3532 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 3533 } 3534 3535 @LargeTest 3536 public void testCheckSignaturesMoreMatch() throws Exception { 3537 int apk1 = APP1_CERT1; 3538 int apk2 = APP2_CERT1_CERT2; 3539 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 3540 } 3541 3542 @LargeTest 3543 public void testCheckSignaturesUnknown() throws Exception { 3544 int apk1 = APP1_CERT1_CERT2; 3545 int apk2 = APP2_CERT1_CERT2; 3546 String apk1Name = "install1.apk"; 3547 String apk2Name = "install2.apk"; 3548 InstallParams ip1 = null; 3549 3550 try { 3551 ip1 = installFromRawResource(apk1Name, apk1, 0, false, 3552 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3553 PackageManager pm = mContext.getPackageManager(); 3554 // Delete app2 3555 File filesDir = mContext.getFilesDir(); 3556 File outFile = new File(filesDir, apk2Name); 3557 int rawResId = apk2; 3558 Uri packageURI = getInstallablePackage(rawResId, outFile); 3559 PackageParser.Package pkg = parsePackage(packageURI); 3560 getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS); 3561 // Check signatures now 3562 int match = mContext.getPackageManager().checkSignatures( 3563 ip1.pkg.packageName, pkg.packageName); 3564 assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match); 3565 } finally { 3566 if (ip1 != null) { 3567 cleanUpInstall(ip1); 3568 } 3569 } 3570 } 3571 3572 @LargeTest 3573 public void testInstallNoCertificates() throws Exception { 3574 int apk1 = APP1_UNSIGNED; 3575 String apk1Name = "install1.apk"; 3576 InstallParams ip1 = null; 3577 3578 try { 3579 installFromRawResource(apk1Name, apk1, 0, false, 3580 true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES, 3581 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3582 } finally { 3583 } 3584 } 3585 3586 /* 3587 * The following tests are related to apps using shared uids signed with 3588 * different certs. 3589 */ 3590 private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned; 3591 3592 private int SHARED1_CERT1 = R.raw.install_shared1_cert1; 3593 3594 private int SHARED1_CERT2 = R.raw.install_shared1_cert2; 3595 3596 private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2; 3597 3598 private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned; 3599 3600 private int SHARED2_CERT1 = R.raw.install_shared2_cert1; 3601 3602 private int SHARED2_CERT2 = R.raw.install_shared2_cert2; 3603 3604 private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2; 3605 3606 private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, 3607 int retCode, int expMatchResult) throws Exception { 3608 String apk1Name = "install1.apk"; 3609 String apk2Name = "install2.apk"; 3610 PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1); 3611 PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2); 3612 3613 try { 3614 // Clean up before testing first. 3615 cleanUpInstall(pkg1.packageName); 3616 cleanUpInstall(pkg2.packageName); 3617 installFromRawResource(apk1Name, apk1, 0, false, false, -1, 3618 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3619 if (fail) { 3620 installFromRawResource(apk2Name, apk2, 0, false, true, retCode, 3621 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3622 } else { 3623 installFromRawResource(apk2Name, apk2, 0, false, false, -1, 3624 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3625 int match = mContext.getPackageManager().checkSignatures(pkg1.packageName, 3626 pkg2.packageName); 3627 assertEquals(expMatchResult, match); 3628 } 3629 } finally { 3630 if (cleanUp) { 3631 cleanUpInstall(pkg1.packageName); 3632 cleanUpInstall(pkg2.packageName); 3633 } 3634 } 3635 } 3636 3637 @LargeTest 3638 public void testCheckSignaturesSharedAllMatch() throws Exception { 3639 int apk1 = SHARED1_CERT1_CERT2; 3640 int apk2 = SHARED2_CERT1_CERT2; 3641 boolean fail = false; 3642 int retCode = -1; 3643 int expMatchResult = PackageManager.SIGNATURE_MATCH; 3644 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 3645 } 3646 3647 @LargeTest 3648 public void testCheckSignaturesSharedNoMatch() throws Exception { 3649 int apk1 = SHARED1_CERT1; 3650 int apk2 = SHARED2_CERT2; 3651 boolean fail = true; 3652 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 3653 int expMatchResult = -1; 3654 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 3655 } 3656 3657 /* 3658 * Test that an app signed with cert1 and cert2 cannot be replaced when 3659 * signed with cert1 alone. 3660 */ 3661 @LargeTest 3662 public void testCheckSignaturesSharedSomeMatch1() throws Exception { 3663 int apk1 = SHARED1_CERT1_CERT2; 3664 int apk2 = SHARED2_CERT1; 3665 boolean fail = true; 3666 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 3667 int expMatchResult = -1; 3668 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 3669 } 3670 3671 /* 3672 * Test that an app signed with cert1 and cert2 cannot be replaced when 3673 * signed with cert2 alone. 3674 */ 3675 @LargeTest 3676 public void testCheckSignaturesSharedSomeMatch2() throws Exception { 3677 int apk1 = SHARED1_CERT1_CERT2; 3678 int apk2 = SHARED2_CERT2; 3679 boolean fail = true; 3680 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 3681 int expMatchResult = -1; 3682 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 3683 } 3684 3685 @LargeTest 3686 public void testCheckSignaturesSharedUnknown() throws Exception { 3687 int apk1 = SHARED1_CERT1_CERT2; 3688 int apk2 = SHARED2_CERT1_CERT2; 3689 String apk1Name = "install1.apk"; 3690 String apk2Name = "install2.apk"; 3691 InstallParams ip1 = null; 3692 3693 try { 3694 ip1 = installFromRawResource(apk1Name, apk1, 0, false, 3695 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3696 PackageManager pm = mContext.getPackageManager(); 3697 // Delete app2 3698 PackageParser.Package pkg = getParsedPackage(apk2Name, apk2); 3699 getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS); 3700 // Check signatures now 3701 int match = mContext.getPackageManager().checkSignatures( 3702 ip1.pkg.packageName, pkg.packageName); 3703 assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match); 3704 } finally { 3705 if (ip1 != null) { 3706 cleanUpInstall(ip1); 3707 } 3708 } 3709 } 3710 3711 @LargeTest 3712 public void testReplaceFirstSharedMatchAllCerts() throws Exception { 3713 int apk1 = SHARED1_CERT1; 3714 int apk2 = SHARED2_CERT1; 3715 int rapk1 = SHARED1_CERT1; 3716 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 3717 replaceCerts(apk1, rapk1, true, false, -1); 3718 } 3719 3720 @LargeTest 3721 public void testReplaceSecondSharedMatchAllCerts() throws Exception { 3722 int apk1 = SHARED1_CERT1; 3723 int apk2 = SHARED2_CERT1; 3724 int rapk2 = SHARED2_CERT1; 3725 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 3726 replaceCerts(apk2, rapk2, true, false, -1); 3727 } 3728 3729 @LargeTest 3730 public void testReplaceFirstSharedMatchSomeCerts() throws Exception { 3731 int apk1 = SHARED1_CERT1_CERT2; 3732 int apk2 = SHARED2_CERT1_CERT2; 3733 int rapk1 = SHARED1_CERT1; 3734 boolean fail = true; 3735 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3736 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3737 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 3738 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3739 } 3740 3741 @LargeTest 3742 public void testReplaceSecondSharedMatchSomeCerts() throws Exception { 3743 int apk1 = SHARED1_CERT1_CERT2; 3744 int apk2 = SHARED2_CERT1_CERT2; 3745 int rapk2 = SHARED2_CERT1; 3746 boolean fail = true; 3747 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3748 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3749 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 3750 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3751 } 3752 3753 @LargeTest 3754 public void testReplaceFirstSharedMatchNoCerts() throws Exception { 3755 int apk1 = SHARED1_CERT1; 3756 int apk2 = SHARED2_CERT1; 3757 int rapk1 = SHARED1_CERT2; 3758 boolean fail = true; 3759 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3760 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3761 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 3762 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3763 } 3764 3765 @LargeTest 3766 public void testReplaceSecondSharedMatchNoCerts() throws Exception { 3767 int apk1 = SHARED1_CERT1; 3768 int apk2 = SHARED2_CERT1; 3769 int rapk2 = SHARED2_CERT2; 3770 boolean fail = true; 3771 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3772 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3773 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 3774 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3775 } 3776 3777 @LargeTest 3778 public void testReplaceFirstSharedMatchMoreCerts() throws Exception { 3779 int apk1 = SHARED1_CERT1; 3780 int apk2 = SHARED2_CERT1; 3781 int rapk1 = SHARED1_CERT1_CERT2; 3782 boolean fail = true; 3783 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3784 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3785 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 3786 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3787 } 3788 3789 @LargeTest 3790 public void testReplaceSecondSharedMatchMoreCerts() throws Exception { 3791 int apk1 = SHARED1_CERT1; 3792 int apk2 = SHARED2_CERT1; 3793 int rapk2 = SHARED2_CERT1_CERT2; 3794 boolean fail = true; 3795 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3796 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 3797 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 3798 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3799 } 3800 3801 /** 3802 * Unknown features should be allowed to install. This prevents older phones 3803 * from rejecting new packages that specify features that didn't exist when 3804 * an older phone existed. All older phones are assumed to have those 3805 * features. 3806 * <p> 3807 * Right now we allow all packages to be installed regardless of their 3808 * features. 3809 */ 3810 @LargeTest 3811 public void testUsesFeatureUnknownFeature() throws Exception { 3812 int retCode = PackageManager.INSTALL_SUCCEEDED; 3813 installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode, 3814 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3815 } 3816 3817 @LargeTest 3818 public void testInstallNonexistentFile() throws Exception { 3819 int retCode = PackageManager.INSTALL_FAILED_INVALID_URI; 3820 File invalidFile = new File("/nonexistent-file.apk"); 3821 invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode); 3822 } 3823 3824 @SmallTest 3825 public void testGetVerifierDeviceIdentity() throws Exception { 3826 PackageManager pm = getPm(); 3827 VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity(); 3828 3829 assertNotNull("Verifier device identity should not be null", id); 3830 } 3831 3832 public void testGetInstalledPackages() throws Exception { 3833 List<PackageInfo> packages = getPm().getInstalledPackages(0); 3834 assertNotNull("installed packages cannot be null", packages); 3835 assertTrue("installed packages cannot be empty", packages.size() > 0); 3836 } 3837 3838 public void testGetUnInstalledPackages() throws Exception { 3839 List<PackageInfo> packages = getPm().getInstalledPackages( 3840 PackageManager.GET_UNINSTALLED_PACKAGES); 3841 assertNotNull("installed packages cannot be null", packages); 3842 assertTrue("installed packages cannot be empty", packages.size() > 0); 3843 } 3844 3845 /** 3846 * Test that getInstalledPackages returns all the data specified in flags. 3847 */ 3848 public void testGetInstalledPackagesAll() throws Exception { 3849 int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS 3850 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION 3851 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS 3852 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES 3853 | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES; 3854 3855 List<PackageInfo> packages = getPm().getInstalledPackages(flags); 3856 assertNotNull("installed packages cannot be null", packages); 3857 assertTrue("installed packages cannot be empty", packages.size() > 0); 3858 3859 PackageInfo packageInfo = null; 3860 3861 // Find the package with all components specified in the AndroidManifest 3862 // to ensure no null values 3863 for (PackageInfo pi : packages) { 3864 if ("com.android.frameworks.coretests.install_complete_package_info" 3865 .equals(pi.packageName)) { 3866 packageInfo = pi; 3867 break; 3868 } 3869 } 3870 assertNotNull("activities should not be null", packageInfo.activities); 3871 assertNotNull("configPreferences should not be null", packageInfo.configPreferences); 3872 assertNotNull("instrumentation should not be null", packageInfo.instrumentation); 3873 assertNotNull("permissions should not be null", packageInfo.permissions); 3874 assertNotNull("providers should not be null", packageInfo.providers); 3875 assertNotNull("receivers should not be null", packageInfo.receivers); 3876 assertNotNull("services should not be null", packageInfo.services); 3877 assertNotNull("signatures should not be null", packageInfo.signatures); 3878 } 3879 3880 /** 3881 * Test that getInstalledPackages returns all the data specified in 3882 * flags when the GET_UNINSTALLED_PACKAGES flag is set. 3883 */ 3884 public void testGetUnInstalledPackagesAll() throws Exception { 3885 int flags = PackageManager.GET_UNINSTALLED_PACKAGES 3886 | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS 3887 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION 3888 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS 3889 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES 3890 | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES; 3891 3892 List<PackageInfo> packages = getPm().getInstalledPackages(flags); 3893 assertNotNull("installed packages cannot be null", packages); 3894 assertTrue("installed packages cannot be empty", packages.size() > 0); 3895 3896 PackageInfo packageInfo = null; 3897 3898 // Find the package with all components specified in the AndroidManifest 3899 // to ensure no null values 3900 for (PackageInfo pi : packages) { 3901 if ("com.android.frameworks.coretests.install_complete_package_info" 3902 .equals(pi.packageName)) { 3903 packageInfo = pi; 3904 break; 3905 } 3906 } 3907 assertNotNull("activities should not be null", packageInfo.activities); 3908 assertNotNull("configPreferences should not be null", packageInfo.configPreferences); 3909 assertNotNull("instrumentation should not be null", packageInfo.instrumentation); 3910 assertNotNull("permissions should not be null", packageInfo.permissions); 3911 assertNotNull("providers should not be null", packageInfo.providers); 3912 assertNotNull("receivers should not be null", packageInfo.receivers); 3913 assertNotNull("services should not be null", packageInfo.services); 3914 assertNotNull("signatures should not be null", packageInfo.signatures); 3915 } 3916 3917 public void testInstall_BadDex_CleanUp() throws Exception { 3918 int retCode = PackageManager.INSTALL_FAILED_DEXOPT; 3919 installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode, 3920 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 3921 } 3922 3923 /*---------- Recommended install location tests ----*/ 3924 /* 3925 * TODO's 3926 * check version numbers for upgrades 3927 * check permissions of installed packages 3928 * how to do tests on updated system apps? 3929 * verify updates to system apps cannot be installed on the sdcard. 3930 */ 3931 } 3932