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