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