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