PackageManagerTests.java revision 1683afac148f5bce186f7af7a6a8ea6294ecd379
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 17package android.content.pm; 18 19import com.android.frameworks.coretests.R; 20import com.android.internal.content.PackageHelper; 21 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.content.pm.PackageManager; 27import android.content.pm.PackageManager.NameNotFoundException; 28import android.content.res.Resources; 29import android.content.res.Resources.NotFoundException; 30import android.net.Uri; 31import android.os.Environment; 32import android.os.FileUtils; 33import android.os.IBinder; 34import android.os.RemoteException; 35import android.os.ServiceManager; 36import android.os.StatFs; 37import android.os.storage.IMountService; 38import android.os.storage.StorageListener; 39import android.os.storage.StorageManager; 40import android.os.storage.StorageResultCode; 41import android.provider.Settings; 42import android.provider.Settings.SettingNotFoundException; 43import android.test.AndroidTestCase; 44import android.test.suitebuilder.annotation.LargeTest; 45import android.util.DisplayMetrics; 46import android.util.Log; 47 48import java.io.File; 49import java.io.IOException; 50import java.io.InputStream; 51 52public class PackageManagerTests extends AndroidTestCase { 53 private static final boolean localLOGV = true; 54 public static final String TAG="PackageManagerTests"; 55 public final long MAX_WAIT_TIME = 25*1000; 56 public final long WAIT_TIME_INCR = 5*1000; 57 private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec"; 58 private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO; 59 private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL; 60 private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL; 61 private boolean mOrigState; 62 63 void failStr(String errMsg) { 64 Log.w(TAG, "errMsg="+errMsg); 65 fail(errMsg); 66 } 67 void failStr(Exception e) { 68 failStr(e.getMessage()); 69 } 70 71 @Override 72 protected void setUp() throws Exception { 73 super.setUp(); 74 mOrigState = checkMediaState(Environment.MEDIA_MOUNTED); 75 if (!mountMedia()) { 76 Log.i(TAG, "sdcard not mounted? Some of these tests might fail"); 77 } 78 } 79 80 @Override 81 protected void tearDown() throws Exception { 82 // Restore media state. 83 boolean newState = checkMediaState(Environment.MEDIA_MOUNTED); 84 if (newState != mOrigState) { 85 if (mOrigState) { 86 mountMedia(); 87 } else { 88 unmountMedia(); 89 } 90 } 91 super.tearDown(); 92 } 93 94 private class PackageInstallObserver extends IPackageInstallObserver.Stub { 95 public int returnCode; 96 private boolean doneFlag = false; 97 98 public void packageInstalled(String packageName, int returnCode) { 99 synchronized(this) { 100 this.returnCode = returnCode; 101 doneFlag = true; 102 notifyAll(); 103 } 104 } 105 106 public boolean isDone() { 107 return doneFlag; 108 } 109 } 110 111 abstract class GenericReceiver extends BroadcastReceiver { 112 private boolean doneFlag = false; 113 boolean received = false; 114 Intent intent; 115 IntentFilter filter; 116 abstract boolean notifyNow(Intent intent); 117 @Override 118 public void onReceive(Context context, Intent intent) { 119 if (notifyNow(intent)) { 120 synchronized (this) { 121 received = true; 122 doneFlag = true; 123 this.intent = intent; 124 notifyAll(); 125 } 126 } 127 } 128 129 public boolean isDone() { 130 return doneFlag; 131 } 132 133 public void setFilter(IntentFilter filter) { 134 this.filter = filter; 135 } 136 } 137 138 class InstallReceiver extends GenericReceiver { 139 String pkgName; 140 141 InstallReceiver(String pkgName) { 142 this.pkgName = pkgName; 143 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 144 filter.addDataScheme("package"); 145 super.setFilter(filter); 146 } 147 148 public boolean notifyNow(Intent intent) { 149 String action = intent.getAction(); 150 if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) { 151 return false; 152 } 153 Uri data = intent.getData(); 154 String installedPkg = data.getEncodedSchemeSpecificPart(); 155 if (pkgName.equals(installedPkg)) { 156 return true; 157 } 158 return false; 159 } 160 } 161 162 private PackageManager getPm() { 163 return mContext.getPackageManager(); 164 } 165 166 private IPackageManager getIPm() { 167 IPackageManager ipm = IPackageManager.Stub.asInterface( 168 ServiceManager.getService("package")); 169 return ipm; 170 } 171 172 public boolean invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver) { 173 PackageInstallObserver observer = new PackageInstallObserver(); 174 final boolean received = false; 175 mContext.registerReceiver(receiver, receiver.filter); 176 final boolean DEBUG = true; 177 try { 178 // Wait on observer 179 synchronized(observer) { 180 synchronized (receiver) { 181 getPm().installPackage(packageURI, observer, flags, null); 182 long waitTime = 0; 183 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 184 try { 185 observer.wait(WAIT_TIME_INCR); 186 waitTime += WAIT_TIME_INCR; 187 } catch (InterruptedException e) { 188 Log.i(TAG, "Interrupted during sleep", e); 189 } 190 } 191 if(!observer.isDone()) { 192 fail("Timed out waiting for packageInstalled callback"); 193 } 194 if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) { 195 Log.i(TAG, "Failed to install with error code = " + observer.returnCode); 196 return false; 197 } 198 // Verify we received the broadcast 199 waitTime = 0; 200 while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 201 try { 202 receiver.wait(WAIT_TIME_INCR); 203 waitTime += WAIT_TIME_INCR; 204 } catch (InterruptedException e) { 205 Log.i(TAG, "Interrupted during sleep", e); 206 } 207 } 208 if(!receiver.isDone()) { 209 fail("Timed out waiting for PACKAGE_ADDED notification"); 210 } 211 return receiver.received; 212 } 213 } 214 } finally { 215 mContext.unregisterReceiver(receiver); 216 } 217 } 218 219 public void invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult) { 220 PackageInstallObserver observer = new PackageInstallObserver(); 221 try { 222 // Wait on observer 223 synchronized(observer) { 224 getPm().installPackage(packageURI, observer, flags, null); 225 long waitTime = 0; 226 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 227 try { 228 observer.wait(WAIT_TIME_INCR); 229 waitTime += WAIT_TIME_INCR; 230 } catch (InterruptedException e) { 231 Log.i(TAG, "Interrupted during sleep", e); 232 } 233 } 234 if(!observer.isDone()) { 235 fail("Timed out waiting for packageInstalled callback"); 236 } 237 assertEquals(expectedResult, observer.returnCode); 238 } 239 } finally { 240 } 241 } 242 243 Uri getInstallablePackage(int fileResId, File outFile) { 244 Resources res = mContext.getResources(); 245 InputStream is = null; 246 try { 247 is = res.openRawResource(fileResId); 248 } catch (NotFoundException e) { 249 failStr("Failed to load resource with id: " + fileResId); 250 } 251 FileUtils.setPermissions(outFile.getPath(), 252 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, 253 -1, -1); 254 assertTrue(FileUtils.copyToFile(is, outFile)); 255 FileUtils.setPermissions(outFile.getPath(), 256 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, 257 -1, -1); 258 return Uri.fromFile(outFile); 259 } 260 261 private PackageParser.Package parsePackage(Uri packageURI) { 262 final String archiveFilePath = packageURI.getPath(); 263 PackageParser packageParser = new PackageParser(archiveFilePath); 264 File sourceFile = new File(archiveFilePath); 265 DisplayMetrics metrics = new DisplayMetrics(); 266 metrics.setToDefaults(); 267 PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0); 268 packageParser = null; 269 return pkg; 270 } 271 private boolean checkSd(long pkgLen) { 272 String status = Environment.getExternalStorageState(); 273 if (!status.equals(Environment.MEDIA_MOUNTED)) { 274 return false; 275 } 276 long sdSize = -1; 277 StatFs sdStats = new StatFs( 278 Environment.getExternalStorageDirectory().getPath()); 279 sdSize = (long)sdStats.getAvailableBlocks() * 280 (long)sdStats.getBlockSize(); 281 // TODO check for thresholds here 282 return pkgLen <= sdSize; 283 284 } 285 private boolean checkInt(long pkgLen) { 286 StatFs intStats = new StatFs(Environment.getDataDirectory().getPath()); 287 long intSize = (long)intStats.getBlockCount() * 288 (long)intStats.getBlockSize(); 289 long iSize = (long)intStats.getAvailableBlocks() * 290 (long)intStats.getBlockSize(); 291 // TODO check for thresholds here? 292 return pkgLen <= iSize; 293 } 294 private static final int INSTALL_LOC_INT = 1; 295 private static final int INSTALL_LOC_SD = 2; 296 private static final int INSTALL_LOC_ERR = -1; 297 private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) { 298 // Flags explicitly over ride everything else. 299 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) { 300 return INSTALL_LOC_INT; 301 } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { 302 return INSTALL_LOC_SD; 303 } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { 304 return INSTALL_LOC_INT; 305 } 306 // Manifest option takes precedence next 307 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 308 if (checkSd(pkgLen)) { 309 return INSTALL_LOC_SD; 310 } 311 if (checkInt(pkgLen)) { 312 return INSTALL_LOC_INT; 313 } 314 return INSTALL_LOC_ERR; 315 } 316 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 317 if (checkInt(pkgLen)) { 318 return INSTALL_LOC_INT; 319 } 320 return INSTALL_LOC_ERR; 321 } 322 if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) { 323 // Check for free memory internally 324 if (checkInt(pkgLen)) { 325 return INSTALL_LOC_INT; 326 } 327 // Check for free memory externally 328 if (checkSd(pkgLen)) { 329 return INSTALL_LOC_SD; 330 } 331 return INSTALL_LOC_ERR; 332 } 333 // Check for settings preference. 334 boolean checkSd = false; 335 int userPref = getDefaultInstallLoc(); 336 if (userPref == APP_INSTALL_DEVICE) { 337 if (checkInt(pkgLen)) { 338 return INSTALL_LOC_INT; 339 } 340 return INSTALL_LOC_ERR; 341 } else if (userPref == APP_INSTALL_SDCARD) { 342 if (checkSd(pkgLen)) { 343 return INSTALL_LOC_SD; 344 } 345 return INSTALL_LOC_ERR; 346 } 347 // Default system policy for apps with no manifest option specified. 348 // Check for free memory internally 349 if (checkInt(pkgLen)) { 350 return INSTALL_LOC_INT; 351 } 352 return INSTALL_LOC_ERR; 353 } 354 355 private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) { 356 try { 357 String pkgName = pkg.packageName; 358 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); 359 assertNotNull(info); 360 assertEquals(pkgName, info.packageName); 361 File dataDir = Environment.getDataDirectory(); 362 String appInstallPath = new File(dataDir, "app").getPath(); 363 String drmInstallPath = new File(dataDir, "app-private").getPath(); 364 File srcDir = new File(info.sourceDir); 365 String srcPath = srcDir.getParent(); 366 File publicSrcDir = new File(info.publicSourceDir); 367 String publicSrcPath = publicSrcDir.getParent(); 368 long pkgLen = new File(info.sourceDir).length(); 369 370 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 371 assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 372 assertEquals(srcPath, drmInstallPath); 373 assertEquals(publicSrcPath, appInstallPath); 374 assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); 375 } else { 376 assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); 377 int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); 378 if (rLoc == INSTALL_LOC_INT) { 379 assertEquals(srcPath, appInstallPath); 380 assertEquals(publicSrcPath, appInstallPath); 381 assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 382 assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); 383 384 // Make sure the native library dir is not a symlink 385 final File nativeLibDir = new File(info.nativeLibraryDir); 386 assertTrue("Native library dir should exist at " + info.nativeLibraryDir, 387 nativeLibDir.exists()); 388 try { 389 assertEquals("Native library dir should not be a symlink", 390 info.nativeLibraryDir, 391 nativeLibDir.getCanonicalPath()); 392 } catch (IOException e) { 393 fail("Can't read " + nativeLibDir.getPath()); 394 } 395 } else if (rLoc == INSTALL_LOC_SD){ 396 assertTrue("Application flags (" + info.flags 397 + ") should contain FLAG_EXTERNAL_STORAGE", 398 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 399 assertTrue("The APK path (" + srcPath + ") should start with " 400 + SECURE_CONTAINERS_PREFIX, srcPath 401 .startsWith(SECURE_CONTAINERS_PREFIX)); 402 assertTrue("The public APK path (" + publicSrcPath + ") should start with " 403 + SECURE_CONTAINERS_PREFIX, publicSrcPath 404 .startsWith(SECURE_CONTAINERS_PREFIX)); 405 assertTrue("The native library path (" + info.nativeLibraryDir 406 + ") should start with " + SECURE_CONTAINERS_PREFIX, 407 info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); 408 409 // Make sure the native library in /data/data/<app>/lib is a 410 // symlink to the ASEC 411 final File nativeLibSymLink = new File(info.dataDir, "lib"); 412 assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), 413 nativeLibSymLink.exists()); 414 try { 415 assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " 416 + info.nativeLibraryDir, info.nativeLibraryDir, nativeLibSymLink 417 .getCanonicalPath()); 418 } catch (IOException e) { 419 fail("Can't read " + nativeLibSymLink.getPath()); 420 } 421 } else { 422 // TODO handle error. Install should have failed. 423 fail("Install should have failed"); 424 } 425 } 426 } catch (NameNotFoundException e) { 427 failStr("failed with exception : " + e); 428 } 429 } 430 431 private void assertNotInstalled(String pkgName) { 432 try { 433 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); 434 fail(pkgName + " shouldnt be installed"); 435 } catch (NameNotFoundException e) { 436 } 437 } 438 439 class InstallParams { 440 Uri packageURI; 441 PackageParser.Package pkg; 442 InstallParams(String outFileName, int rawResId) { 443 this.pkg = getParsedPackage(outFileName, rawResId); 444 this.packageURI = Uri.fromFile(new File(pkg.mScanPath)); 445 } 446 InstallParams(PackageParser.Package pkg) { 447 this.packageURI = Uri.fromFile(new File(pkg.mScanPath)); 448 this.pkg = pkg; 449 } 450 long getApkSize() { 451 File file = new File(pkg.mScanPath); 452 return file.length(); 453 } 454 } 455 456 private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) { 457 return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, 458 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 459 } 460 461 static final String PERM_PACKAGE = "package"; 462 static final String PERM_DEFINED = "defined"; 463 static final String PERM_UNDEFINED = "undefined"; 464 static final String PERM_USED = "used"; 465 static final String PERM_NOTUSED = "notused"; 466 467 private void assertPermissions(String[] cmds) { 468 final PackageManager pm = getPm(); 469 String pkg = null; 470 PackageInfo pkgInfo = null; 471 String mode = PERM_DEFINED; 472 int i = 0; 473 while (i < cmds.length) { 474 String cmd = cmds[i++]; 475 if (cmd == PERM_PACKAGE) { 476 pkg = cmds[i++]; 477 try { 478 pkgInfo = pm.getPackageInfo(pkg, 479 PackageManager.GET_PERMISSIONS 480 | PackageManager.GET_UNINSTALLED_PACKAGES); 481 } catch (NameNotFoundException e) { 482 pkgInfo = null; 483 } 484 } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED 485 || cmd == PERM_USED || cmd == PERM_NOTUSED) { 486 mode = cmds[i++]; 487 } else { 488 if (mode == PERM_DEFINED) { 489 try { 490 PermissionInfo pi = pm.getPermissionInfo(cmd, 0); 491 assertNotNull(pi); 492 assertEquals(pi.packageName, pkg); 493 assertEquals(pi.name, cmd); 494 assertNotNull(pkgInfo); 495 boolean found = false; 496 for (int j=0; j<pkgInfo.permissions.length && !found; j++) { 497 if (pkgInfo.permissions[j].name.equals(cmd)) { 498 found = true; 499 } 500 } 501 if (!found) { 502 fail("Permission not found: " + cmd); 503 } 504 } catch (NameNotFoundException e) { 505 throw new RuntimeException(e); 506 } 507 } else if (mode == PERM_UNDEFINED) { 508 try { 509 pm.getPermissionInfo(cmd, 0); 510 throw new RuntimeException("Permission exists: " + cmd); 511 } catch (NameNotFoundException e) { 512 } 513 if (pkgInfo != null) { 514 boolean found = false; 515 for (int j=0; j<pkgInfo.permissions.length && !found; j++) { 516 if (pkgInfo.permissions[j].name.equals(cmd)) { 517 found = true; 518 } 519 } 520 if (found) { 521 fail("Permission still exists: " + cmd); 522 } 523 } 524 } else if (mode == PERM_USED || mode == PERM_NOTUSED) { 525 boolean found = false; 526 for (int j=0; j<pkgInfo.requestedPermissions.length && !found; j++) { 527 if (pkgInfo.requestedPermissions[j].equals(cmd)) { 528 found = true; 529 } 530 } 531 if (!found) { 532 fail("Permission not requested: " + cmd); 533 } 534 if (mode == PERM_USED) { 535 if (pm.checkPermission(cmd, pkg) 536 != PackageManager.PERMISSION_GRANTED) { 537 fail("Permission not granted: " + cmd); 538 } 539 } else { 540 if (pm.checkPermission(cmd, pkg) 541 != PackageManager.PERMISSION_DENIED) { 542 fail("Permission granted: " + cmd); 543 } 544 } 545 } 546 } 547 } 548 } 549 550 private PackageParser.Package getParsedPackage(String outFileName, int rawResId) { 551 PackageManager pm = mContext.getPackageManager(); 552 File filesDir = mContext.getFilesDir(); 553 File outFile = new File(filesDir, outFileName); 554 Uri packageURI = getInstallablePackage(rawResId, outFile); 555 PackageParser.Package pkg = parsePackage(packageURI); 556 return pkg; 557 } 558 559 /* 560 * Utility function that reads a apk bundled as a raw resource 561 * copies it into own data directory and invokes 562 * PackageManager api to install it. 563 */ 564 private void installFromRawResource(InstallParams ip, 565 int flags, boolean cleanUp, boolean fail, int result, 566 int expInstallLocation) { 567 PackageManager pm = mContext.getPackageManager(); 568 PackageParser.Package pkg = ip.pkg; 569 Uri packageURI = ip.packageURI; 570 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) { 571 // Make sure the package doesn't exist 572 try { 573 ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName, 574 PackageManager.GET_UNINSTALLED_PACKAGES); 575 GenericReceiver receiver = new DeleteReceiver(pkg.packageName); 576 invokeDeletePackage(pkg.packageName, 0, receiver); 577 } catch (NameNotFoundException e1) { 578 } catch (Exception e) { 579 failStr(e); 580 } 581 } 582 try { 583 if (fail) { 584 invokeInstallPackageFail(packageURI, flags, result); 585 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) { 586 assertNotInstalled(pkg.packageName); 587 } 588 } else { 589 InstallReceiver receiver = new InstallReceiver(pkg.packageName); 590 assertTrue(invokeInstallPackage(packageURI, flags, receiver)); 591 // Verify installed information 592 assertInstall(pkg, flags, expInstallLocation); 593 } 594 } finally { 595 if (cleanUp) { 596 cleanUpInstall(ip); 597 } 598 } 599 } 600 601 /* 602 * Utility function that reads a apk bundled as a raw resource 603 * copies it into own data directory and invokes 604 * PackageManager api to install it. 605 */ 606 private InstallParams installFromRawResource(String outFileName, 607 int rawResId, int flags, boolean cleanUp, boolean fail, int result, 608 int expInstallLocation) { 609 InstallParams ip = new InstallParams(outFileName, rawResId); 610 installFromRawResource(ip, flags, cleanUp, fail, result, expInstallLocation); 611 return ip; 612 } 613 614 @LargeTest 615 public void testInstallNormalInternal() { 616 sampleInstallFromRawResource(0, true); 617 } 618 619 @LargeTest 620 public void testInstallFwdLockedInternal() { 621 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true); 622 } 623 624 @LargeTest 625 public void testInstallSdcard() { 626 mountMedia(); 627 sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true); 628 } 629 630 /* ------------------------- Test replacing packages --------------*/ 631 class ReplaceReceiver extends GenericReceiver { 632 String pkgName; 633 final static int INVALID = -1; 634 final static int REMOVED = 1; 635 final static int ADDED = 2; 636 final static int REPLACED = 3; 637 int removed = INVALID; 638 // for updated system apps only 639 boolean update = false; 640 641 ReplaceReceiver(String pkgName) { 642 this.pkgName = pkgName; 643 filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 644 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 645 if (update) { 646 filter.addAction(Intent.ACTION_PACKAGE_REPLACED); 647 } 648 filter.addDataScheme("package"); 649 super.setFilter(filter); 650 } 651 652 public boolean notifyNow(Intent intent) { 653 String action = intent.getAction(); 654 Uri data = intent.getData(); 655 String installedPkg = data.getEncodedSchemeSpecificPart(); 656 if (pkgName == null || !pkgName.equals(installedPkg)) { 657 return false; 658 } 659 if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 660 removed = REMOVED; 661 } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 662 if (removed != REMOVED) { 663 return false; 664 } 665 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 666 if (!replacing) { 667 return false; 668 } 669 removed = ADDED; 670 if (!update) { 671 return true; 672 } 673 } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 674 if (removed != ADDED) { 675 return false; 676 } 677 removed = REPLACED; 678 return true; 679 } 680 return false; 681 } 682 } 683 684 /* 685 * Utility function that reads a apk bundled as a raw resource 686 * copies it into own data directory and invokes 687 * PackageManager api to install first and then replace it 688 * again. 689 */ 690 private void sampleReplaceFromRawResource(int flags) { 691 InstallParams ip = sampleInstallFromRawResource(flags, false); 692 boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0); 693 Log.i(TAG, "replace=" + replace); 694 GenericReceiver receiver; 695 if (replace) { 696 receiver = new ReplaceReceiver(ip.pkg.packageName); 697 Log.i(TAG, "Creating replaceReceiver"); 698 } else { 699 receiver = new InstallReceiver(ip.pkg.packageName); 700 } 701 try { 702 try { 703 assertEquals(invokeInstallPackage(ip.packageURI, flags, receiver), replace); 704 if (replace) { 705 assertInstall(ip.pkg, flags, ip.pkg.installLocation); 706 } 707 } catch (Exception e) { 708 failStr("Failed with exception : " + e); 709 } 710 } finally { 711 cleanUpInstall(ip); 712 } 713 } 714 715 @LargeTest 716 public void testReplaceFailNormalInternal() { 717 sampleReplaceFromRawResource(0); 718 } 719 720 @LargeTest 721 public void testReplaceFailFwdLockedInternal() { 722 sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK); 723 } 724 725 @LargeTest 726 public void testReplaceFailSdcard() { 727 sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL); 728 } 729 730 @LargeTest 731 public void testReplaceNormalInternal() { 732 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING); 733 } 734 735 @LargeTest 736 public void testReplaceFwdLockedInternal() { 737 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING | 738 PackageManager.INSTALL_FORWARD_LOCK); 739 } 740 741 @LargeTest 742 public void testReplaceSdcard() { 743 sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING | 744 PackageManager.INSTALL_EXTERNAL); 745 } 746 747 /* -------------- Delete tests ---*/ 748 class DeleteObserver extends IPackageDeleteObserver.Stub { 749 750 public boolean succeeded; 751 private boolean doneFlag = false; 752 753 public boolean isDone() { 754 return doneFlag; 755 } 756 757 public void packageDeleted(boolean succeeded) throws RemoteException { 758 synchronized(this) { 759 this.succeeded = succeeded; 760 doneFlag = true; 761 notifyAll(); 762 } 763 } 764 } 765 766 class DeleteReceiver extends GenericReceiver { 767 String pkgName; 768 769 DeleteReceiver(String pkgName) { 770 this.pkgName = pkgName; 771 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 772 filter.addDataScheme("package"); 773 super.setFilter(filter); 774 } 775 776 public boolean notifyNow(Intent intent) { 777 String action = intent.getAction(); 778 if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 779 return false; 780 } 781 Uri data = intent.getData(); 782 String installedPkg = data.getEncodedSchemeSpecificPart(); 783 if (pkgName.equals(installedPkg)) { 784 return true; 785 } 786 return false; 787 } 788 } 789 790 public boolean invokeDeletePackage(final String pkgName, int flags, 791 GenericReceiver receiver) throws Exception { 792 DeleteObserver observer = new DeleteObserver(); 793 final boolean received = false; 794 mContext.registerReceiver(receiver, receiver.filter); 795 try { 796 // Wait on observer 797 synchronized(observer) { 798 synchronized (receiver) { 799 getPm().deletePackage(pkgName, observer, flags); 800 long waitTime = 0; 801 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 802 observer.wait(WAIT_TIME_INCR); 803 waitTime += WAIT_TIME_INCR; 804 } 805 if(!observer.isDone()) { 806 throw new Exception("Timed out waiting for packageInstalled callback"); 807 } 808 // Verify we received the broadcast 809 waitTime = 0; 810 while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 811 receiver.wait(WAIT_TIME_INCR); 812 waitTime += WAIT_TIME_INCR; 813 } 814 if(!receiver.isDone()) { 815 throw new Exception("Timed out waiting for PACKAGE_REMOVED notification"); 816 } 817 return receiver.received; 818 } 819 } 820 } finally { 821 mContext.unregisterReceiver(receiver); 822 } 823 } 824 825 public void deleteFromRawResource(int iFlags, int dFlags) { 826 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 827 boolean retainData = ((dFlags & PackageManager.DONT_DELETE_DATA) != 0); 828 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 829 DeleteObserver observer = new DeleteObserver(); 830 try { 831 assertTrue(invokeDeletePackage(ip.pkg.packageName, dFlags, receiver)); 832 ApplicationInfo info = null; 833 Log.i(TAG, "okay4"); 834 try { 835 info = getPm().getApplicationInfo(ip.pkg.packageName, 836 PackageManager.GET_UNINSTALLED_PACKAGES); 837 } catch (NameNotFoundException e) { 838 info = null; 839 } 840 if (retainData) { 841 assertNotNull(info); 842 assertEquals(info.packageName, ip.pkg.packageName); 843 File file = new File(info.dataDir); 844 assertTrue(file.exists()); 845 } else { 846 assertNull(info); 847 } 848 } catch (Exception e) { 849 failStr(e); 850 } finally { 851 cleanUpInstall(ip); 852 } 853 } 854 855 @LargeTest 856 public void testDeleteNormalInternal() { 857 deleteFromRawResource(0, 0); 858 } 859 860 @LargeTest 861 public void testDeleteFwdLockedInternal() { 862 deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0); 863 } 864 865 @LargeTest 866 public void testDeleteSdcard() { 867 deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0); 868 } 869 870 @LargeTest 871 public void testDeleteNormalInternalRetainData() { 872 deleteFromRawResource(0, PackageManager.DONT_DELETE_DATA); 873 } 874 875 @LargeTest 876 public void testDeleteFwdLockedInternalRetainData() { 877 deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DONT_DELETE_DATA); 878 } 879 880 @LargeTest 881 public void testDeleteSdcardRetainData() { 882 deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA); 883 } 884 885 /* sdcard mount/unmount tests ******/ 886 887 class SdMountReceiver extends GenericReceiver { 888 String pkgNames[]; 889 boolean status = true; 890 891 SdMountReceiver(String[] pkgNames) { 892 this.pkgNames = pkgNames; 893 IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 894 super.setFilter(filter); 895 } 896 897 public boolean notifyNow(Intent intent) { 898 Log.i(TAG, "okay 1"); 899 String action = intent.getAction(); 900 if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 901 return false; 902 } 903 String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 904 for (String pkg : pkgNames) { 905 boolean found = false; 906 for (String rpkg : rpkgList) { 907 if (rpkg.equals(pkg)) { 908 found = true; 909 break; 910 } 911 } 912 if (!found) { 913 status = false; 914 return true; 915 } 916 } 917 return true; 918 } 919 } 920 921 class SdUnMountReceiver extends GenericReceiver { 922 String pkgNames[]; 923 boolean status = true; 924 925 SdUnMountReceiver(String[] pkgNames) { 926 this.pkgNames = pkgNames; 927 IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 928 super.setFilter(filter); 929 } 930 931 public boolean notifyNow(Intent intent) { 932 String action = intent.getAction(); 933 if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 934 return false; 935 } 936 String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 937 for (String pkg : pkgNames) { 938 boolean found = false; 939 for (String rpkg : rpkgList) { 940 if (rpkg.equals(pkg)) { 941 found = true; 942 break; 943 } 944 } 945 if (!found) { 946 status = false; 947 return true; 948 } 949 } 950 return true; 951 } 952 } 953 954 IMountService getMs() { 955 IBinder service = ServiceManager.getService("mount"); 956 if (service != null) { 957 return IMountService.Stub.asInterface(service); 958 } else { 959 Log.e(TAG, "Can't get mount service"); 960 } 961 return null; 962 } 963 964 boolean checkMediaState(String desired) { 965 try { 966 String mPath = Environment.getExternalStorageDirectory().getPath(); 967 String actual = getMs().getVolumeState(mPath); 968 if (desired.equals(actual)) { 969 return true; 970 } else { 971 return false; 972 } 973 } catch (RemoteException e) { 974 Log.e(TAG, "Exception while checking media state", e); 975 return false; 976 } 977 } 978 979 boolean mountMedia() { 980 if (checkMediaState(Environment.MEDIA_MOUNTED)) { 981 return true; 982 } 983 984 final String path = Environment.getExternalStorageDirectory().toString(); 985 StorageListener observer = new StorageListener(Environment.MEDIA_MOUNTED); 986 StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 987 sm.registerListener(observer); 988 try { 989 // Wait on observer 990 synchronized (observer) { 991 int ret = getMs().mountVolume(path); 992 if (ret != StorageResultCode.OperationSucceeded) { 993 throw new Exception("Could not mount the media"); 994 } 995 long waitTime = 0; 996 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) { 997 observer.wait(WAIT_TIME_INCR); 998 waitTime += WAIT_TIME_INCR; 999 } 1000 if (!observer.isDone()) { 1001 throw new Exception("Timed out waiting for unmount media notification"); 1002 } 1003 return true; 1004 } 1005 } catch (Exception e) { 1006 Log.e(TAG, "Exception : " + e); 1007 return false; 1008 } finally { 1009 sm.unregisterListener(observer); 1010 } 1011 } 1012 1013 private boolean unmountMedia() { 1014 if (checkMediaState(Environment.MEDIA_UNMOUNTED)) { 1015 return true; 1016 } 1017 1018 final String path = Environment.getExternalStorageDirectory().getPath(); 1019 StorageListener observer = new StorageListener(Environment.MEDIA_UNMOUNTED); 1020 StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 1021 sm.registerListener(observer); 1022 try { 1023 // Wait on observer 1024 synchronized(observer) { 1025 getMs().unmountVolume(path, true); 1026 long waitTime = 0; 1027 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 1028 observer.wait(WAIT_TIME_INCR); 1029 waitTime += WAIT_TIME_INCR; 1030 } 1031 if(!observer.isDone()) { 1032 throw new Exception("Timed out waiting for unmount media notification"); 1033 } 1034 return true; 1035 } 1036 } catch (Exception e) { 1037 Log.e(TAG, "Exception : " + e); 1038 return false; 1039 } finally { 1040 sm.unregisterListener(observer); 1041 } 1042 } 1043 1044 private boolean mountFromRawResource() { 1045 // Install pkg on sdcard 1046 InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false); 1047 if (localLOGV) Log.i(TAG, "Installed pkg on sdcard"); 1048 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1049 boolean registeredReceiver = false; 1050 SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName}); 1051 try { 1052 if (localLOGV) Log.i(TAG, "Unmounting media"); 1053 // Unmount media 1054 assertTrue(unmountMedia()); 1055 if (localLOGV) Log.i(TAG, "Unmounted media"); 1056 // Register receiver here 1057 PackageManager pm = getPm(); 1058 mContext.registerReceiver(receiver, receiver.filter); 1059 registeredReceiver = true; 1060 1061 // Wait on receiver 1062 synchronized (receiver) { 1063 if (localLOGV) Log.i(TAG, "Mounting media"); 1064 // Mount media again 1065 assertTrue(mountMedia()); 1066 if (localLOGV) Log.i(TAG, "Mounted media"); 1067 if (localLOGV) Log.i(TAG, "Waiting for notification"); 1068 long waitTime = 0; 1069 // Verify we received the broadcast 1070 waitTime = 0; 1071 while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 1072 receiver.wait(WAIT_TIME_INCR); 1073 waitTime += WAIT_TIME_INCR; 1074 } 1075 if(!receiver.isDone()) { 1076 failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification"); 1077 } 1078 return receiver.received; 1079 } 1080 } catch (InterruptedException e) { 1081 failStr(e); 1082 return false; 1083 } finally { 1084 if (registeredReceiver) mContext.unregisterReceiver(receiver); 1085 // Restore original media state 1086 if (origState) { 1087 mountMedia(); 1088 } else { 1089 unmountMedia(); 1090 } 1091 if (localLOGV) Log.i(TAG, "Cleaning up install"); 1092 cleanUpInstall(ip); 1093 } 1094 } 1095 1096 /* 1097 * Install package on sdcard. Unmount and then mount the media. 1098 * (Use PackageManagerService private api for now) 1099 * Make sure the installed package is available. 1100 */ 1101 @LargeTest 1102 public void testMountSdNormalInternal() { 1103 assertTrue(mountFromRawResource()); 1104 } 1105 1106 void cleanUpInstall(InstallParams ip) { 1107 if (ip == null) { 1108 return; 1109 } 1110 Runtime.getRuntime().gc(); 1111 Log.i(TAG, "Deleting package : " + ip.pkg.packageName); 1112 getPm().deletePackage(ip.pkg.packageName, null, 0); 1113 File outFile = new File(ip.pkg.mScanPath); 1114 if (outFile != null && outFile.exists()) { 1115 outFile.delete(); 1116 } 1117 } 1118 void cleanUpInstall(String pkgName) { 1119 if (pkgName == null) { 1120 return; 1121 } 1122 Log.i(TAG, "Deleting package : " + pkgName); 1123 try { 1124 ApplicationInfo info = getPm().getApplicationInfo(pkgName, 1125 PackageManager.GET_UNINSTALLED_PACKAGES); 1126 if (info != null) { 1127 getPm().deletePackage(pkgName, null, 0); 1128 } 1129 } catch (NameNotFoundException e) {} 1130 } 1131 1132 @LargeTest 1133 public void testManifestInstallLocationInternal() { 1134 installFromRawResource("install.apk", R.raw.install_loc_internal, 1135 0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1136 } 1137 1138 @LargeTest 1139 public void testManifestInstallLocationSdcard() { 1140 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1141 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1142 } 1143 1144 @LargeTest 1145 public void testManifestInstallLocationAuto() { 1146 installFromRawResource("install.apk", R.raw.install_loc_auto, 1147 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO); 1148 } 1149 1150 @LargeTest 1151 public void testManifestInstallLocationUnspecified() { 1152 installFromRawResource("install.apk", R.raw.install_loc_unspecified, 1153 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1154 } 1155 1156 @LargeTest 1157 public void testManifestInstallLocationFwdLockedFlagSdcard() { 1158 installFromRawResource("install.apk", R.raw.install_loc_unspecified, 1159 PackageManager.INSTALL_FORWARD_LOCK | 1160 PackageManager.INSTALL_EXTERNAL, true, true, 1161 PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1162 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1163 } 1164 1165 @LargeTest 1166 public void testManifestInstallLocationFwdLockedSdcard() { 1167 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1168 PackageManager.INSTALL_FORWARD_LOCK, true, false, 1169 -1, 1170 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1171 } 1172 1173 /* 1174 * Install a package on internal flash via PackageManager install flag. Replace 1175 * the package via flag to install on sdcard. Make sure the new flag overrides 1176 * the old install location. 1177 */ 1178 @LargeTest 1179 public void testReplaceFlagInternalSdcard() { 1180 int iFlags = 0; 1181 int rFlags = PackageManager.INSTALL_EXTERNAL; 1182 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 1183 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1184 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1185 try { 1186 assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags, receiver), true); 1187 assertInstall(ip.pkg, rFlags, ip.pkg.installLocation); 1188 } catch (Exception e) { 1189 failStr("Failed with exception : " + e); 1190 } finally { 1191 cleanUpInstall(ip); 1192 } 1193 } 1194 1195 /* 1196 * Install a package on sdcard via PackageManager install flag. Replace 1197 * the package with no flags or manifest option and make sure the old 1198 * install location is retained. 1199 */ 1200 @LargeTest 1201 public void testReplaceFlagSdcardInternal() { 1202 int iFlags = PackageManager.INSTALL_EXTERNAL; 1203 int rFlags = 0; 1204 InstallParams ip = sampleInstallFromRawResource(iFlags, false); 1205 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1206 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1207 try { 1208 assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags, receiver), true); 1209 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 1210 } catch (Exception e) { 1211 failStr("Failed with exception : " + e); 1212 } finally { 1213 cleanUpInstall(ip); 1214 } 1215 } 1216 1217 @LargeTest 1218 public void testManifestInstallLocationReplaceInternalSdcard() { 1219 int iFlags = 0; 1220 int iApk = R.raw.install_loc_internal; 1221 int rFlags = 0; 1222 int rApk = R.raw.install_loc_sdcard; 1223 InstallParams ip = installFromRawResource("install.apk", iApk, 1224 iFlags, false, 1225 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1226 GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName); 1227 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1228 try { 1229 InstallParams rp = installFromRawResource("install.apk", rApk, 1230 replaceFlags, false, 1231 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1232 assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation); 1233 } catch (Exception e) { 1234 failStr("Failed with exception : " + e); 1235 } finally { 1236 cleanUpInstall(ip); 1237 } 1238 } 1239 1240 @LargeTest 1241 public void testManifestInstallLocationReplaceSdcardInternal() { 1242 int iFlags = 0; 1243 int iApk = R.raw.install_loc_sdcard; 1244 int rFlags = 0; 1245 int rApk = R.raw.install_loc_unspecified; 1246 InstallParams ip = installFromRawResource("install.apk", iApk, 1247 iFlags, false, 1248 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1249 int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING; 1250 try { 1251 InstallParams rp = installFromRawResource("install.apk", rApk, 1252 replaceFlags, false, 1253 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1254 assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation); 1255 } catch (Exception e) { 1256 failStr("Failed with exception : " + e); 1257 } finally { 1258 cleanUpInstall(ip); 1259 } 1260 } 1261 1262 class MoveReceiver extends GenericReceiver { 1263 String pkgName; 1264 final static int INVALID = -1; 1265 final static int REMOVED = 1; 1266 final static int ADDED = 2; 1267 int removed = INVALID; 1268 1269 MoveReceiver(String pkgName) { 1270 this.pkgName = pkgName; 1271 filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 1272 filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 1273 super.setFilter(filter); 1274 } 1275 1276 public boolean notifyNow(Intent intent) { 1277 String action = intent.getAction(); 1278 Log.i(TAG, "MoveReceiver::" + action); 1279 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 1280 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1281 if (list != null) { 1282 for (String pkg : list) { 1283 if (pkg.equals(pkgName)) { 1284 removed = REMOVED; 1285 break; 1286 } 1287 } 1288 } 1289 removed = REMOVED; 1290 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 1291 if (removed != REMOVED) { 1292 return false; 1293 } 1294 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1295 if (list != null) { 1296 for (String pkg : list) { 1297 if (pkg.equals(pkgName)) { 1298 removed = ADDED; 1299 return true; 1300 } 1301 } 1302 } 1303 } 1304 return false; 1305 } 1306 } 1307 1308 private class PackageMoveObserver extends IPackageMoveObserver.Stub { 1309 public int returnCode; 1310 private boolean doneFlag = false; 1311 public String packageName; 1312 public PackageMoveObserver(String pkgName) { 1313 packageName = pkgName; 1314 } 1315 public void packageMoved(String packageName, int returnCode) { 1316 Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode); 1317 if (!packageName.equals(this.packageName)) { 1318 return; 1319 } 1320 synchronized(this) { 1321 this.returnCode = returnCode; 1322 doneFlag = true; 1323 notifyAll(); 1324 } 1325 } 1326 1327 public boolean isDone() { 1328 return doneFlag; 1329 } 1330 } 1331 1332 public boolean invokeMovePackage(String pkgName, int flags, 1333 GenericReceiver receiver) throws Exception { 1334 PackageMoveObserver observer = new PackageMoveObserver(pkgName); 1335 final boolean received = false; 1336 mContext.registerReceiver(receiver, receiver.filter); 1337 try { 1338 // Wait on observer 1339 synchronized(observer) { 1340 synchronized (receiver) { 1341 getPm().movePackage(pkgName, observer, flags); 1342 long waitTime = 0; 1343 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 1344 observer.wait(WAIT_TIME_INCR); 1345 waitTime += WAIT_TIME_INCR; 1346 } 1347 if(!observer.isDone()) { 1348 throw new Exception("Timed out waiting for pkgmove callback"); 1349 } 1350 if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) { 1351 return false; 1352 } 1353 // Verify we received the broadcast 1354 waitTime = 0; 1355 while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 1356 receiver.wait(WAIT_TIME_INCR); 1357 waitTime += WAIT_TIME_INCR; 1358 } 1359 if(!receiver.isDone()) { 1360 throw new Exception("Timed out waiting for MOVE notifications"); 1361 } 1362 return receiver.received; 1363 } 1364 } 1365 } finally { 1366 mContext.unregisterReceiver(receiver); 1367 } 1368 } 1369 private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception { 1370 PackageMoveObserver observer = new PackageMoveObserver(pkgName); 1371 try { 1372 // Wait on observer 1373 synchronized(observer) { 1374 getPm().movePackage(pkgName, observer, flags); 1375 long waitTime = 0; 1376 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { 1377 observer.wait(WAIT_TIME_INCR); 1378 waitTime += WAIT_TIME_INCR; 1379 } 1380 if(!observer.isDone()) { 1381 throw new Exception("Timed out waiting for pkgmove callback"); 1382 } 1383 assertEquals(errCode, observer.returnCode); 1384 } 1385 } finally { 1386 } 1387 return true; 1388 } 1389 1390 private int getDefaultInstallLoc() { 1391 int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO; 1392 try { 1393 origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.DEFAULT_INSTALL_LOCATION); 1394 } catch (SettingNotFoundException e1) { 1395 } 1396 return origDefaultLoc; 1397 } 1398 1399 private void setInstallLoc(int loc) { 1400 Settings.System.putInt(mContext.getContentResolver(), 1401 Settings.Secure.DEFAULT_INSTALL_LOCATION, loc); 1402 } 1403 /* 1404 * Tests for moving apps between internal and external storage 1405 */ 1406 /* 1407 * Utility function that reads a apk bundled as a raw resource 1408 * copies it into own data directory and invokes 1409 * PackageManager api to install first and then replace it 1410 * again. 1411 */ 1412 1413 private void moveFromRawResource(String outFileName, 1414 int rawResId, int installFlags, int moveFlags, boolean cleanUp, 1415 boolean fail, int result) { 1416 int origDefaultLoc = getDefaultInstallLoc(); 1417 InstallParams ip = null; 1418 try { 1419 setInstallLoc(PackageHelper.APP_INSTALL_AUTO); 1420 // Install first 1421 ip = installFromRawResource("install.apk", rawResId, installFlags, false, 1422 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1423 ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1424 if (fail) { 1425 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); 1426 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1427 assertNotNull(info); 1428 assertEquals(oldAppInfo.flags, info.flags); 1429 } else { 1430 // Create receiver based on expRetCode 1431 MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); 1432 boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, 1433 receiver); 1434 assertTrue(retCode); 1435 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); 1436 assertNotNull("ApplicationInfo for recently installed application should exist", 1437 info); 1438 if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) { 1439 assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set", 1440 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0); 1441 assertTrue("ApplicationInfo.nativeLibraryDir should start with " + info.dataDir, 1442 info.nativeLibraryDir.startsWith(info.dataDir)); 1443 } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){ 1444 assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set", 1445 (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); 1446 assertTrue("ApplicationInfo.nativeLibraryDir should start with " + SECURE_CONTAINERS_PREFIX, 1447 info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); 1448 final File nativeLibSymLink = new File(info.dataDir, "lib"); 1449 assertTrue("The data directory should have a 'lib' symlink that points to the ASEC container", 1450 nativeLibSymLink.getCanonicalPath().startsWith(SECURE_CONTAINERS_PREFIX)); 1451 } 1452 } 1453 } catch (NameNotFoundException e) { 1454 failStr("Pkg hasnt been installed correctly"); 1455 } catch (Exception e) { 1456 failStr("Failed with exception : " + e); 1457 } finally { 1458 if (ip != null) { 1459 cleanUpInstall(ip); 1460 } 1461 // Restore default install location 1462 setInstallLoc(origDefaultLoc); 1463 } 1464 } 1465 private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail, 1466 int result) { 1467 moveFromRawResource("install.apk", 1468 R.raw.install, installFlags, moveFlags, true, 1469 fail, result); 1470 } 1471 1472 @LargeTest 1473 public void testMoveAppInternalToExternal() { 1474 int installFlags = PackageManager.INSTALL_INTERNAL; 1475 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1476 boolean fail = false; 1477 int result = PackageManager.MOVE_SUCCEEDED; 1478 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1479 } 1480 1481 @LargeTest 1482 public void testMoveAppInternalToInternal() { 1483 int installFlags = PackageManager.INSTALL_INTERNAL; 1484 int moveFlags = PackageManager.MOVE_INTERNAL; 1485 boolean fail = true; 1486 int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; 1487 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1488 } 1489 1490 @LargeTest 1491 public void testMoveAppExternalToExternal() { 1492 int installFlags = PackageManager.INSTALL_EXTERNAL; 1493 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1494 boolean fail = true; 1495 int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; 1496 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1497 } 1498 @LargeTest 1499 public void testMoveAppExternalToInternal() { 1500 int installFlags = PackageManager.INSTALL_EXTERNAL; 1501 int moveFlags = PackageManager.MOVE_INTERNAL; 1502 boolean fail = false; 1503 int result = PackageManager.MOVE_SUCCEEDED; 1504 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1505 } 1506 @LargeTest 1507 public void testMoveAppForwardLocked() { 1508 int installFlags = PackageManager.INSTALL_FORWARD_LOCK; 1509 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1510 boolean fail = true; 1511 int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED; 1512 sampleMoveFromRawResource(installFlags, moveFlags, fail, result); 1513 } 1514 @LargeTest 1515 public void testMoveAppFailInternalToExternalDelete() { 1516 int installFlags = 0; 1517 int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; 1518 boolean fail = true; 1519 final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST; 1520 1521 int rawResId = R.raw.install; 1522 int origDefaultLoc = getDefaultInstallLoc(); 1523 InstallParams ip = null; 1524 try { 1525 PackageManager pm = getPm(); 1526 setInstallLoc(PackageHelper.APP_INSTALL_AUTO); 1527 // Install first 1528 ip = installFromRawResource("install.apk", R.raw.install, installFlags, false, 1529 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 1530 // Delete the package now retaining data. 1531 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 1532 invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver); 1533 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); 1534 } catch (Exception e) { 1535 failStr(e); 1536 } finally { 1537 if (ip != null) { 1538 cleanUpInstall(ip); 1539 } 1540 // Restore default install location 1541 setInstallLoc(origDefaultLoc); 1542 } 1543 } 1544 /* 1545 * Test that an install error code is returned when media is unmounted 1546 * and package installed on sdcard via package manager flag. 1547 */ 1548 @LargeTest 1549 public void testInstallSdcardUnmount() { 1550 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1551 try { 1552 // Unmount sdcard 1553 assertTrue(unmountMedia()); 1554 // Try to install and make sure an error code is returned. 1555 installFromRawResource("install.apk", R.raw.install, 1556 PackageManager.INSTALL_EXTERNAL, false, 1557 true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE, 1558 PackageInfo.INSTALL_LOCATION_AUTO); 1559 } finally { 1560 // Restore original media state 1561 if (origState) { 1562 mountMedia(); 1563 } else { 1564 unmountMedia(); 1565 } 1566 } 1567 } 1568 1569 /* 1570 * Unmount sdcard. Try installing an app with manifest option to install 1571 * on sdcard. Make sure it gets installed on internal flash. 1572 */ 1573 @LargeTest 1574 public void testInstallManifestSdcardUnmount() { 1575 boolean origState = checkMediaState(Environment.MEDIA_MOUNTED); 1576 try { 1577 // Unmount sdcard 1578 assertTrue(unmountMedia()); 1579 InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard); 1580 installFromRawResource(ip, 0, true, false, -1, 1581 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1582 } finally { 1583 // Restore original media state 1584 if (origState) { 1585 mountMedia(); 1586 } else { 1587 unmountMedia(); 1588 } 1589 } 1590 } 1591 1592 /*---------- Recommended install location tests ----*/ 1593 /* Precedence: FlagManifestExistingUser 1594 * PrecedenceSuffixes: 1595 * Flag : FlagI, FlagE, FlagF 1596 * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option. 1597 * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option. 1598 * Existing: Existing suffix absent if not existing. 1599 * User: UserI, UserE, UserA, User suffix absent if not existing. 1600 * 1601 */ 1602 /* 1603 * Install an app on internal flash 1604 */ 1605 @LargeTest 1606 public void testFlagI() { 1607 sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true); 1608 } 1609 /* 1610 * Install an app on sdcard. 1611 */ 1612 @LargeTest 1613 public void testFlagE() { 1614 sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true); 1615 } 1616 1617 /* 1618 * Install an app on sdcard. 1619 */ 1620 @LargeTest 1621 public void testFlagF() { 1622 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true); 1623 } 1624 /* 1625 * Install an app with both internal and external flags set. should fail 1626 */ 1627 @LargeTest 1628 public void testFlagIE() { 1629 installFromRawResource("install.apk", R.raw.install, 1630 PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL, 1631 false, 1632 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1633 PackageInfo.INSTALL_LOCATION_AUTO); 1634 } 1635 1636 /* 1637 * Install an app with both internal and external flags set. should fail 1638 */ 1639 @LargeTest 1640 public void testFlagIF() { 1641 sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK | 1642 PackageManager.INSTALL_INTERNAL, true); 1643 } 1644 /* 1645 * Install an app with both internal and external flags set. should fail 1646 */ 1647 @LargeTest 1648 public void testFlagEF() { 1649 installFromRawResource("install.apk", R.raw.install, 1650 PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL, 1651 false, 1652 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1653 PackageInfo.INSTALL_LOCATION_AUTO); 1654 } 1655 /* 1656 * Install an app with both internal and external flags set. should fail 1657 */ 1658 @LargeTest 1659 public void testFlagIEF() { 1660 installFromRawResource("install.apk", R.raw.install, 1661 PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL | 1662 PackageManager.INSTALL_EXTERNAL, 1663 false, 1664 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1665 PackageInfo.INSTALL_LOCATION_AUTO); 1666 } 1667 /* 1668 * Install an app with both internal and manifest option set. 1669 * should install on internal. 1670 */ 1671 @LargeTest 1672 public void testFlagIManifestI() { 1673 installFromRawResource("install.apk", R.raw.install_loc_internal, 1674 PackageManager.INSTALL_INTERNAL, 1675 true, 1676 false, -1, 1677 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1678 } 1679 /* 1680 * Install an app with both internal and manifest preference for 1681 * preferExternal. Should install on internal. 1682 */ 1683 @LargeTest 1684 public void testFlagIManifestE() { 1685 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1686 PackageManager.INSTALL_INTERNAL, 1687 true, 1688 false, -1, 1689 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1690 } 1691 /* 1692 * Install an app with both internal and manifest preference for 1693 * auto. should install internal. 1694 */ 1695 @LargeTest 1696 public void testFlagIManifestA() { 1697 installFromRawResource("install.apk", R.raw.install_loc_auto, 1698 PackageManager.INSTALL_INTERNAL, 1699 true, 1700 false, -1, 1701 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1702 } 1703 /* 1704 * Install an app with both external and manifest option set. 1705 * should install externally. 1706 */ 1707 @LargeTest 1708 public void testFlagEManifestI() { 1709 installFromRawResource("install.apk", R.raw.install_loc_internal, 1710 PackageManager.INSTALL_EXTERNAL, 1711 true, 1712 false, -1, 1713 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1714 } 1715 /* 1716 * Install an app with both external and manifest preference for 1717 * preferExternal. Should install externally. 1718 */ 1719 @LargeTest 1720 public void testFlagEManifestE() { 1721 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1722 PackageManager.INSTALL_EXTERNAL, 1723 true, 1724 false, -1, 1725 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1726 } 1727 /* 1728 * Install an app with both external and manifest preference for 1729 * auto. should install on external media. 1730 */ 1731 @LargeTest 1732 public void testFlagEManifestA() { 1733 installFromRawResource("install.apk", R.raw.install_loc_auto, 1734 PackageManager.INSTALL_EXTERNAL, 1735 true, 1736 false, -1, 1737 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1738 } 1739 /* 1740 * Install an app with fwd locked flag set and install location set to 1741 * internal. should install internally. 1742 */ 1743 @LargeTest 1744 public void testFlagFManifestI() { 1745 installFromRawResource("install.apk", R.raw.install_loc_internal, 1746 PackageManager.INSTALL_EXTERNAL, 1747 true, 1748 false, -1, 1749 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1750 } 1751 /* 1752 * Install an app with fwd locked flag set and install location set to 1753 * preferExternal. should install internally. 1754 */ 1755 @LargeTest 1756 public void testFlagFManifestE() { 1757 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1758 PackageManager.INSTALL_EXTERNAL, 1759 true, 1760 false, -1, 1761 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1762 } 1763 /* 1764 * Install an app with fwd locked flag set and install location set to 1765 * auto. should install internally. 1766 */ 1767 @LargeTest 1768 public void testFlagFManifestA() { 1769 installFromRawResource("install.apk", R.raw.install_loc_auto, 1770 PackageManager.INSTALL_EXTERNAL, 1771 true, 1772 false, -1, 1773 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1774 } 1775 /* The following test functions verify install location for existing apps. 1776 * ie existing app can be installed internally or externally. If install 1777 * flag is explicitly set it should override current location. If manifest location 1778 * is set, that should over ride current location too. if not the existing install 1779 * location should be honoured. 1780 * testFlagI/E/F/ExistingI/E - 1781 */ 1782 @LargeTest 1783 public void testFlagIExistingI() { 1784 int iFlags = PackageManager.INSTALL_INTERNAL; 1785 int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 1786 // First install. 1787 installFromRawResource("install.apk", R.raw.install, 1788 iFlags, 1789 false, 1790 false, -1, 1791 -1); 1792 // Replace now 1793 installFromRawResource("install.apk", R.raw.install, 1794 rFlags, 1795 true, 1796 false, -1, 1797 -1); 1798 } 1799 @LargeTest 1800 public void testFlagIExistingE() { 1801 int iFlags = PackageManager.INSTALL_EXTERNAL; 1802 int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 1803 // First install. 1804 installFromRawResource("install.apk", R.raw.install, 1805 iFlags, 1806 false, 1807 false, -1, 1808 -1); 1809 // Replace now 1810 installFromRawResource("install.apk", R.raw.install, 1811 rFlags, 1812 true, 1813 false, -1, 1814 -1); 1815 } 1816 @LargeTest 1817 public void testFlagEExistingI() { 1818 int iFlags = PackageManager.INSTALL_INTERNAL; 1819 int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 1820 // First install. 1821 installFromRawResource("install.apk", R.raw.install, 1822 iFlags, 1823 false, 1824 false, -1, 1825 -1); 1826 // Replace now 1827 installFromRawResource("install.apk", R.raw.install, 1828 rFlags, 1829 true, 1830 false, -1, 1831 -1); 1832 } 1833 @LargeTest 1834 public void testFlagEExistingE() { 1835 int iFlags = PackageManager.INSTALL_EXTERNAL; 1836 int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING; 1837 // First install. 1838 installFromRawResource("install.apk", R.raw.install, 1839 iFlags, 1840 false, 1841 false, -1, 1842 -1); 1843 // Replace now 1844 installFromRawResource("install.apk", R.raw.install, 1845 rFlags, 1846 true, 1847 false, -1, 1848 -1); 1849 } 1850 @LargeTest 1851 public void testFlagFExistingI() { 1852 int iFlags = PackageManager.INSTALL_INTERNAL; 1853 int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING; 1854 // First install. 1855 installFromRawResource("install.apk", R.raw.install, 1856 iFlags, 1857 false, 1858 false, -1, 1859 -1); 1860 // Replace now 1861 installFromRawResource("install.apk", R.raw.install, 1862 rFlags, 1863 true, 1864 false, -1, 1865 -1); 1866 } 1867 @LargeTest 1868 public void testFlagFExistingE() { 1869 int iFlags = PackageManager.INSTALL_EXTERNAL; 1870 int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING; 1871 // First install. 1872 installFromRawResource("install.apk", R.raw.install, 1873 iFlags, 1874 false, 1875 false, -1, 1876 -1); 1877 // Replace now 1878 installFromRawResource("install.apk", R.raw.install, 1879 rFlags, 1880 true, 1881 false, -1, 1882 -1); 1883 } 1884 /* 1885 * The following set of tests verify the installation of apps with 1886 * install location attribute set to internalOnly, preferExternal and auto. 1887 * The manifest option should dictate the install location. 1888 * public void testManifestI/E/A 1889 * TODO out of memory fall back behaviour. 1890 */ 1891 @LargeTest 1892 public void testManifestI() { 1893 installFromRawResource("install.apk", R.raw.install_loc_internal, 1894 0, 1895 true, 1896 false, -1, 1897 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1898 } 1899 @LargeTest 1900 public void testManifestE() { 1901 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1902 0, 1903 true, 1904 false, -1, 1905 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1906 } 1907 @LargeTest 1908 public void testManifestA() { 1909 installFromRawResource("install.apk", R.raw.install_loc_auto, 1910 0, 1911 true, 1912 false, -1, 1913 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1914 } 1915 /* 1916 * The following set of tests verify the installation of apps 1917 * with install location attribute set to internalOnly, preferExternal and auto 1918 * for already existing apps. The manifest option should take precedence. 1919 * TODO add out of memory fall back behaviour. 1920 * testManifestI/E/AExistingI/E 1921 */ 1922 @LargeTest 1923 public void testManifestIExistingI() { 1924 int iFlags = PackageManager.INSTALL_INTERNAL; 1925 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 1926 // First install. 1927 installFromRawResource("install.apk", R.raw.install, 1928 iFlags, 1929 false, 1930 false, -1, 1931 -1); 1932 // Replace now 1933 installFromRawResource("install.apk", R.raw.install_loc_internal, 1934 rFlags, 1935 true, 1936 false, -1, 1937 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1938 } 1939 @LargeTest 1940 public void testManifestIExistingE() { 1941 int iFlags = PackageManager.INSTALL_EXTERNAL; 1942 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 1943 // First install. 1944 installFromRawResource("install.apk", R.raw.install, 1945 iFlags, 1946 false, 1947 false, -1, 1948 -1); 1949 // Replace now 1950 installFromRawResource("install.apk", R.raw.install_loc_internal, 1951 rFlags, 1952 true, 1953 false, -1, 1954 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 1955 } 1956 @LargeTest 1957 public void testManifestEExistingI() { 1958 int iFlags = PackageManager.INSTALL_INTERNAL; 1959 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 1960 // First install. 1961 installFromRawResource("install.apk", R.raw.install, 1962 iFlags, 1963 false, 1964 false, -1, 1965 -1); 1966 // Replace now 1967 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1968 rFlags, 1969 true, 1970 false, -1, 1971 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1972 } 1973 @LargeTest 1974 public void testManifestEExistingE() { 1975 int iFlags = PackageManager.INSTALL_EXTERNAL; 1976 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 1977 // First install. 1978 installFromRawResource("install.apk", R.raw.install, 1979 iFlags, 1980 false, 1981 false, -1, 1982 -1); 1983 // Replace now 1984 installFromRawResource("install.apk", R.raw.install_loc_sdcard, 1985 rFlags, 1986 true, 1987 false, -1, 1988 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 1989 } 1990 @LargeTest 1991 public void testManifestAExistingI() { 1992 int iFlags = PackageManager.INSTALL_INTERNAL; 1993 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 1994 // First install. 1995 installFromRawResource("install.apk", R.raw.install, 1996 iFlags, 1997 false, 1998 false, -1, 1999 -1); 2000 // Replace now 2001 installFromRawResource("install.apk", R.raw.install_loc_auto, 2002 rFlags, 2003 true, 2004 false, -1, 2005 PackageInfo.INSTALL_LOCATION_AUTO); 2006 } 2007 @LargeTest 2008 public void testManifestAExistingE() { 2009 int iFlags = PackageManager.INSTALL_EXTERNAL; 2010 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2011 // First install. 2012 installFromRawResource("install.apk", R.raw.install, 2013 iFlags, 2014 false, 2015 false, -1, 2016 -1); 2017 // Replace now 2018 installFromRawResource("install.apk", R.raw.install_loc_auto, 2019 rFlags, 2020 true, 2021 false, -1, 2022 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2023 } 2024 /* 2025 * The following set of tests check install location for existing 2026 * application based on user setting. 2027 */ 2028 private int getExpectedInstallLocation(int userSetting) { 2029 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2030 boolean enable = getUserSettingSetInstallLocation(); 2031 if (enable) { 2032 if (userSetting == PackageHelper.APP_INSTALL_AUTO) { 2033 iloc = PackageInfo.INSTALL_LOCATION_AUTO; 2034 } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) { 2035 iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL; 2036 } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) { 2037 iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY; 2038 } 2039 } 2040 return iloc; 2041 } 2042 private void setExistingXUserX(int userSetting, int iFlags, int iloc) { 2043 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2044 // First install. 2045 installFromRawResource("install.apk", R.raw.install, 2046 iFlags, 2047 false, 2048 false, -1, 2049 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2050 int origSetting = getDefaultInstallLoc(); 2051 try { 2052 // Set user setting 2053 setInstallLoc(userSetting); 2054 // Replace now 2055 installFromRawResource("install.apk", R.raw.install, 2056 rFlags, 2057 true, 2058 false, -1, 2059 iloc); 2060 } finally { 2061 setInstallLoc(origSetting); 2062 } 2063 } 2064 @LargeTest 2065 public void testExistingIUserI() { 2066 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2067 int iFlags = PackageManager.INSTALL_INTERNAL; 2068 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2069 } 2070 @LargeTest 2071 public void testExistingIUserE() { 2072 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2073 int iFlags = PackageManager.INSTALL_INTERNAL; 2074 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2075 } 2076 @LargeTest 2077 public void testExistingIUserA() { 2078 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2079 int iFlags = PackageManager.INSTALL_INTERNAL; 2080 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2081 } 2082 @LargeTest 2083 public void testExistingEUserI() { 2084 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2085 int iFlags = PackageManager.INSTALL_EXTERNAL; 2086 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2087 } 2088 @LargeTest 2089 public void testExistingEUserE() { 2090 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2091 int iFlags = PackageManager.INSTALL_EXTERNAL; 2092 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2093 } 2094 @LargeTest 2095 public void testExistingEUserA() { 2096 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2097 int iFlags = PackageManager.INSTALL_EXTERNAL; 2098 setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); 2099 } 2100 /* 2101 * The following set of tests verify that the user setting defines 2102 * the install location. 2103 * 2104 */ 2105 private boolean getUserSettingSetInstallLocation() { 2106 try { 2107 return Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION) != 0; 2108 2109 } catch (SettingNotFoundException e1) { 2110 } 2111 return false; 2112 } 2113 2114 private void setUserSettingSetInstallLocation(boolean value) { 2115 Settings.System.putInt(mContext.getContentResolver(), 2116 Settings.Secure.SET_INSTALL_LOCATION, value ? 1 : 0); 2117 } 2118 private void setUserX(boolean enable, int userSetting, int iloc) { 2119 boolean origUserSetting = getUserSettingSetInstallLocation(); 2120 int origSetting = getDefaultInstallLoc(); 2121 try { 2122 setUserSettingSetInstallLocation(enable); 2123 // Set user setting 2124 setInstallLoc(userSetting); 2125 // Replace now 2126 installFromRawResource("install.apk", R.raw.install, 2127 0, 2128 true, 2129 false, -1, 2130 iloc); 2131 } finally { 2132 // Restore original setting 2133 setUserSettingSetInstallLocation(origUserSetting); 2134 setInstallLoc(origSetting); 2135 } 2136 } 2137 @LargeTest 2138 public void testUserI() { 2139 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2140 int iloc = getExpectedInstallLocation(userSetting); 2141 setUserX(true, userSetting, iloc); 2142 } 2143 @LargeTest 2144 public void testUserE() { 2145 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2146 int iloc = getExpectedInstallLocation(userSetting); 2147 setUserX(true, userSetting, iloc); 2148 } 2149 @LargeTest 2150 public void testUserA() { 2151 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2152 int iloc = getExpectedInstallLocation(userSetting); 2153 setUserX(true, userSetting, iloc); 2154 } 2155 /* 2156 * The following set of tests turn on/off the basic 2157 * user setting for turning on install location. 2158 */ 2159 @LargeTest 2160 public void testUserPrefOffUserI() { 2161 int userSetting = PackageHelper.APP_INSTALL_INTERNAL; 2162 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2163 setUserX(false, userSetting, iloc); 2164 } 2165 @LargeTest 2166 public void testUserPrefOffUserE() { 2167 int userSetting = PackageHelper.APP_INSTALL_EXTERNAL; 2168 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2169 setUserX(false, userSetting, iloc); 2170 } 2171 @LargeTest 2172 public void testUserPrefOffA() { 2173 int userSetting = PackageHelper.APP_INSTALL_AUTO; 2174 int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; 2175 setUserX(false, userSetting, iloc); 2176 } 2177 2178 static final String BASE_PERMISSIONS_DEFINED[] = new String[] { 2179 PERM_PACKAGE, "com.android.unit_tests.install_decl_perm", 2180 PERM_DEFINED, 2181 "com.android.frameworks.coretests.NORMAL", 2182 "com.android.frameworks.coretests.DANGEROUS", 2183 "com.android.frameworks.coretests.SIGNATURE", 2184 }; 2185 2186 static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] { 2187 PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm", 2188 PERM_UNDEFINED, 2189 "com.android.frameworks.coretests.NORMAL", 2190 "com.android.frameworks.coretests.DANGEROUS", 2191 "com.android.frameworks.coretests.SIGNATURE", 2192 }; 2193 2194 static final String BASE_PERMISSIONS_USED[] = new String[] { 2195 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2196 PERM_USED, 2197 "com.android.frameworks.coretests.NORMAL", 2198 "com.android.frameworks.coretests.DANGEROUS", 2199 "com.android.frameworks.coretests.SIGNATURE", 2200 }; 2201 2202 static final String BASE_PERMISSIONS_NOTUSED[] = new String[] { 2203 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2204 PERM_NOTUSED, 2205 "com.android.frameworks.coretests.NORMAL", 2206 "com.android.frameworks.coretests.DANGEROUS", 2207 "com.android.frameworks.coretests.SIGNATURE", 2208 }; 2209 2210 static final String BASE_PERMISSIONS_SIGUSED[] = new String[] { 2211 PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good", 2212 PERM_USED, 2213 "com.android.frameworks.coretests.SIGNATURE", 2214 PERM_NOTUSED, 2215 "com.android.frameworks.coretests.NORMAL", 2216 "com.android.frameworks.coretests.DANGEROUS", 2217 }; 2218 2219 /* 2220 * Ensure that permissions are properly declared. 2221 */ 2222 @LargeTest 2223 public void testInstallDeclaresPermissions() { 2224 InstallParams ip = null; 2225 InstallParams ip2 = null; 2226 try { 2227 // **: Upon installing a package, are its declared permissions published? 2228 2229 int iFlags = PackageManager.INSTALL_INTERNAL; 2230 int iApk = R.raw.install_decl_perm; 2231 ip = installFromRawResource("install.apk", iApk, 2232 iFlags, false, 2233 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2234 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2235 assertPermissions(BASE_PERMISSIONS_DEFINED); 2236 2237 // **: Upon installing package, are its permissions granted? 2238 2239 int i2Flags = PackageManager.INSTALL_INTERNAL; 2240 int i2Apk = R.raw.install_use_perm_good; 2241 ip2 = installFromRawResource("install2.apk", i2Apk, 2242 i2Flags, false, 2243 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2244 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2245 assertPermissions(BASE_PERMISSIONS_USED); 2246 2247 // **: Upon removing but not deleting, are permissions retained? 2248 2249 GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName); 2250 2251 try { 2252 invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver); 2253 } catch (Exception e) { 2254 failStr(e); 2255 } 2256 assertPermissions(BASE_PERMISSIONS_DEFINED); 2257 assertPermissions(BASE_PERMISSIONS_USED); 2258 2259 // **: Upon re-installing, are permissions retained? 2260 2261 ip = installFromRawResource("install.apk", iApk, 2262 iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false, 2263 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2264 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2265 assertPermissions(BASE_PERMISSIONS_DEFINED); 2266 assertPermissions(BASE_PERMISSIONS_USED); 2267 2268 // **: Upon deleting package, are all permissions removed? 2269 2270 try { 2271 invokeDeletePackage(ip.pkg.packageName, 0, receiver); 2272 ip = null; 2273 } catch (Exception e) { 2274 failStr(e); 2275 } 2276 assertPermissions(BASE_PERMISSIONS_UNDEFINED); 2277 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2278 2279 // **: Delete package using permissions; nothing to check here. 2280 2281 GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName); 2282 try { 2283 invokeDeletePackage(ip2.pkg.packageName, 0, receiver); 2284 ip2 = null; 2285 } catch (Exception e) { 2286 failStr(e); 2287 } 2288 2289 // **: Re-install package using permissions; no permissions can be granted. 2290 2291 ip2 = installFromRawResource("install2.apk", i2Apk, 2292 i2Flags, false, 2293 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2294 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2295 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2296 2297 // **: Upon installing declaring package, are sig permissions granted 2298 // to other apps (but not other perms)? 2299 2300 ip = installFromRawResource("install.apk", iApk, 2301 iFlags, false, 2302 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2303 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2304 assertPermissions(BASE_PERMISSIONS_DEFINED); 2305 assertPermissions(BASE_PERMISSIONS_SIGUSED); 2306 2307 // **: Re-install package using permissions; are all permissions granted? 2308 2309 ip2 = installFromRawResource("install2.apk", i2Apk, 2310 i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false, 2311 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2312 assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation); 2313 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2314 2315 // **: Upon deleting package, are all permissions removed? 2316 2317 try { 2318 invokeDeletePackage(ip.pkg.packageName, 0, receiver); 2319 ip = null; 2320 } catch (Exception e) { 2321 failStr(e); 2322 } 2323 assertPermissions(BASE_PERMISSIONS_UNDEFINED); 2324 assertPermissions(BASE_PERMISSIONS_NOTUSED); 2325 2326 // **: Delete package using permissions; nothing to check here. 2327 2328 try { 2329 invokeDeletePackage(ip2.pkg.packageName, 0, receiver); 2330 ip2 = null; 2331 } catch (Exception e) { 2332 failStr(e); 2333 } 2334 2335 } finally { 2336 if (ip2 != null) { 2337 cleanUpInstall(ip2); 2338 } 2339 if (ip != null) { 2340 cleanUpInstall(ip); 2341 } 2342 } 2343 } 2344 2345 /* 2346 * Ensure that permissions are properly declared. 2347 */ 2348 @LargeTest 2349 public void testInstallOnSdPermissionsUnmount() { 2350 InstallParams ip = null; 2351 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2352 try { 2353 // **: Upon installing a package, are its declared permissions published? 2354 int iFlags = PackageManager.INSTALL_INTERNAL; 2355 int iApk = R.raw.install_decl_perm; 2356 ip = installFromRawResource("install.apk", iApk, 2357 iFlags, false, 2358 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2359 assertInstall(ip.pkg, iFlags, ip.pkg.installLocation); 2360 assertPermissions(BASE_PERMISSIONS_DEFINED); 2361 // Unmount media here 2362 assertTrue(unmountMedia()); 2363 // Mount media again 2364 mountMedia(); 2365 //Check permissions now 2366 assertPermissions(BASE_PERMISSIONS_DEFINED); 2367 } finally { 2368 if (ip != null) { 2369 cleanUpInstall(ip); 2370 } 2371 } 2372 } 2373 2374 /* This test creates a stale container via MountService and then installs 2375 * a package and verifies that the stale container is cleaned up and install 2376 * is successful. 2377 * Please note that this test is very closely tied to the framework's 2378 * naming convention for secure containers. 2379 */ 2380 @LargeTest 2381 public void testInstallSdcardStaleContainer() { 2382 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2383 try { 2384 // Mount media first 2385 mountMedia(); 2386 String outFileName = "install.apk"; 2387 int rawResId = R.raw.install; 2388 PackageManager pm = mContext.getPackageManager(); 2389 File filesDir = mContext.getFilesDir(); 2390 File outFile = new File(filesDir, outFileName); 2391 Uri packageURI = getInstallablePackage(rawResId, outFile); 2392 PackageParser.Package pkg = parsePackage(packageURI); 2393 assertNotNull(pkg); 2394 // Install an app on sdcard. 2395 installFromRawResource(outFileName, rawResId, 2396 PackageManager.INSTALL_EXTERNAL, false, 2397 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2398 // Unmount sdcard 2399 unmountMedia(); 2400 // Delete the app on sdcard to leave a stale container on sdcard. 2401 GenericReceiver receiver = new DeleteReceiver(pkg.packageName); 2402 assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver)); 2403 mountMedia(); 2404 // Reinstall the app and make sure it gets installed. 2405 installFromRawResource(outFileName, rawResId, 2406 PackageManager.INSTALL_EXTERNAL, true, 2407 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2408 } catch (Exception e) { 2409 failStr(e.getMessage()); 2410 } finally { 2411 if (origMediaState) { 2412 mountMedia(); 2413 } else { 2414 unmountMedia(); 2415 } 2416 2417 } 2418 } 2419 2420 /* This test installs an application on sdcard and unmounts media. 2421 * The app is then re-installed on internal storage. The sdcard is mounted 2422 * and verified that the re-installation on internal storage takes precedence. 2423 */ 2424 @LargeTest 2425 public void testInstallSdcardStaleContainerReinstall() { 2426 boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED); 2427 try { 2428 // Mount media first 2429 mountMedia(); 2430 String outFileName = "install.apk"; 2431 int rawResId = R.raw.install; 2432 PackageManager pm = mContext.getPackageManager(); 2433 File filesDir = mContext.getFilesDir(); 2434 File outFile = new File(filesDir, outFileName); 2435 Uri packageURI = getInstallablePackage(rawResId, outFile); 2436 PackageParser.Package pkg = parsePackage(packageURI); 2437 assertNotNull(pkg); 2438 // Install an app on sdcard. 2439 installFromRawResource(outFileName, rawResId, 2440 PackageManager.INSTALL_EXTERNAL, false, 2441 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2442 // Unmount sdcard 2443 unmountMedia(); 2444 // Reinstall the app and make sure it gets installed on internal storage. 2445 installFromRawResource(outFileName, rawResId, 2446 PackageManager.INSTALL_REPLACE_EXISTING, false, 2447 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2448 mountMedia(); 2449 // Verify that the app installed is on internal storage. 2450 assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); 2451 } catch (Exception e) { 2452 failStr(e.getMessage()); 2453 } finally { 2454 if (origMediaState) { 2455 mountMedia(); 2456 } else { 2457 unmountMedia(); 2458 } 2459 } 2460 } 2461 /* 2462 * The following series of tests are related to upgrading apps with 2463 * different certificates. 2464 */ 2465 private int APP1_UNSIGNED = R.raw.install_app1_unsigned; 2466 private int APP1_CERT1 = R.raw.install_app1_cert1; 2467 private int APP1_CERT2 = R.raw.install_app1_cert2; 2468 private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2; 2469 private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4; 2470 private int APP1_CERT3 = R.raw.install_app1_cert3; 2471 private int APP2_UNSIGNED = R.raw.install_app2_unsigned; 2472 private int APP2_CERT1 = R.raw.install_app2_cert1; 2473 private int APP2_CERT2 = R.raw.install_app2_cert2; 2474 private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2; 2475 private int APP2_CERT3 = R.raw.install_app2_cert3; 2476 2477 private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode) { 2478 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2479 String apk1Name = "install1.apk"; 2480 String apk2Name = "install2.apk"; 2481 PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1); 2482 try { 2483 InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false, 2484 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2485 installFromRawResource(apk2Name, apk2, rFlags, false, 2486 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2487 return ip; 2488 } catch (Exception e) { 2489 failStr(e.getMessage()); 2490 } finally { 2491 if (cleanUp) { 2492 cleanUpInstall(pkg1.packageName); 2493 } 2494 } 2495 return null; 2496 } 2497 /* 2498 * Test that an app signed with two certificates can be upgraded by the 2499 * same app signed with two certificates. 2500 */ 2501 @LargeTest 2502 public void testReplaceMatchAllCerts() { 2503 replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1); 2504 } 2505 2506 /* 2507 * Test that an app signed with two certificates cannot be upgraded 2508 * by an app signed with a different certificate. 2509 */ 2510 @LargeTest 2511 public void testReplaceMatchNoCerts1() { 2512 replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true, 2513 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2514 } 2515 /* 2516 * Test that an app signed with two certificates cannot be upgraded 2517 * by an app signed with a different certificate. 2518 */ 2519 @LargeTest 2520 public void testReplaceMatchNoCerts2() { 2521 replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true, 2522 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2523 } 2524 /* 2525 * Test that an app signed with two certificates cannot be upgraded by 2526 * an app signed with a subset of initial certificates. 2527 */ 2528 @LargeTest 2529 public void testReplaceMatchSomeCerts1() { 2530 replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true, 2531 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2532 } 2533 /* 2534 * Test that an app signed with two certificates cannot be upgraded by 2535 * an app signed with the last certificate. 2536 */ 2537 @LargeTest 2538 public void testReplaceMatchSomeCerts2() { 2539 replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true, 2540 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2541 } 2542 /* 2543 * Test that an app signed with a certificate can be upgraded by app 2544 * signed with a superset of certificates. 2545 */ 2546 @LargeTest 2547 public void testReplaceMatchMoreCerts() { 2548 replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true, 2549 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2550 } 2551 /* 2552 * Test that an app signed with a certificate can be upgraded by app 2553 * signed with a superset of certificates. Then verify that the an app 2554 * signed with the original set of certs cannot upgrade the new one. 2555 */ 2556 @LargeTest 2557 public void testReplaceMatchMoreCertsReplaceSomeCerts() { 2558 InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true, 2559 PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES); 2560 try { 2561 int rFlags = PackageManager.INSTALL_REPLACE_EXISTING; 2562 installFromRawResource("install.apk", APP1_CERT1, rFlags, false, 2563 false, -1, 2564 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2565 } catch (Exception e) { 2566 failStr(e.getMessage()); 2567 } finally { 2568 if (ip != null) { 2569 cleanUpInstall(ip); 2570 } 2571 } 2572 } 2573 /* 2574 * The following tests are related to testing the checkSignatures 2575 * api. 2576 */ 2577 private void checkSignatures(int apk1, int apk2, int expMatchResult) { 2578 checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult); 2579 } 2580 @LargeTest 2581 public void testCheckSignaturesAllMatch() { 2582 int apk1 = APP1_CERT1_CERT2; 2583 int apk2 = APP2_CERT1_CERT2; 2584 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 2585 } 2586 @LargeTest 2587 public void testCheckSignaturesNoMatch() { 2588 int apk1 = APP1_CERT1; 2589 int apk2 = APP2_CERT2; 2590 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 2591 } 2592 @LargeTest 2593 public void testCheckSignaturesSomeMatch1() { 2594 int apk1 = APP1_CERT1_CERT2; 2595 int apk2 = APP2_CERT1; 2596 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 2597 } 2598 @LargeTest 2599 public void testCheckSignaturesSomeMatch2() { 2600 int apk1 = APP1_CERT1_CERT2; 2601 int apk2 = APP2_CERT2; 2602 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 2603 } 2604 @LargeTest 2605 public void testCheckSignaturesMoreMatch() { 2606 int apk1 = APP1_CERT1; 2607 int apk2 = APP2_CERT1_CERT2; 2608 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH); 2609 } 2610 @LargeTest 2611 public void testCheckSignaturesUnknown() { 2612 int apk1 = APP1_CERT1_CERT2; 2613 int apk2 = APP2_CERT1_CERT2; 2614 String apk1Name = "install1.apk"; 2615 String apk2Name = "install2.apk"; 2616 InstallParams ip1 = null; 2617 2618 try { 2619 ip1 = installFromRawResource(apk1Name, apk1, 0, false, 2620 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2621 PackageManager pm = mContext.getPackageManager(); 2622 // Delete app2 2623 File filesDir = mContext.getFilesDir(); 2624 File outFile = new File(filesDir, apk2Name); 2625 int rawResId = apk2; 2626 Uri packageURI = getInstallablePackage(rawResId, outFile); 2627 PackageParser.Package pkg = parsePackage(packageURI); 2628 getPm().deletePackage(pkg.packageName, null, 0); 2629 // Check signatures now 2630 int match = mContext.getPackageManager().checkSignatures( 2631 ip1.pkg.packageName, pkg.packageName); 2632 assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match); 2633 } finally { 2634 if (ip1 != null) { 2635 cleanUpInstall(ip1); 2636 } 2637 } 2638 } 2639 @LargeTest 2640 public void testInstallNoCertificates() { 2641 int apk1 = APP1_UNSIGNED; 2642 String apk1Name = "install1.apk"; 2643 InstallParams ip1 = null; 2644 2645 try { 2646 installFromRawResource(apk1Name, apk1, 0, false, 2647 true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES, 2648 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2649 } finally { 2650 } 2651 } 2652 /* The following tests are related to apps using shared uids signed 2653 * with different certs. 2654 */ 2655 private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned; 2656 private int SHARED1_CERT1 = R.raw.install_shared1_cert1; 2657 private int SHARED1_CERT2 = R.raw.install_shared1_cert2; 2658 private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2; 2659 private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned; 2660 private int SHARED2_CERT1 = R.raw.install_shared2_cert1; 2661 private int SHARED2_CERT2 = R.raw.install_shared2_cert2; 2662 private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2; 2663 private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult) { 2664 String apk1Name = "install1.apk"; 2665 String apk2Name = "install2.apk"; 2666 PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1); 2667 PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2); 2668 2669 try { 2670 // Clean up before testing first. 2671 cleanUpInstall(pkg1.packageName); 2672 cleanUpInstall(pkg2.packageName); 2673 installFromRawResource(apk1Name, apk1, 0, false, 2674 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2675 if (fail) { 2676 installFromRawResource(apk2Name, apk2, 0, false, 2677 true, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2678 } else { 2679 installFromRawResource(apk2Name, apk2, 0, false, 2680 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2681 int match = mContext.getPackageManager().checkSignatures( 2682 pkg1.packageName, pkg2.packageName); 2683 assertEquals(expMatchResult, match); 2684 } 2685 } finally { 2686 if (cleanUp) { 2687 cleanUpInstall(pkg1.packageName); 2688 cleanUpInstall(pkg2.packageName); 2689 } 2690 } 2691 } 2692 @LargeTest 2693 public void testCheckSignaturesSharedAllMatch() { 2694 int apk1 = SHARED1_CERT1_CERT2; 2695 int apk2 = SHARED2_CERT1_CERT2; 2696 boolean fail = false; 2697 int retCode = -1; 2698 int expMatchResult = PackageManager.SIGNATURE_MATCH; 2699 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 2700 } 2701 @LargeTest 2702 public void testCheckSignaturesSharedNoMatch() { 2703 int apk1 = SHARED1_CERT1; 2704 int apk2 = SHARED2_CERT2; 2705 boolean fail = true; 2706 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 2707 int expMatchResult = -1; 2708 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 2709 } 2710 /* 2711 * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone. 2712 */ 2713 @LargeTest 2714 public void testCheckSignaturesSharedSomeMatch1() { 2715 int apk1 = SHARED1_CERT1_CERT2; 2716 int apk2 = SHARED2_CERT1; 2717 boolean fail = true; 2718 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 2719 int expMatchResult = -1; 2720 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 2721 } 2722 /* 2723 * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone. 2724 */ 2725 @LargeTest 2726 public void testCheckSignaturesSharedSomeMatch2() { 2727 int apk1 = SHARED1_CERT1_CERT2; 2728 int apk2 = SHARED2_CERT2; 2729 boolean fail = true; 2730 int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 2731 int expMatchResult = -1; 2732 checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult); 2733 } 2734 @LargeTest 2735 public void testCheckSignaturesSharedUnknown() { 2736 int apk1 = SHARED1_CERT1_CERT2; 2737 int apk2 = SHARED2_CERT1_CERT2; 2738 String apk1Name = "install1.apk"; 2739 String apk2Name = "install2.apk"; 2740 InstallParams ip1 = null; 2741 2742 try { 2743 ip1 = installFromRawResource(apk1Name, apk1, 0, false, 2744 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2745 PackageManager pm = mContext.getPackageManager(); 2746 // Delete app2 2747 PackageParser.Package pkg = getParsedPackage(apk2Name, apk2); 2748 getPm().deletePackage(pkg.packageName, null, 0); 2749 // Check signatures now 2750 int match = mContext.getPackageManager().checkSignatures( 2751 ip1.pkg.packageName, pkg.packageName); 2752 assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match); 2753 } finally { 2754 if (ip1 != null) { 2755 cleanUpInstall(ip1); 2756 } 2757 } 2758 } 2759 2760 @LargeTest 2761 public void testReplaceFirstSharedMatchAllCerts() { 2762 int apk1 = SHARED1_CERT1; 2763 int apk2 = SHARED2_CERT1; 2764 int rapk1 = SHARED1_CERT1; 2765 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 2766 replaceCerts(apk1, rapk1, true, false, -1); 2767 } 2768 @LargeTest 2769 public void testReplaceSecondSharedMatchAllCerts() { 2770 int apk1 = SHARED1_CERT1; 2771 int apk2 = SHARED2_CERT1; 2772 int rapk2 = SHARED2_CERT1; 2773 checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH); 2774 replaceCerts(apk2, rapk2, true, false, -1); 2775 } 2776 @LargeTest 2777 public void testReplaceFirstSharedMatchSomeCerts() { 2778 int apk1 = SHARED1_CERT1_CERT2; 2779 int apk2 = SHARED2_CERT1_CERT2; 2780 int rapk1 = SHARED1_CERT1; 2781 boolean fail = true; 2782 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2783 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2784 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 2785 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2786 } 2787 @LargeTest 2788 public void testReplaceSecondSharedMatchSomeCerts() { 2789 int apk1 = SHARED1_CERT1_CERT2; 2790 int apk2 = SHARED2_CERT1_CERT2; 2791 int rapk2 = SHARED2_CERT1; 2792 boolean fail = true; 2793 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2794 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2795 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 2796 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2797 } 2798 @LargeTest 2799 public void testReplaceFirstSharedMatchNoCerts() { 2800 int apk1 = SHARED1_CERT1; 2801 int apk2 = SHARED2_CERT1; 2802 int rapk1 = SHARED1_CERT2; 2803 boolean fail = true; 2804 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2805 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2806 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 2807 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2808 } 2809 @LargeTest 2810 public void testReplaceSecondSharedMatchNoCerts() { 2811 int apk1 = SHARED1_CERT1; 2812 int apk2 = SHARED2_CERT1; 2813 int rapk2 = SHARED2_CERT2; 2814 boolean fail = true; 2815 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2816 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2817 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 2818 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2819 } 2820 @LargeTest 2821 public void testReplaceFirstSharedMatchMoreCerts() { 2822 int apk1 = SHARED1_CERT1; 2823 int apk2 = SHARED2_CERT1; 2824 int rapk1 = SHARED1_CERT1_CERT2; 2825 boolean fail = true; 2826 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2827 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2828 installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true, 2829 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2830 } 2831 @LargeTest 2832 public void testReplaceSecondSharedMatchMoreCerts() { 2833 int apk1 = SHARED1_CERT1; 2834 int apk2 = SHARED2_CERT1; 2835 int rapk2 = SHARED2_CERT1_CERT2; 2836 boolean fail = true; 2837 int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 2838 checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH); 2839 installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true, 2840 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2841 } 2842 2843 @LargeTest 2844 public void testUsesFeatureMissingFeature() { 2845 int retCode = PackageManager.INSTALL_FAILED_MISSING_FEATURE; 2846 installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, true, retCode, 2847 PackageInfo.INSTALL_LOCATION_UNSPECIFIED); 2848 } 2849 /*---------- Recommended install location tests ----*/ 2850 /* 2851 * TODO's 2852 * check version numbers for upgrades 2853 * check permissions of installed packages 2854 * how to do tests on updated system apps? 2855 * verify updates to system apps cannot be installed on the sdcard. 2856 */ 2857} 2858