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