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