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