[go: nahoru, domu]

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