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