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