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