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