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