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