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