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