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