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