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.IStorageManager;
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.MATCH_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.MATCH_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.MATCH_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.MATCH_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    IStorageManager getSm() {
1153        IBinder service = ServiceManager.getService("mount");
1154        if (service != null) {
1155            return IStorageManager.Stub.asInterface(service);
1156        } else {
1157            Log.e(TAG, "Can't get storagemanager 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 = getSm().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                getSm().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        try {
1321            cleanUpInstall(ip.pkg.packageName);
1322        } finally {
1323            File outFile = new File(ip.pkg.codePath);
1324            if (outFile != null && outFile.exists()) {
1325                outFile.delete();
1326            }
1327        }
1328    }
1329
1330    private void cleanUpInstall(String pkgName) throws Exception {
1331        if (pkgName == null) {
1332            return;
1333        }
1334        Log.i(TAG, "Deleting package : " + pkgName);
1335        try {
1336            final ApplicationInfo info = getPm().getApplicationInfo(pkgName,
1337                    PackageManager.MATCH_UNINSTALLED_PACKAGES);
1338            if (info != null) {
1339                DeleteObserver observer = new DeleteObserver(pkgName);
1340                getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
1341                observer.waitForCompletion(MAX_WAIT_TIME);
1342                assertUninstalled(info);
1343            }
1344        } catch (IllegalArgumentException | NameNotFoundException e) {
1345        }
1346    }
1347
1348    @LargeTest
1349    public void testManifestInstallLocationInternal() throws Exception {
1350        installFromRawResource("install.apk", R.raw.install_loc_internal,
1351                0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1352    }
1353
1354    @LargeTest
1355    public void testManifestInstallLocationSdcard() throws Exception {
1356        // Do not run on devices with emulated external storage.
1357        if (Environment.isExternalStorageEmulated()) {
1358            return;
1359        }
1360
1361        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1362                0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1363    }
1364
1365    @LargeTest
1366    public void testManifestInstallLocationAuto() throws Exception {
1367        installFromRawResource("install.apk", R.raw.install_loc_auto,
1368                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
1369    }
1370
1371    @LargeTest
1372    public void testManifestInstallLocationUnspecified() throws Exception {
1373        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1374                0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1375    }
1376
1377    @LargeTest
1378    public void testManifestInstallLocationFwdLockedFlagSdcard() throws Exception {
1379        // Do not run on devices with emulated external storage.
1380        if (Environment.isExternalStorageEmulated()) {
1381            return;
1382        }
1383
1384        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1385                PackageManager.INSTALL_FORWARD_LOCK |
1386                PackageManager.INSTALL_EXTERNAL, true, false, -1,
1387                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1388    }
1389
1390    @LargeTest
1391    public void testManifestInstallLocationFwdLockedSdcard() throws Exception {
1392        // Do not run on devices with emulated external storage.
1393        if (Environment.isExternalStorageEmulated()) {
1394            return;
1395        }
1396
1397        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1398                PackageManager.INSTALL_FORWARD_LOCK, true, false, -1,
1399                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1400    }
1401
1402    /*
1403     * Install a package on internal flash via PackageManager install flag. Replace
1404     * the package via flag to install on sdcard. Make sure the new flag overrides
1405     * the old install location.
1406     */
1407    @LargeTest
1408    public void testReplaceFlagInternalSdcard() throws Exception {
1409        // Do not run on devices with emulated external storage.
1410        if (Environment.isExternalStorageEmulated()) {
1411            return;
1412        }
1413
1414        int iFlags = 0;
1415        int rFlags = PackageManager.INSTALL_EXTERNAL;
1416        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1417        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1418        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1419        try {
1420            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1421            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
1422        } catch (Exception e) {
1423            failStr("Failed with exception : " + e);
1424        } finally {
1425            cleanUpInstall(ip);
1426        }
1427    }
1428
1429    /*
1430     * Install a package on sdcard via PackageManager install flag. Replace
1431     * the package with no flags or manifest option and make sure the old
1432     * install location is retained.
1433     */
1434    @LargeTest
1435    public void testReplaceFlagSdcardInternal() throws Exception {
1436        // Do not run on devices with emulated external storage.
1437        if (Environment.isExternalStorageEmulated()) {
1438            return;
1439        }
1440
1441        int iFlags = PackageManager.INSTALL_EXTERNAL;
1442        int rFlags = 0;
1443        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1444        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1445        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1446        try {
1447            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1448            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1449        } catch (Exception e) {
1450            failStr("Failed with exception : " + e);
1451        } finally {
1452            cleanUpInstall(ip);
1453        }
1454    }
1455
1456    @LargeTest
1457    public void testManifestInstallLocationReplaceInternalSdcard() throws Exception {
1458        // Do not run on devices with emulated external storage.
1459        if (Environment.isExternalStorageEmulated()) {
1460            return;
1461        }
1462
1463        int iFlags = 0;
1464        int iApk = R.raw.install_loc_internal;
1465        int rFlags = 0;
1466        int rApk = R.raw.install_loc_sdcard;
1467        InstallParams ip = installFromRawResource("install.apk", iApk,
1468                iFlags, false,
1469                false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1470        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1471        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1472        try {
1473            InstallParams rp = installFromRawResource("install.apk", rApk,
1474                    replaceFlags, false,
1475                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1476            assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1477        } catch (Exception e) {
1478            failStr("Failed with exception : " + e);
1479        } finally {
1480            cleanUpInstall(ip);
1481        }
1482    }
1483
1484    @LargeTest
1485    public void testManifestInstallLocationReplaceSdcardInternal() throws Exception {
1486        // Do not run on devices with emulated external storage.
1487        if (Environment.isExternalStorageEmulated()) {
1488            return;
1489        }
1490
1491        int iFlags = 0;
1492        int iApk = R.raw.install_loc_sdcard;
1493        int rFlags = 0;
1494        int rApk = R.raw.install_loc_unspecified;
1495        InstallParams ip = installFromRawResource("install.apk", iApk,
1496                iFlags, false,
1497                false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1498        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1499        try {
1500            InstallParams rp = installFromRawResource("install.apk", rApk,
1501                    replaceFlags, false,
1502                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1503            assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1504        } catch (Exception e) {
1505            failStr("Failed with exception : " + e);
1506        } finally {
1507            cleanUpInstall(ip);
1508        }
1509    }
1510
1511    class MoveReceiver extends GenericReceiver {
1512        String pkgName;
1513
1514        final static int INVALID = -1;
1515
1516        final static int REMOVED = 1;
1517
1518        final static int ADDED = 2;
1519
1520        int removed = INVALID;
1521
1522        MoveReceiver(String pkgName) {
1523            this.pkgName = pkgName;
1524            filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1525            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1526            super.setFilter(filter);
1527        }
1528
1529        public boolean notifyNow(Intent intent) {
1530            String action = intent.getAction();
1531            Log.i(TAG, "MoveReceiver::" + action);
1532            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1533                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1534                if (list != null) {
1535                    for (String pkg : list) {
1536                        if (pkg.equals(pkgName)) {
1537                            removed = REMOVED;
1538                            break;
1539                        }
1540                    }
1541                }
1542                removed = REMOVED;
1543            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1544                if (removed != REMOVED) {
1545                    return false;
1546                }
1547                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1548                if (list != null) {
1549                    for (String pkg : list) {
1550                        if (pkg.equals(pkgName)) {
1551                            removed = ADDED;
1552                            return true;
1553                        }
1554                    }
1555                }
1556            }
1557            return false;
1558        }
1559    }
1560
1561    public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)
1562            throws Exception {
1563        throw new UnsupportedOperationException();
1564    }
1565
1566    private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
1567        throw new UnsupportedOperationException();
1568    }
1569
1570    private int getDefaultInstallLoc() {
1571        int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1572        try {
1573            origDefaultLoc = Settings.Global.getInt(mContext.getContentResolver(),
1574                    Settings.Global.DEFAULT_INSTALL_LOCATION);
1575        } catch (SettingNotFoundException e1) {
1576        }
1577        return origDefaultLoc;
1578    }
1579
1580    private void setInstallLoc(int loc) {
1581        Settings.Global.putInt(mContext.getContentResolver(),
1582                Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
1583    }
1584
1585    /*
1586     * Tests for moving apps between internal and external storage
1587     */
1588    /*
1589     * Utility function that reads a apk bundled as a raw resource
1590     * copies it into own data directory and invokes
1591     * PackageManager api to install first and then replace it
1592     * again.
1593     */
1594
1595    private void moveFromRawResource(String outFileName, int rawResId, int installFlags,
1596            int moveFlags, boolean cleanUp, boolean fail, int result) throws Exception {
1597        int origDefaultLoc = getDefaultInstallLoc();
1598        InstallParams ip = null;
1599        try {
1600            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1601            // Install first
1602            ip = installFromRawResource("install.apk", rawResId, installFlags, false,
1603                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1604            ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1605            if (fail) {
1606                assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1607                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1608                assertNotNull(info);
1609                assertEquals(oldAppInfo.flags, info.flags);
1610            } else {
1611                // Create receiver based on expRetCode
1612                MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1613                boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, receiver);
1614                assertTrue(retCode);
1615                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1616                assertNotNull("ApplicationInfo for recently installed application should exist",
1617                        info);
1618                if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1619                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set",
1620                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1621                    assertStartsWith("Native library dir should be in dataDir",
1622                            info.dataDir, info.nativeLibraryDir);
1623                } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0) {
1624                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set",
1625                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1626                    assertStartsWith("Native library dir should point to ASEC",
1627                            SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
1628                }
1629            }
1630        } catch (NameNotFoundException e) {
1631            failStr("Pkg hasnt been installed correctly");
1632        } finally {
1633            if (ip != null) {
1634                cleanUpInstall(ip);
1635            }
1636            // Restore default install location
1637            setInstallLoc(origDefaultLoc);
1638        }
1639    }
1640
1641    private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
1642            int result) throws Exception {
1643        moveFromRawResource("install.apk",
1644                R.raw.install, installFlags, moveFlags, true,
1645                fail, result);
1646    }
1647
1648    @LargeTest
1649    public void testMoveAppInternalToExternal() throws Exception {
1650        // Do not run on devices with emulated external storage.
1651        if (Environment.isExternalStorageEmulated()) {
1652            return;
1653        }
1654
1655        int installFlags = PackageManager.INSTALL_INTERNAL;
1656        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1657        boolean fail = false;
1658        int result = PackageManager.MOVE_SUCCEEDED;
1659        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1660    }
1661
1662    @Suppress
1663    @LargeTest
1664    public void testMoveAppInternalToInternal() throws Exception {
1665        int installFlags = PackageManager.INSTALL_INTERNAL;
1666        int moveFlags = PackageManager.MOVE_INTERNAL;
1667        boolean fail = true;
1668        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1669        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1670    }
1671
1672    @LargeTest
1673    public void testMoveAppExternalToExternal() throws Exception {
1674        // Do not run on devices with emulated external storage.
1675        if (Environment.isExternalStorageEmulated()) {
1676            return;
1677        }
1678
1679        int installFlags = PackageManager.INSTALL_EXTERNAL;
1680        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1681        boolean fail = true;
1682        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1683        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1684    }
1685
1686    @LargeTest
1687    public void testMoveAppExternalToInternal() throws Exception {
1688        // Do not run on devices with emulated external storage.
1689        if (Environment.isExternalStorageEmulated()) {
1690            return;
1691        }
1692
1693        int installFlags = PackageManager.INSTALL_EXTERNAL;
1694        int moveFlags = PackageManager.MOVE_INTERNAL;
1695        boolean fail = false;
1696        int result = PackageManager.MOVE_SUCCEEDED;
1697        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1698    }
1699
1700    @LargeTest
1701    public void testMoveAppForwardLocked() throws Exception {
1702        // Do not run on devices with emulated external storage.
1703        if (Environment.isExternalStorageEmulated()) {
1704            return;
1705        }
1706
1707        int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
1708        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1709        boolean fail = false;
1710        int result = PackageManager.MOVE_SUCCEEDED;
1711        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1712    }
1713
1714    @LargeTest
1715    public void testMoveAppFailInternalToExternalDelete() throws Exception {
1716        // Do not run on devices with emulated external storage.
1717        if (Environment.isExternalStorageEmulated()) {
1718            return;
1719        }
1720
1721        int installFlags = 0;
1722        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1723        boolean fail = true;
1724        final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
1725
1726        int rawResId = R.raw.install;
1727        int origDefaultLoc = getDefaultInstallLoc();
1728        InstallParams ip = null;
1729        try {
1730            PackageManager pm = getPm();
1731            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1732            // Install first
1733            ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
1734                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1735            // Delete the package now retaining data.
1736            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1737            invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
1738            assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1739        } catch (Exception e) {
1740            failStr(e);
1741        } finally {
1742            if (ip != null) {
1743                cleanUpInstall(ip);
1744            }
1745            // Restore default install location
1746            setInstallLoc(origDefaultLoc);
1747        }
1748    }
1749
1750    /*
1751     * Test that an install error code is returned when media is unmounted
1752     * and package installed on sdcard via package manager flag.
1753     */
1754    @LargeTest
1755    public void testInstallSdcardUnmount() throws Exception {
1756        // Do not run on devices with emulated external storage.
1757        if (Environment.isExternalStorageEmulated()) {
1758            return;
1759        }
1760
1761        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1762        try {
1763            // Unmount sdcard
1764            assertTrue(unmountMedia());
1765            // Try to install and make sure an error code is returned.
1766            installFromRawResource("install.apk", R.raw.install,
1767                    PackageManager.INSTALL_EXTERNAL, false,
1768                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1769                    PackageInfo.INSTALL_LOCATION_AUTO);
1770        } finally {
1771            // Restore original media state
1772            if (origState) {
1773                mountMedia();
1774            } else {
1775                unmountMedia();
1776            }
1777        }
1778    }
1779
1780    /*
1781     * Unmount sdcard. Try installing an app with manifest option to install
1782     * on sdcard. Make sure it gets installed on internal flash.
1783     */
1784    @LargeTest
1785    public void testInstallManifestSdcardUnmount() throws Exception {
1786        // Do not run on devices with emulated external storage.
1787        if (Environment.isExternalStorageEmulated()) {
1788            return;
1789        }
1790
1791        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1792        try {
1793            // Unmount sdcard
1794            assertTrue(unmountMedia());
1795            InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
1796            installFromRawResource(ip, 0, true, false, -1,
1797                    PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1798        } finally {
1799            // Restore original media state
1800            if (origState) {
1801                mountMedia();
1802            } else {
1803                unmountMedia();
1804            }
1805        }
1806    }
1807
1808    /*---------- Recommended install location tests ----*/
1809    /*
1810     * PrecedenceSuffixes:
1811     * Flag : FlagI, FlagE, FlagF
1812     * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1813     * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1814     * Existing: Existing suffix absent if not existing.
1815     * User: UserI, UserE, UserA, User suffix absent if not existing.
1816     *
1817     */
1818
1819    /*
1820     * Install an app on internal flash
1821     */
1822    @LargeTest
1823    public void testFlagI() throws Exception {
1824        sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1825    }
1826
1827    /*
1828     * Install an app on sdcard.
1829     */
1830    @LargeTest
1831    public void testFlagE() throws Exception {
1832        // Do not run on devices with emulated external storage.
1833        if (Environment.isExternalStorageEmulated()) {
1834            return;
1835        }
1836
1837        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1838    }
1839
1840    /*
1841     * Install an app forward-locked.
1842     */
1843    @LargeTest
1844    public void testFlagF() throws Exception {
1845        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1846    }
1847
1848    /*
1849     * Install an app with both internal and external flags set. should fail
1850     */
1851    @LargeTest
1852    public void testFlagIE() throws Exception {
1853        installFromRawResource("install.apk", R.raw.install,
1854                PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1855                false,
1856                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1857                PackageInfo.INSTALL_LOCATION_AUTO);
1858    }
1859
1860    /*
1861     * Install an app with both internal and forward-lock flags set.
1862     */
1863    @LargeTest
1864    public void testFlagIF() throws Exception {
1865        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1866                | PackageManager.INSTALL_INTERNAL, true);
1867    }
1868
1869    /*
1870     * Install an app with both external and forward-lock flags set.
1871     */
1872    @LargeTest
1873    public void testFlagEF() throws Exception {
1874        // Do not run on devices with emulated external storage.
1875        if (Environment.isExternalStorageEmulated()) {
1876            return;
1877        }
1878
1879        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1880                | PackageManager.INSTALL_EXTERNAL, true);
1881    }
1882
1883    /*
1884     * Install an app with both internal and external flags set with forward
1885     * lock. Should fail.
1886     */
1887    @LargeTest
1888    public void testFlagIEF() throws Exception {
1889        installFromRawResource("install.apk", R.raw.install,
1890                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1891                PackageManager.INSTALL_EXTERNAL,
1892                false,
1893                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1894                PackageInfo.INSTALL_LOCATION_AUTO);
1895    }
1896
1897    /*
1898     * Install an app with both internal and manifest option set.
1899     * should install on internal.
1900     */
1901    @LargeTest
1902    public void testFlagIManifestI() throws Exception {
1903        installFromRawResource("install.apk", R.raw.install_loc_internal,
1904                PackageManager.INSTALL_INTERNAL,
1905                true,
1906                false, -1,
1907                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1908    }
1909    /*
1910     * Install an app with both internal and manifest preference for
1911     * preferExternal. Should install on internal.
1912     */
1913    @LargeTest
1914    public void testFlagIManifestE() throws Exception {
1915        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1916                PackageManager.INSTALL_INTERNAL,
1917                true,
1918                false, -1,
1919                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1920    }
1921    /*
1922     * Install an app with both internal and manifest preference for
1923     * auto. should install internal.
1924     */
1925    @LargeTest
1926    public void testFlagIManifestA() throws Exception {
1927        installFromRawResource("install.apk", R.raw.install_loc_auto,
1928                PackageManager.INSTALL_INTERNAL,
1929                true,
1930                false, -1,
1931                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1932    }
1933    /*
1934     * Install an app with both external and manifest option set.
1935     * should install externally.
1936     */
1937    @LargeTest
1938    public void testFlagEManifestI() throws Exception {
1939        // Do not run on devices with emulated external storage.
1940        if (Environment.isExternalStorageEmulated()) {
1941            return;
1942        }
1943
1944        installFromRawResource("install.apk", R.raw.install_loc_internal,
1945                PackageManager.INSTALL_EXTERNAL,
1946                true,
1947                false, -1,
1948                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1949    }
1950
1951    /*
1952     * Install an app with both external and manifest preference for
1953     * preferExternal. Should install externally.
1954     */
1955    @LargeTest
1956    public void testFlagEManifestE() throws Exception {
1957        // Do not run on devices with emulated external storage.
1958        if (Environment.isExternalStorageEmulated()) {
1959            return;
1960        }
1961
1962        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1963                PackageManager.INSTALL_EXTERNAL,
1964                true,
1965                false, -1,
1966                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1967    }
1968
1969    /*
1970     * Install an app with both external and manifest preference for
1971     * auto. should install on external media.
1972     */
1973    @LargeTest
1974    public void testFlagEManifestA() throws Exception {
1975        // Do not run on devices with emulated external storage.
1976        if (Environment.isExternalStorageEmulated()) {
1977            return;
1978        }
1979
1980        installFromRawResource("install.apk", R.raw.install_loc_auto,
1981                PackageManager.INSTALL_EXTERNAL,
1982                true,
1983                false, -1,
1984                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1985    }
1986
1987    /*
1988     * Install an app with fwd locked flag set and install location set to
1989     * internal. should install internally.
1990     */
1991    @LargeTest
1992    public void testFlagFManifestI() throws Exception {
1993        installFromRawResource("install.apk", R.raw.install_loc_internal,
1994                PackageManager.INSTALL_FORWARD_LOCK,
1995                true,
1996                false, -1,
1997                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1998    }
1999
2000    /*
2001     * Install an app with fwd locked flag set and install location set to
2002     * preferExternal. Should install externally.
2003     */
2004    @LargeTest
2005    public void testFlagFManifestE() throws Exception {
2006        // Do not run on devices with emulated external storage.
2007        if (Environment.isExternalStorageEmulated()) {
2008            return;
2009        }
2010
2011        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2012                PackageManager.INSTALL_FORWARD_LOCK,
2013                true,
2014                false, -1,
2015                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2016    }
2017
2018    /*
2019     * Install an app with fwd locked flag set and install location set to auto.
2020     * should install externally.
2021     */
2022    @LargeTest
2023    public void testFlagFManifestA() throws Exception {
2024        // Do not run on devices with emulated external storage.
2025        if (Environment.isExternalStorageEmulated()) {
2026            return;
2027        }
2028
2029        installFromRawResource("install.apk", R.raw.install_loc_auto,
2030                PackageManager.INSTALL_FORWARD_LOCK,
2031                true,
2032                false, -1,
2033                PackageInfo.INSTALL_LOCATION_AUTO);
2034    }
2035
2036    /*
2037     * The following test functions verify install location for existing apps.
2038     * ie existing app can be installed internally or externally. If install
2039     * flag is explicitly set it should override current location. If manifest location
2040     * is set, that should over ride current location too. if not the existing install
2041     * location should be honoured.
2042     * testFlagI/E/F/ExistingI/E -
2043     */
2044    @LargeTest
2045    public void testFlagIExistingI() throws Exception {
2046        int iFlags = PackageManager.INSTALL_INTERNAL;
2047        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2048        // First install.
2049        installFromRawResource("install.apk", R.raw.install,
2050                iFlags,
2051                false,
2052                false, -1,
2053                -1);
2054        // Replace now
2055        installFromRawResource("install.apk", R.raw.install,
2056                rFlags,
2057                true,
2058                false, -1,
2059                -1);
2060    }
2061
2062    @LargeTest
2063    public void testFlagIExistingE() throws Exception {
2064        // Do not run on devices with emulated external storage.
2065        if (Environment.isExternalStorageEmulated()) {
2066            return;
2067        }
2068
2069        int iFlags = PackageManager.INSTALL_EXTERNAL;
2070        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2071        // First install.
2072        installFromRawResource("install.apk", R.raw.install,
2073                iFlags,
2074                false,
2075                false, -1,
2076                -1);
2077        // Replace now
2078        installFromRawResource("install.apk", R.raw.install,
2079                rFlags,
2080                true,
2081                false, -1,
2082                -1);
2083    }
2084
2085    @LargeTest
2086    public void testFlagEExistingI() throws Exception {
2087        // Do not run on devices with emulated external storage.
2088        if (Environment.isExternalStorageEmulated()) {
2089            return;
2090        }
2091
2092        int iFlags = PackageManager.INSTALL_INTERNAL;
2093        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2094        // First install.
2095        installFromRawResource("install.apk", R.raw.install,
2096                iFlags,
2097                false,
2098                false, -1,
2099                -1);
2100        // Replace now
2101        installFromRawResource("install.apk", R.raw.install,
2102                rFlags,
2103                true,
2104                false, -1,
2105                -1);
2106    }
2107
2108    @LargeTest
2109    public void testFlagEExistingE() throws Exception {
2110        // Do not run on devices with emulated external storage.
2111        if (Environment.isExternalStorageEmulated()) {
2112            return;
2113        }
2114
2115        int iFlags = PackageManager.INSTALL_EXTERNAL;
2116        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2117        // First install.
2118        installFromRawResource("install.apk", R.raw.install,
2119                iFlags,
2120                false,
2121                false, -1,
2122                -1);
2123        // Replace now
2124        installFromRawResource("install.apk", R.raw.install,
2125                rFlags,
2126                true,
2127                false, -1,
2128                -1);
2129    }
2130
2131    @Suppress
2132    @LargeTest
2133    public void testFlagFExistingI() throws Exception {
2134        int iFlags = PackageManager.INSTALL_INTERNAL;
2135        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2136        // First install.
2137        installFromRawResource("install.apk", R.raw.install,
2138                iFlags,
2139                false,
2140                false, -1,
2141                -1);
2142        // Replace now
2143        installFromRawResource("install.apk", R.raw.install,
2144                rFlags,
2145                true,
2146                false, -1,
2147                -1);
2148    }
2149
2150    @LargeTest
2151    public void testFlagFExistingE() throws Exception {
2152        // Do not run on devices with emulated external storage.
2153        if (Environment.isExternalStorageEmulated()) {
2154            return;
2155        }
2156
2157        int iFlags = PackageManager.INSTALL_EXTERNAL;
2158        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2159        // First install.
2160        installFromRawResource("install.apk", R.raw.install,
2161                iFlags,
2162                false,
2163                false, -1,
2164                -1);
2165        // Replace now
2166        installFromRawResource("install.apk", R.raw.install,
2167                rFlags,
2168                true,
2169                false, -1,
2170                -1);
2171    }
2172
2173    /*
2174     * The following set of tests verify the installation of apps with
2175     * install location attribute set to internalOnly, preferExternal and auto.
2176     * The manifest option should dictate the install location.
2177     * public void testManifestI/E/A
2178     * TODO out of memory fall back behaviour.
2179     */
2180    @LargeTest
2181    public void testManifestI() throws Exception {
2182        installFromRawResource("install.apk", R.raw.install_loc_internal,
2183                0,
2184                true,
2185                false, -1,
2186                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2187    }
2188
2189    @LargeTest
2190    public void testManifestE() throws Exception {
2191        // Do not run on devices with emulated external storage.
2192        if (Environment.isExternalStorageEmulated()) {
2193            return;
2194        }
2195
2196        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2197                0,
2198                true,
2199                false, -1,
2200                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2201    }
2202
2203    @LargeTest
2204    public void testManifestA() throws Exception {
2205        installFromRawResource("install.apk", R.raw.install_loc_auto,
2206                0,
2207                true,
2208                false, -1,
2209                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2210    }
2211
2212    /*
2213     * The following set of tests verify the installation of apps
2214     * with install location attribute set to internalOnly, preferExternal and auto
2215     * for already existing apps. The manifest option should take precedence.
2216     * TODO add out of memory fall back behaviour.
2217     * testManifestI/E/AExistingI/E
2218     */
2219    @LargeTest
2220    public void testManifestIExistingI() throws Exception {
2221        int iFlags = PackageManager.INSTALL_INTERNAL;
2222        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2223        // First install.
2224        installFromRawResource("install.apk", R.raw.install,
2225                iFlags,
2226                false,
2227                false, -1,
2228                -1);
2229        // Replace now
2230        installFromRawResource("install.apk", R.raw.install_loc_internal,
2231                rFlags,
2232                true,
2233                false, -1,
2234                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2235    }
2236
2237    @LargeTest
2238    public void testManifestIExistingE() throws Exception {
2239        // Do not run on devices with emulated external storage.
2240        if (Environment.isExternalStorageEmulated()) {
2241            return;
2242        }
2243
2244        int iFlags = PackageManager.INSTALL_EXTERNAL;
2245        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2246        // First install.
2247        installFromRawResource("install.apk", R.raw.install,
2248                iFlags,
2249                false,
2250                false, -1,
2251                -1);
2252        // Replace now
2253        installFromRawResource("install.apk", R.raw.install_loc_internal,
2254                rFlags,
2255                true,
2256                false, -1,
2257                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2258    }
2259
2260    @LargeTest
2261    public void testManifestEExistingI() throws Exception {
2262        // Do not run on devices with emulated external storage.
2263        if (Environment.isExternalStorageEmulated()) {
2264            return;
2265        }
2266
2267        int iFlags = PackageManager.INSTALL_INTERNAL;
2268        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2269        // First install.
2270        installFromRawResource("install.apk", R.raw.install,
2271                iFlags,
2272                false,
2273                false, -1,
2274                -1);
2275        // Replace now
2276        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2277                rFlags,
2278                true,
2279                false, -1,
2280                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2281    }
2282
2283    @LargeTest
2284    public void testManifestEExistingE() throws Exception {
2285        // Do not run on devices with emulated external storage.
2286        if (Environment.isExternalStorageEmulated()) {
2287            return;
2288        }
2289
2290        int iFlags = PackageManager.INSTALL_EXTERNAL;
2291        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2292        // First install.
2293        installFromRawResource("install.apk", R.raw.install,
2294                iFlags,
2295                false,
2296                false, -1,
2297                -1);
2298        // Replace now
2299        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2300                rFlags,
2301                true,
2302                false, -1,
2303                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2304    }
2305
2306    @LargeTest
2307    public void testManifestAExistingI() throws Exception {
2308        int iFlags = PackageManager.INSTALL_INTERNAL;
2309        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2310        // First install.
2311        installFromRawResource("install.apk", R.raw.install,
2312                iFlags,
2313                false,
2314                false, -1,
2315                -1);
2316        // Replace now
2317        installFromRawResource("install.apk", R.raw.install_loc_auto,
2318                rFlags,
2319                true,
2320                false, -1,
2321                PackageInfo.INSTALL_LOCATION_AUTO);
2322    }
2323
2324    @LargeTest
2325    public void testManifestAExistingE() throws Exception {
2326        // Do not run on devices with emulated external storage.
2327        if (Environment.isExternalStorageEmulated()) {
2328            return;
2329        }
2330
2331        int iFlags = PackageManager.INSTALL_EXTERNAL;
2332        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2333        // First install.
2334        installFromRawResource("install.apk", R.raw.install,
2335                iFlags,
2336                false,
2337                false, -1,
2338                -1);
2339        // Replace now
2340        installFromRawResource("install.apk", R.raw.install_loc_auto,
2341                rFlags,
2342                true,
2343                false, -1,
2344                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2345    }
2346
2347    /*
2348     * The following set of tests check install location for existing
2349     * application based on user setting.
2350     */
2351    private int getExpectedInstallLocation(int userSetting) {
2352        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2353        boolean enable = getUserSettingSetInstallLocation();
2354        if (enable) {
2355            if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
2356                iloc = PackageInfo.INSTALL_LOCATION_AUTO;
2357            } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
2358                iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
2359            } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
2360                iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
2361            }
2362        }
2363        return iloc;
2364    }
2365
2366    private void setExistingXUserX(int userSetting, int iFlags, int iloc) throws Exception {
2367        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2368        // First install.
2369        installFromRawResource("install.apk", R.raw.install,
2370                iFlags,
2371                false,
2372                false, -1,
2373                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2374        int origSetting = getDefaultInstallLoc();
2375        try {
2376            // Set user setting
2377            setInstallLoc(userSetting);
2378            // Replace now
2379            installFromRawResource("install.apk", R.raw.install,
2380                    rFlags,
2381                    true,
2382                    false, -1,
2383                    iloc);
2384        } finally {
2385            setInstallLoc(origSetting);
2386        }
2387    }
2388    @LargeTest
2389    public void testExistingIUserI() throws Exception {
2390        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2391        int iFlags = PackageManager.INSTALL_INTERNAL;
2392        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2393    }
2394
2395    @LargeTest
2396    public void testExistingIUserE() throws Exception {
2397        // Do not run on devices with emulated external storage.
2398        if (Environment.isExternalStorageEmulated()) {
2399            return;
2400        }
2401
2402        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2403        int iFlags = PackageManager.INSTALL_INTERNAL;
2404        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2405    }
2406
2407    @LargeTest
2408    public void testExistingIUserA() throws Exception {
2409        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2410        int iFlags = PackageManager.INSTALL_INTERNAL;
2411        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2412    }
2413
2414    @LargeTest
2415    public void testExistingEUserI() throws Exception {
2416        // Do not run on devices with emulated external storage.
2417        if (Environment.isExternalStorageEmulated()) {
2418            return;
2419        }
2420
2421        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2422        int iFlags = PackageManager.INSTALL_EXTERNAL;
2423        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2424    }
2425
2426    @LargeTest
2427    public void testExistingEUserE() throws Exception {
2428        // Do not run on devices with emulated external storage.
2429        if (Environment.isExternalStorageEmulated()) {
2430            return;
2431        }
2432
2433        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2434        int iFlags = PackageManager.INSTALL_EXTERNAL;
2435        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2436    }
2437
2438    @LargeTest
2439    public void testExistingEUserA() throws Exception {
2440        // Do not run on devices with emulated external storage.
2441        if (Environment.isExternalStorageEmulated()) {
2442            return;
2443        }
2444
2445        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2446        int iFlags = PackageManager.INSTALL_EXTERNAL;
2447        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2448    }
2449
2450    /*
2451     * The following set of tests verify that the user setting defines
2452     * the install location.
2453     *
2454     */
2455    private boolean getUserSettingSetInstallLocation() {
2456        try {
2457            return Settings.Global.getInt(
2458                    mContext.getContentResolver(), Settings.Global.SET_INSTALL_LOCATION) != 0;
2459        } catch (SettingNotFoundException e1) {
2460        }
2461        return false;
2462    }
2463
2464    private void setUserSettingSetInstallLocation(boolean value) {
2465        Settings.Global.putInt(mContext.getContentResolver(),
2466                Settings.Global.SET_INSTALL_LOCATION, value ? 1 : 0);
2467    }
2468
2469    private void setUserX(boolean enable, int userSetting, int iloc) throws Exception {
2470        boolean origUserSetting = getUserSettingSetInstallLocation();
2471        int origSetting = getDefaultInstallLoc();
2472        try {
2473            setUserSettingSetInstallLocation(enable);
2474            // Set user setting
2475            setInstallLoc(userSetting);
2476            // Replace now
2477            installFromRawResource("install.apk", R.raw.install,
2478                    0,
2479                    true,
2480                    false, -1,
2481                    iloc);
2482        } finally {
2483            // Restore original setting
2484            setUserSettingSetInstallLocation(origUserSetting);
2485            setInstallLoc(origSetting);
2486        }
2487    }
2488    @LargeTest
2489    public void testUserI() throws Exception {
2490        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2491        int iloc = getExpectedInstallLocation(userSetting);
2492        setUserX(true, userSetting, iloc);
2493    }
2494
2495    @LargeTest
2496    public void testUserE() throws Exception {
2497        // Do not run on devices with emulated external storage.
2498        if (Environment.isExternalStorageEmulated()) {
2499            return;
2500        }
2501
2502        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2503        int iloc = getExpectedInstallLocation(userSetting);
2504        setUserX(true, userSetting, iloc);
2505    }
2506
2507    @LargeTest
2508    public void testUserA() throws Exception {
2509        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2510        int iloc = getExpectedInstallLocation(userSetting);
2511        setUserX(true, userSetting, iloc);
2512    }
2513
2514    /*
2515     * The following set of tests turn on/off the basic
2516     * user setting for turning on install location.
2517     */
2518    @LargeTest
2519    public void testUserPrefOffUserI() throws Exception {
2520        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2521        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2522        setUserX(false, userSetting, iloc);
2523    }
2524
2525    @LargeTest
2526    public void testUserPrefOffUserE() throws Exception {
2527        // Do not run on devices with emulated external storage.
2528        if (Environment.isExternalStorageEmulated()) {
2529            return;
2530        }
2531
2532        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2533        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2534        setUserX(false, userSetting, iloc);
2535    }
2536
2537    @LargeTest
2538    public void testUserPrefOffA() throws Exception {
2539        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2540        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2541        setUserX(false, userSetting, iloc);
2542    }
2543
2544    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
2545        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
2546        PERM_DEFINED,
2547        "com.android.frameworks.coretests.NORMAL",
2548        "com.android.frameworks.coretests.DANGEROUS",
2549        "com.android.frameworks.coretests.SIGNATURE",
2550    };
2551
2552    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
2553        PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
2554        PERM_UNDEFINED,
2555        "com.android.frameworks.coretests.NORMAL",
2556        "com.android.frameworks.coretests.DANGEROUS",
2557        "com.android.frameworks.coretests.SIGNATURE",
2558    };
2559
2560    static final String BASE_PERMISSIONS_USED[] = new String[] {
2561        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2562        PERM_USED,
2563        "com.android.frameworks.coretests.NORMAL",
2564        "com.android.frameworks.coretests.DANGEROUS",
2565        "com.android.frameworks.coretests.SIGNATURE",
2566    };
2567
2568    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
2569        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2570        PERM_NOTUSED,
2571        "com.android.frameworks.coretests.NORMAL",
2572        "com.android.frameworks.coretests.DANGEROUS",
2573        "com.android.frameworks.coretests.SIGNATURE",
2574    };
2575
2576    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
2577        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2578        PERM_USED,
2579        "com.android.frameworks.coretests.SIGNATURE",
2580        PERM_NOTUSED,
2581        "com.android.frameworks.coretests.NORMAL",
2582        "com.android.frameworks.coretests.DANGEROUS",
2583    };
2584
2585    /*
2586     * Ensure that permissions are properly declared.
2587     */
2588    @LargeTest
2589    public void testInstallDeclaresPermissions() throws Exception {
2590        InstallParams ip = null;
2591        InstallParams ip2 = null;
2592        try {
2593            // **: Upon installing a package, are its declared permissions published?
2594
2595            int iFlags = PackageManager.INSTALL_INTERNAL;
2596            int iApk = R.raw.install_decl_perm;
2597            ip = installFromRawResource("install.apk", iApk,
2598                    iFlags, false,
2599                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2600            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2601            assertPermissions(BASE_PERMISSIONS_DEFINED);
2602
2603            // **: Upon installing package, are its permissions granted?
2604
2605            int i2Flags = PackageManager.INSTALL_INTERNAL;
2606            int i2Apk = R.raw.install_use_perm_good;
2607            ip2 = installFromRawResource("install2.apk", i2Apk,
2608                    i2Flags, false,
2609                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2610            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2611            assertPermissions(BASE_PERMISSIONS_USED);
2612
2613            // **: Upon removing but not deleting, are permissions retained?
2614
2615            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2616
2617            try {
2618                invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
2619            } catch (Exception e) {
2620                failStr(e);
2621            }
2622            assertPermissions(BASE_PERMISSIONS_DEFINED);
2623            assertPermissions(BASE_PERMISSIONS_USED);
2624
2625            // **: Upon re-installing, are permissions retained?
2626
2627            ip = installFromRawResource("install.apk", iApk,
2628                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2629                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2630            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2631            assertPermissions(BASE_PERMISSIONS_DEFINED);
2632            assertPermissions(BASE_PERMISSIONS_USED);
2633
2634            // **: Upon deleting package, are all permissions removed?
2635
2636            try {
2637                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2638                ip = null;
2639            } catch (Exception e) {
2640                failStr(e);
2641            }
2642            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2643            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2644
2645            // **: Delete package using permissions; nothing to check here.
2646
2647            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2648            try {
2649                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2650                ip2 = null;
2651            } catch (Exception e) {
2652                failStr(e);
2653            }
2654
2655            // **: Re-install package using permissions; no permissions can be granted.
2656
2657            ip2 = installFromRawResource("install2.apk", i2Apk,
2658                    i2Flags, false,
2659                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2660            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2661            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2662
2663            // **: Upon installing declaring package, are sig permissions granted
2664            // to other apps (but not other perms)?
2665
2666            ip = installFromRawResource("install.apk", iApk,
2667                    iFlags, false,
2668                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2669            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2670            assertPermissions(BASE_PERMISSIONS_DEFINED);
2671            assertPermissions(BASE_PERMISSIONS_SIGUSED);
2672
2673            // **: Re-install package using permissions; are all permissions granted?
2674
2675            ip2 = installFromRawResource("install2.apk", i2Apk,
2676                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2677                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2678            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2679            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2680
2681            // **: Upon deleting package, are all permissions removed?
2682
2683            try {
2684                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2685                ip = null;
2686            } catch (Exception e) {
2687                failStr(e);
2688            }
2689            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2690            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2691
2692            // **: Delete package using permissions; nothing to check here.
2693
2694            try {
2695                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2696                ip2 = null;
2697            } catch (Exception e) {
2698                failStr(e);
2699            }
2700
2701        } finally {
2702            if (ip2 != null) {
2703                cleanUpInstall(ip2);
2704            }
2705            if (ip != null) {
2706                cleanUpInstall(ip);
2707            }
2708        }
2709    }
2710
2711    /*
2712     * Ensure that permissions are properly declared.
2713     */
2714    @LargeTest
2715    public void testInstallOnSdPermissionsUnmount() throws Exception {
2716        InstallParams ip = null;
2717        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2718        try {
2719            // **: Upon installing a package, are its declared permissions published?
2720            int iFlags = PackageManager.INSTALL_INTERNAL;
2721            int iApk = R.raw.install_decl_perm;
2722            ip = installFromRawResource("install.apk", iApk,
2723                    iFlags, false,
2724                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2725            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2726            assertPermissions(BASE_PERMISSIONS_DEFINED);
2727            // Unmount media here
2728            assertTrue(unmountMedia());
2729            // Mount media again
2730            mountMedia();
2731            //Check permissions now
2732            assertPermissions(BASE_PERMISSIONS_DEFINED);
2733        } finally {
2734            if (ip != null) {
2735                cleanUpInstall(ip);
2736            }
2737        }
2738    }
2739
2740    /* This test creates a stale container via StorageManagerService and then installs
2741     * a package and verifies that the stale container is cleaned up and install
2742     * is successful.
2743     * Please note that this test is very closely tied to the framework's
2744     * naming convention for secure containers.
2745     */
2746    @LargeTest
2747    public void testInstallSdcardStaleContainer() throws Exception {
2748        // Do not run on devices with emulated external storage.
2749        if (Environment.isExternalStorageEmulated()) {
2750            return;
2751        }
2752
2753        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2754        try {
2755            // Mount media first
2756            mountMedia();
2757            String outFileName = "install.apk";
2758            int rawResId = R.raw.install;
2759            PackageManager pm = mContext.getPackageManager();
2760            File filesDir = mContext.getFilesDir();
2761            File outFile = new File(filesDir, outFileName);
2762            Uri packageURI = getInstallablePackage(rawResId, outFile);
2763            PackageParser.Package pkg = parsePackage(packageURI);
2764            assertNotNull(pkg);
2765            // Install an app on sdcard.
2766            installFromRawResource(outFileName, rawResId,
2767                    PackageManager.INSTALL_EXTERNAL, false,
2768                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2769            // Unmount sdcard
2770            unmountMedia();
2771            // Delete the app on sdcard to leave a stale container on sdcard.
2772            GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2773            assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver));
2774            mountMedia();
2775            // Reinstall the app and make sure it gets installed.
2776            installFromRawResource(outFileName, rawResId,
2777                    PackageManager.INSTALL_EXTERNAL, true,
2778                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2779        } catch (Exception e) {
2780            failStr(e.getMessage());
2781        } finally {
2782            if (origMediaState) {
2783                mountMedia();
2784            } else {
2785                unmountMedia();
2786            }
2787
2788        }
2789    }
2790
2791    /* This test installs an application on sdcard and unmounts media.
2792     * The app is then re-installed on internal storage. The sdcard is mounted
2793     * and verified that the re-installation on internal storage takes precedence.
2794     */
2795    @LargeTest
2796    public void testInstallSdcardStaleContainerReinstall() throws Exception {
2797        // Do not run on devices with emulated external storage.
2798        if (Environment.isExternalStorageEmulated()) {
2799            return;
2800        }
2801
2802        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2803        try {
2804            // Mount media first
2805            mountMedia();
2806            String outFileName = "install.apk";
2807            int rawResId = R.raw.install;
2808            PackageManager pm = mContext.getPackageManager();
2809            File filesDir = mContext.getFilesDir();
2810            File outFile = new File(filesDir, outFileName);
2811            Uri packageURI = getInstallablePackage(rawResId, outFile);
2812            PackageParser.Package pkg = parsePackage(packageURI);
2813            assertNotNull(pkg);
2814            // Install an app on sdcard.
2815            installFromRawResource(outFileName, rawResId,
2816                    PackageManager.INSTALL_EXTERNAL, false,
2817                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2818            // Unmount sdcard
2819            unmountMedia();
2820            // Reinstall the app and make sure it gets installed on internal storage.
2821            installFromRawResource(outFileName, rawResId,
2822                    PackageManager.INSTALL_REPLACE_EXISTING, false,
2823                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2824            mountMedia();
2825            // Verify that the app installed is on internal storage.
2826            assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2827        } catch (Exception e) {
2828            failStr(e.getMessage());
2829        } finally {
2830            if (origMediaState) {
2831                mountMedia();
2832            } else {
2833                unmountMedia();
2834            }
2835        }
2836    }
2837
2838    /*
2839     * The following series of tests are related to upgrading apps with
2840     * different certificates.
2841     */
2842    private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
2843
2844    private int APP1_CERT1 = R.raw.install_app1_cert1;
2845
2846    private int APP1_CERT2 = R.raw.install_app1_cert2;
2847
2848    private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
2849
2850    private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
2851
2852    private int APP1_CERT3 = R.raw.install_app1_cert3;
2853
2854    private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
2855
2856    private int APP2_CERT1 = R.raw.install_app2_cert1;
2857
2858    private int APP2_CERT2 = R.raw.install_app2_cert2;
2859
2860    private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
2861
2862    private int APP2_CERT3 = R.raw.install_app2_cert3;
2863
2864    private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail,
2865            int retCode) throws Exception {
2866        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2867        String apk1Name = "install1.apk";
2868        String apk2Name = "install2.apk";
2869        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2870        try {
2871            InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2872                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2873            installFromRawResource(apk2Name, apk2, rFlags, false,
2874                    fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2875            return ip;
2876        } catch (Exception e) {
2877            failStr(e.getMessage());
2878        } finally {
2879            if (cleanUp) {
2880                cleanUpInstall(pkg1.packageName);
2881            }
2882        }
2883        return null;
2884    }
2885
2886    /*
2887     * Test that an app signed with two certificates can be upgraded by the
2888     * same app signed with two certificates.
2889     */
2890    @LargeTest
2891    public void testReplaceMatchAllCerts() throws Exception {
2892        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
2893    }
2894
2895    /*
2896     * Test that an app signed with two certificates cannot be upgraded
2897     * by an app signed with a different certificate.
2898     */
2899    @LargeTest
2900    public void testReplaceMatchNoCerts1() throws Exception {
2901        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
2902                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2903    }
2904
2905    /*
2906     * Test that an app signed with two certificates cannot be upgraded
2907     * by an app signed with a different certificate.
2908     */
2909    @LargeTest
2910    public void testReplaceMatchNoCerts2() throws Exception {
2911        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
2912                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2913    }
2914
2915    /*
2916     * Test that an app signed with two certificates cannot be upgraded by
2917     * an app signed with a subset of initial certificates.
2918     */
2919    @LargeTest
2920    public void testReplaceMatchSomeCerts1() throws Exception {
2921        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
2922                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2923    }
2924
2925    /*
2926     * Test that an app signed with two certificates cannot be upgraded by
2927     * an app signed with the last certificate.
2928     */
2929    @LargeTest
2930    public void testReplaceMatchSomeCerts2() throws Exception {
2931        replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
2932                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2933    }
2934
2935    /*
2936     * Test that an app signed with a certificate can be upgraded by app
2937     * signed with a superset of certificates.
2938     */
2939    @LargeTest
2940    public void testReplaceMatchMoreCerts() throws Exception {
2941        replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
2942                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2943    }
2944
2945    /*
2946     * Test that an app signed with a certificate can be upgraded by app
2947     * signed with a superset of certificates. Then verify that the an app
2948     * signed with the original set of certs cannot upgrade the new one.
2949     */
2950    @LargeTest
2951    public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception {
2952        InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
2953                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2954        try {
2955            int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2956            installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
2957                    false, -1,
2958                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2959        } catch (Exception e) {
2960            failStr(e.getMessage());
2961        } finally {
2962            if (ip != null) {
2963                cleanUpInstall(ip);
2964            }
2965        }
2966    }
2967
2968    /**
2969     * The following tests are related to testing KeySets-based key rotation
2970     */
2971    /*
2972     * Check if an apk which does not specify an upgrade-keyset may be upgraded
2973     * by an apk which does
2974     */
2975    public void testNoKSToUpgradeKS() throws Exception {
2976        replaceCerts(R.raw.keyset_sa_unone, R.raw.keyset_sa_ua, true, false, -1);
2977    }
2978
2979    /*
2980     * Check if an apk which does specify an upgrade-keyset may be downgraded to
2981     * an apk which does not
2982     */
2983    public void testUpgradeKSToNoKS() throws Exception {
2984        replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_unone, true, false, -1);
2985    }
2986
2987    /*
2988     * Check if an apk signed by a key other than the upgrade keyset can update
2989     * an app
2990     */
2991    public void testUpgradeKSWithWrongKey() throws Exception {
2992        replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true,
2993                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2994    }
2995
2996    /*
2997     * Check if an apk signed by its signing key, which is not an upgrade key,
2998     * can upgrade an app.
2999     */
3000    public void testUpgradeKSWithWrongSigningKey() throws Exception {
3001        replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true,
3002                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
3003    }
3004
3005    /*
3006     * Check if an apk signed by its upgrade key, which is not its signing key,
3007     * can upgrade an app.
3008     */
3009    public void testUpgradeKSWithUpgradeKey() throws Exception {
3010        replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sb_ub, true, false, -1);
3011    }
3012    /*
3013     * Check if an apk signed by its upgrade key, which is its signing key, can
3014     * upgrade an app.
3015     */
3016    public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
3017        replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_ua, true, false, -1);
3018    }
3019
3020    /*
3021     * Check if an apk signed by multiple keys, one of which is its upgrade key,
3022     * can upgrade an app.
3023     */
3024    public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
3025        replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sab_ua, true, false, -1);
3026    }
3027
3028    /*
3029     * Check if an apk signed by multiple keys, one of which is its signing key,
3030     * but none of which is an upgrade key, can upgrade an app.
3031     */
3032    public void testMultipleUpgradeKSWithSigningKey() throws Exception {
3033        replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true,
3034                PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
3035    }
3036
3037    /*
3038     * Check if an apk which defines multiple (two) upgrade keysets is
3039     * upgrade-able by either.
3040     */
3041    public void testUpgradeKSWithMultipleUpgradeKeySets() throws Exception {
3042        replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sa_ua, true, false, -1);
3043        replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sb_ub, true, false, -1);
3044    }
3045
3046    /*
3047     * Check if an apk's sigs are changed after upgrading with a non-signing
3048     * key.
3049     *
3050     * TODO: consider checking against hard-coded Signatures in the Sig-tests
3051     */
3052    public void testSigChangeAfterUpgrade() throws Exception {
3053        // install original apk and grab sigs
3054        installFromRawResource("tmp.apk", R.raw.keyset_sa_ub,
3055                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3056        PackageManager pm = getPm();
3057        String pkgName = "com.android.frameworks.coretests.keysets";
3058        PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3059        assertTrue("Package should only have one signature, sig A",
3060                pi.signatures.length == 1);
3061        String sigBefore = pi.signatures[0].toCharsString();
3062        // install apk signed by different upgrade KeySet
3063        installFromRawResource("tmp2.apk", R.raw.keyset_sb_ub,
3064                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3065                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3066        pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3067        assertTrue("Package should only have one signature, sig B",
3068                pi.signatures.length == 1);
3069        String sigAfter = pi.signatures[0].toCharsString();
3070        assertFalse("Package signatures did not change after upgrade!",
3071                sigBefore.equals(sigAfter));
3072        cleanUpInstall(pkgName);
3073    }
3074
3075    /*
3076     * Check if an apk's sig is the same  after upgrading with a signing
3077     * key.
3078     */
3079    public void testSigSameAfterUpgrade() throws Exception {
3080        // install original apk and grab sigs
3081        installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
3082                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3083        PackageManager pm = getPm();
3084        String pkgName = "com.android.frameworks.coretests.keysets";
3085        PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3086        assertTrue("Package should only have one signature, sig A",
3087                pi.signatures.length == 1);
3088        String sigBefore = pi.signatures[0].toCharsString();
3089        // install apk signed by same upgrade KeySet
3090        installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
3091                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3092                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3093        pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3094        assertTrue("Package should only have one signature, sig A",
3095                pi.signatures.length == 1);
3096        String sigAfter = pi.signatures[0].toCharsString();
3097        assertTrue("Package signatures changed after upgrade!",
3098                sigBefore.equals(sigAfter));
3099        cleanUpInstall(pkgName);
3100    }
3101
3102    /*
3103     * Check if an apk's sigs are the same after upgrading with an app with
3104     * a subset of the original signing keys.
3105     */
3106    public void testSigRemovedAfterUpgrade() throws Exception {
3107        // install original apk and grab sigs
3108        installFromRawResource("tmp.apk", R.raw.keyset_sab_ua,
3109                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3110        PackageManager pm = getPm();
3111        String pkgName = "com.android.frameworks.coretests.keysets";
3112        PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3113        assertTrue("Package should have two signatures, sig A and sig B",
3114                pi.signatures.length == 2);
3115        Set<String> sigsBefore = new HashSet<String>();
3116        for (int i = 0; i < pi.signatures.length; i++) {
3117            sigsBefore.add(pi.signatures[i].toCharsString());
3118        }
3119        // install apk signed subset upgrade KeySet
3120        installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
3121                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3122                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3123        pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3124        assertTrue("Package should only have one signature, sig A",
3125                pi.signatures.length == 1);
3126        String sigAfter = pi.signatures[0].toCharsString();
3127        assertTrue("Original package signatures did not contain new sig",
3128                sigsBefore.contains(sigAfter));
3129        cleanUpInstall(pkgName);
3130    }
3131
3132    /*
3133     * Check if an apk's sigs are added to after upgrading with an app with
3134     * a superset of the original signing keys.
3135     */
3136    public void testSigAddedAfterUpgrade() throws Exception {
3137        // install original apk and grab sigs
3138        installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
3139                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3140        PackageManager pm = getPm();
3141        String pkgName = "com.android.frameworks.coretests.keysets";
3142        PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3143        assertTrue("Package should only have one signature, sig A",
3144                pi.signatures.length == 1);
3145        String sigBefore = pi.signatures[0].toCharsString();
3146        // install apk signed subset upgrade KeySet
3147        installFromRawResource("tmp2.apk", R.raw.keyset_sab_ua,
3148                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3149                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3150        pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3151        assertTrue("Package should have two signatures, sig A and sig B",
3152                pi.signatures.length == 2);
3153        Set<String> sigsAfter = new HashSet<String>();
3154        for (int i = 0; i < pi.signatures.length; i++) {
3155            sigsAfter.add(pi.signatures[i].toCharsString());
3156        }
3157        assertTrue("Package signatures did not change after upgrade!",
3158                sigsAfter.contains(sigBefore));
3159        cleanUpInstall(pkgName);
3160    }
3161
3162    /*
3163     * Check if an apk gains signature-level permission after changing to the a
3164     * new signature, for which a permission should be granted.
3165     */
3166    public void testUpgradeSigPermGained() throws Exception {
3167        // install apk which defines permission
3168        installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
3169                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3170        // install apk which uses permission but does not have sig
3171        installFromRawResource("permUse.apk", R.raw.keyset_permuse_sb_ua_ub,
3172                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3173        // verify that package does not have perm before
3174        PackageManager pm = getPm();
3175        String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
3176        String pkgName = "com.android.frameworks.coretests.keysets";
3177        String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
3178        assertFalse("keyset permission granted to app without same signature!",
3179                    pm.checkPermission(permName, pkgName)
3180                    == PackageManager.PERMISSION_GRANTED);
3181        // upgrade to apk with perm signature
3182        installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sa_ua_ub,
3183                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3184                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3185        assertTrue("keyset permission not granted to app after upgrade to same sig",
3186                    pm.checkPermission(permName, pkgName)
3187                    == PackageManager.PERMISSION_GRANTED);
3188        cleanUpInstall(permPkgName);
3189        cleanUpInstall(pkgName);
3190    }
3191
3192    /*
3193     * Check if an apk loses signature-level permission after changing to the a
3194     * new signature, from one which a permission should be granted.
3195     */
3196    public void testUpgradeSigPermLost() throws Exception {
3197        // install apk which defines permission
3198        installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
3199                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3200        // install apk which uses permission, signed by same sig
3201        installFromRawResource("permUse.apk", R.raw.keyset_permuse_sa_ua_ub,
3202                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3203        // verify that package does not have perm before
3204        PackageManager pm = getPm();
3205        String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
3206        String pkgName = "com.android.frameworks.coretests.keysets";
3207        String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
3208        assertTrue("keyset permission not granted to app with same sig",
3209                    pm.checkPermission(permName, pkgName)
3210                    == PackageManager.PERMISSION_GRANTED);
3211        // upgrade to apk without perm signature
3212        installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sb_ua_ub,
3213                PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3214                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3215
3216        assertFalse("keyset permission not revoked from app which upgraded to a "
3217                    + "different signature",
3218                    pm.checkPermission(permName, pkgName)
3219                    == PackageManager.PERMISSION_GRANTED);
3220        cleanUpInstall(permPkgName);
3221        cleanUpInstall(pkgName);
3222    }
3223
3224    /**
3225     * The following tests are related to testing KeySets-based API
3226     */
3227
3228    /*
3229     * testGetSigningKeySetNull - ensure getSigningKeySet() returns null on null
3230     * input and when calling a package other than that which made the call.
3231     */
3232    public void testGetSigningKeySet() throws Exception {
3233        PackageManager pm = getPm();
3234        String mPkgName = mContext.getPackageName();
3235        String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3236        KeySet ks;
3237        try {
3238            ks = pm.getSigningKeySet(null);
3239            assertTrue(false); // should have thrown
3240        } catch (NullPointerException e) {
3241        }
3242        try {
3243            ks = pm.getSigningKeySet("keysets.test.bogus.package");
3244            assertTrue(false); // should have thrown
3245        } catch (IllegalArgumentException e) {
3246        }
3247        final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3248                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3249        try {
3250            ks = pm.getSigningKeySet(otherPkgName);
3251            assertTrue(false); // should have thrown
3252        } catch (SecurityException e) {
3253        } finally {
3254            cleanUpInstall(ip);
3255        }
3256        ks = pm.getSigningKeySet(mContext.getPackageName());
3257        assertNotNull(ks);
3258    }
3259
3260    /*
3261     * testGetKeySetByAlias - same as getSigningKeySet, but for keysets defined
3262     * by this package.
3263     */
3264    public void testGetKeySetByAlias() throws Exception {
3265        PackageManager pm = getPm();
3266        String mPkgName = mContext.getPackageName();
3267        String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3268        KeySet ks;
3269        try {
3270            ks = pm.getKeySetByAlias(null, null);
3271            assertTrue(false); // should have thrown
3272        } catch (NullPointerException e) {
3273        }
3274        try {
3275            ks = pm.getKeySetByAlias(null, "keysetBogus");
3276            assertTrue(false); // should have thrown
3277        } catch (NullPointerException e) {
3278        }
3279        try {
3280            ks = pm.getKeySetByAlias("keysets.test.bogus.package", null);
3281            assertTrue(false); // should have thrown
3282        } catch (NullPointerException e) {
3283        }
3284        try {
3285            ks = pm.getKeySetByAlias("keysets.test.bogus.package", "A");
3286            assertTrue(false); // should have thrown
3287        } catch(IllegalArgumentException e) {
3288        }
3289        try {
3290            ks = pm.getKeySetByAlias(mPkgName, "keysetBogus");
3291            assertTrue(false); // should have thrown
3292        } catch(IllegalArgumentException e) {
3293        }
3294
3295        // make sure we can get a KeySet from our pkg
3296        ks = pm.getKeySetByAlias(mPkgName, "A");
3297        assertNotNull(ks);
3298
3299        // and another
3300        final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3301                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3302        try {
3303            ks = pm.getKeySetByAlias(otherPkgName, "A");
3304            assertNotNull(ks);
3305        } finally {
3306            cleanUpInstall(ip);
3307        }
3308    }
3309
3310    public void testIsSignedBy() throws Exception {
3311        PackageManager pm = getPm();
3312        String mPkgName = mContext.getPackageName();
3313        String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3314        KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
3315        KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
3316
3317        try {
3318            assertFalse(pm.isSignedBy(null, null));
3319            assertTrue(false); // should have thrown
3320        } catch (NullPointerException e) {
3321        }
3322        try {
3323            assertFalse(pm.isSignedBy(null, mSigningKS));
3324            assertTrue(false); // should have thrown
3325        } catch (NullPointerException e) {
3326        }
3327        try {
3328            assertFalse(pm.isSignedBy(mPkgName, null));
3329            assertTrue(false); // should have thrown
3330        } catch (NullPointerException e) {
3331        }
3332        try {
3333            assertFalse(pm.isSignedBy("keysets.test.bogus.package", mDefinedKS));
3334        } catch(IllegalArgumentException e) {
3335        }
3336        assertFalse(pm.isSignedBy(mPkgName, mDefinedKS));
3337        assertFalse(pm.isSignedBy(mPkgName, new KeySet(new Binder())));
3338        assertTrue(pm.isSignedBy(mPkgName, mSigningKS));
3339
3340        final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3341                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3342        try {
3343            assertFalse(pm.isSignedBy(otherPkgName, mDefinedKS));
3344            assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
3345        } finally {
3346            cleanUpInstall(ip1);
3347        }
3348
3349        final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
3350                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3351        try {
3352            assertTrue(pm.isSignedBy(otherPkgName, mDefinedKS));
3353            assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
3354        } finally {
3355            cleanUpInstall(ip2);
3356        }
3357    }
3358
3359    public void testIsSignedByExactly() throws Exception {
3360        PackageManager pm = getPm();
3361        String mPkgName = mContext.getPackageName();
3362        String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3363        KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
3364        KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
3365        try {
3366            assertFalse(pm.isSignedBy(null, null));
3367            assertTrue(false); // should have thrown
3368        } catch (NullPointerException e) {
3369        }
3370        try {
3371            assertFalse(pm.isSignedBy(null, mSigningKS));
3372            assertTrue(false); // should have thrown
3373        } catch (NullPointerException e) {
3374        }
3375        try {
3376            assertFalse(pm.isSignedBy(mPkgName, null));
3377            assertTrue(false); // should have thrown
3378        } catch (NullPointerException e) {
3379        }
3380        try {
3381            assertFalse(pm.isSignedByExactly("keysets.test.bogus.package", mDefinedKS));
3382        } catch(IllegalArgumentException e) {
3383        }
3384        assertFalse(pm.isSignedByExactly(mPkgName, mDefinedKS));
3385        assertFalse(pm.isSignedByExactly(mPkgName, new KeySet(new Binder())));
3386        assertTrue(pm.isSignedByExactly(mPkgName, mSigningKS));
3387
3388        final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3389                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3390        try {
3391            assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
3392            assertTrue(pm.isSignedByExactly(otherPkgName, mSigningKS));
3393        } finally {
3394            cleanUpInstall(ip1);
3395        }
3396
3397        final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
3398                0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3399        try {
3400            assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
3401            assertFalse(pm.isSignedByExactly(otherPkgName, mSigningKS));
3402        } finally {
3403            cleanUpInstall(ip2);
3404        }
3405    }
3406
3407
3408
3409    /**
3410     * The following tests are related to testing the checkSignatures api.
3411     */
3412    private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {
3413        checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
3414    }
3415
3416    @LargeTest
3417    public void testCheckSignaturesAllMatch() throws Exception {
3418        int apk1 = APP1_CERT1_CERT2;
3419        int apk2 = APP2_CERT1_CERT2;
3420        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3421    }
3422
3423    @LargeTest
3424    public void testCheckSignaturesNoMatch() throws Exception {
3425        int apk1 = APP1_CERT1;
3426        int apk2 = APP2_CERT2;
3427        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3428    }
3429
3430    @LargeTest
3431    public void testCheckSignaturesSomeMatch1() throws Exception {
3432        int apk1 = APP1_CERT1_CERT2;
3433        int apk2 = APP2_CERT1;
3434        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3435    }
3436
3437    @LargeTest
3438    public void testCheckSignaturesSomeMatch2() throws Exception {
3439        int apk1 = APP1_CERT1_CERT2;
3440        int apk2 = APP2_CERT2;
3441        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3442    }
3443
3444    @LargeTest
3445    public void testCheckSignaturesMoreMatch() throws Exception {
3446        int apk1 = APP1_CERT1;
3447        int apk2 = APP2_CERT1_CERT2;
3448        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3449    }
3450
3451    @LargeTest
3452    public void testCheckSignaturesUnknown() throws Exception {
3453        int apk1 = APP1_CERT1_CERT2;
3454        int apk2 = APP2_CERT1_CERT2;
3455        String apk1Name = "install1.apk";
3456        String apk2Name = "install2.apk";
3457
3458        final InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
3459                false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3460        try {
3461            PackageManager pm = mContext.getPackageManager();
3462            // Delete app2
3463            File filesDir = mContext.getFilesDir();
3464            File outFile = new File(filesDir, apk2Name);
3465            int rawResId = apk2;
3466            Uri packageURI = getInstallablePackage(rawResId, outFile);
3467            PackageParser.Package pkg = parsePackage(packageURI);
3468            getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
3469            // Check signatures now
3470            int match = mContext.getPackageManager().checkSignatures(
3471                    ip.pkg.packageName, pkg.packageName);
3472            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3473        } finally {
3474            cleanUpInstall(ip);
3475        }
3476    }
3477
3478    @LargeTest
3479    public void testInstallNoCertificates() throws Exception {
3480        int apk1 = APP1_UNSIGNED;
3481        String apk1Name = "install1.apk";
3482
3483        installFromRawResource(apk1Name, apk1, 0, false,
3484                true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
3485                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3486    }
3487
3488    /*
3489     * The following tests are related to apps using shared uids signed with
3490     * different certs.
3491     */
3492    private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
3493
3494    private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
3495
3496    private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
3497
3498    private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
3499
3500    private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
3501
3502    private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
3503
3504    private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
3505
3506    private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
3507
3508    private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail,
3509            int retCode, int expMatchResult) throws Exception {
3510        String apk1Name = "install1.apk";
3511        String apk2Name = "install2.apk";
3512        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
3513        PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
3514
3515        try {
3516            // Clean up before testing first.
3517            cleanUpInstall(pkg1.packageName);
3518            cleanUpInstall(pkg2.packageName);
3519            installFromRawResource(apk1Name, apk1, 0, false, false, -1,
3520                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3521            if (fail) {
3522                installFromRawResource(apk2Name, apk2, 0, false, true, retCode,
3523                        PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3524            } else {
3525                installFromRawResource(apk2Name, apk2, 0, false, false, -1,
3526                        PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3527                int match = mContext.getPackageManager().checkSignatures(pkg1.packageName,
3528                        pkg2.packageName);
3529                assertEquals(expMatchResult, match);
3530            }
3531        } finally {
3532            if (cleanUp) {
3533                cleanUpInstall(pkg1.packageName);
3534                cleanUpInstall(pkg2.packageName);
3535            }
3536        }
3537    }
3538
3539    @LargeTest
3540    public void testCheckSignaturesSharedAllMatch() throws Exception {
3541        int apk1 = SHARED1_CERT1_CERT2;
3542        int apk2 = SHARED2_CERT1_CERT2;
3543        boolean fail = false;
3544        int retCode = -1;
3545        int expMatchResult = PackageManager.SIGNATURE_MATCH;
3546        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3547    }
3548
3549    @LargeTest
3550    public void testCheckSignaturesSharedNoMatch() throws Exception {
3551        int apk1 = SHARED1_CERT1;
3552        int apk2 = SHARED2_CERT2;
3553        boolean fail = true;
3554        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3555        int expMatchResult = -1;
3556        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3557    }
3558
3559    /*
3560     * Test that an app signed with cert1 and cert2 cannot be replaced when
3561     * signed with cert1 alone.
3562     */
3563    @LargeTest
3564    public void testCheckSignaturesSharedSomeMatch1() throws Exception {
3565        int apk1 = SHARED1_CERT1_CERT2;
3566        int apk2 = SHARED2_CERT1;
3567        boolean fail = true;
3568        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3569        int expMatchResult = -1;
3570        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3571    }
3572
3573    /*
3574     * Test that an app signed with cert1 and cert2 cannot be replaced when
3575     * signed with cert2 alone.
3576     */
3577    @LargeTest
3578    public void testCheckSignaturesSharedSomeMatch2() throws Exception {
3579        int apk1 = SHARED1_CERT1_CERT2;
3580        int apk2 = SHARED2_CERT2;
3581        boolean fail = true;
3582        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3583        int expMatchResult = -1;
3584        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3585    }
3586
3587    @LargeTest
3588    public void testCheckSignaturesSharedUnknown() throws Exception {
3589        int apk1 = SHARED1_CERT1_CERT2;
3590        int apk2 = SHARED2_CERT1_CERT2;
3591        String apk1Name = "install1.apk";
3592        String apk2Name = "install2.apk";
3593        InstallParams ip1 = null;
3594
3595        try {
3596            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
3597                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3598            PackageManager pm = mContext.getPackageManager();
3599            // Delete app2
3600            PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
3601            getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
3602            // Check signatures now
3603            int match = mContext.getPackageManager().checkSignatures(
3604                    ip1.pkg.packageName, pkg.packageName);
3605            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3606        } finally {
3607            if (ip1 != null) {
3608                cleanUpInstall(ip1);
3609            }
3610        }
3611    }
3612
3613    @LargeTest
3614    public void testReplaceFirstSharedMatchAllCerts() throws Exception {
3615        int apk1 = SHARED1_CERT1;
3616        int apk2 = SHARED2_CERT1;
3617        int rapk1 = SHARED1_CERT1;
3618        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3619        replaceCerts(apk1, rapk1, true, false, -1);
3620    }
3621
3622    @LargeTest
3623    public void testReplaceSecondSharedMatchAllCerts() throws Exception {
3624        int apk1 = SHARED1_CERT1;
3625        int apk2 = SHARED2_CERT1;
3626        int rapk2 = SHARED2_CERT1;
3627        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3628        replaceCerts(apk2, rapk2, true, false, -1);
3629    }
3630
3631    @LargeTest
3632    public void testReplaceFirstSharedMatchSomeCerts() throws Exception {
3633        int apk1 = SHARED1_CERT1_CERT2;
3634        int apk2 = SHARED2_CERT1_CERT2;
3635        int rapk1 = SHARED1_CERT1;
3636        boolean fail = true;
3637        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3638        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3639        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3640                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3641    }
3642
3643    @LargeTest
3644    public void testReplaceSecondSharedMatchSomeCerts() throws Exception {
3645        int apk1 = SHARED1_CERT1_CERT2;
3646        int apk2 = SHARED2_CERT1_CERT2;
3647        int rapk2 = SHARED2_CERT1;
3648        boolean fail = true;
3649        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3650        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3651        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3652                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3653    }
3654
3655    @LargeTest
3656    public void testReplaceFirstSharedMatchNoCerts() throws Exception {
3657        int apk1 = SHARED1_CERT1;
3658        int apk2 = SHARED2_CERT1;
3659        int rapk1 = SHARED1_CERT2;
3660        boolean fail = true;
3661        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3662        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3663        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3664                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3665    }
3666
3667    @LargeTest
3668    public void testReplaceSecondSharedMatchNoCerts() throws Exception {
3669        int apk1 = SHARED1_CERT1;
3670        int apk2 = SHARED2_CERT1;
3671        int rapk2 = SHARED2_CERT2;
3672        boolean fail = true;
3673        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3674        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3675        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3676                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3677    }
3678
3679    @LargeTest
3680    public void testReplaceFirstSharedMatchMoreCerts() throws Exception {
3681        int apk1 = SHARED1_CERT1;
3682        int apk2 = SHARED2_CERT1;
3683        int rapk1 = SHARED1_CERT1_CERT2;
3684        boolean fail = true;
3685        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3686        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3687        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3688                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3689    }
3690
3691    @LargeTest
3692    public void testReplaceSecondSharedMatchMoreCerts() throws Exception {
3693        int apk1 = SHARED1_CERT1;
3694        int apk2 = SHARED2_CERT1;
3695        int rapk2 = SHARED2_CERT1_CERT2;
3696        boolean fail = true;
3697        int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3698        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3699        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3700                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3701    }
3702
3703    /**
3704     * Unknown features should be allowed to install. This prevents older phones
3705     * from rejecting new packages that specify features that didn't exist when
3706     * an older phone existed. All older phones are assumed to have those
3707     * features.
3708     * <p>
3709     * Right now we allow all packages to be installed regardless of their
3710     * features.
3711     */
3712    @LargeTest
3713    public void testUsesFeatureUnknownFeature() throws Exception {
3714        int retCode = PackageManager.INSTALL_SUCCEEDED;
3715        installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode,
3716                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3717    }
3718
3719    @LargeTest
3720    public void testInstallNonexistentFile() throws Exception {
3721        int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
3722        File invalidFile = new File("/nonexistent-file.apk");
3723        invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
3724    }
3725
3726    @SmallTest
3727    public void testGetVerifierDeviceIdentity() throws Exception {
3728        PackageManager pm = getPm();
3729        VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity();
3730
3731        assertNotNull("Verifier device identity should not be null", id);
3732    }
3733
3734    public void testGetInstalledPackages() throws Exception {
3735        List<PackageInfo> packages = getPm().getInstalledPackages(0);
3736        assertNotNull("installed packages cannot be null", packages);
3737        assertTrue("installed packages cannot be empty", packages.size() > 0);
3738    }
3739
3740    public void testGetUnInstalledPackages() throws Exception {
3741        List<PackageInfo> packages = getPm().getInstalledPackages(
3742                PackageManager.MATCH_UNINSTALLED_PACKAGES);
3743        assertNotNull("installed packages cannot be null", packages);
3744        assertTrue("installed packages cannot be empty", packages.size() > 0);
3745    }
3746
3747    /**
3748     * Test that getInstalledPackages returns all the data specified in flags.
3749     */
3750    public void testGetInstalledPackagesAll() throws Exception {
3751        final int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3752                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3753                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3754                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3755                | PackageManager.GET_SIGNATURES | PackageManager.MATCH_UNINSTALLED_PACKAGES;
3756
3757        final InstallParams ip =
3758                installFromRawResource("install.apk", R.raw.install_complete_package_info,
3759                        0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
3760                        PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
3761        try {
3762            final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3763            assertNotNull("installed packages cannot be null", packages);
3764            assertTrue("installed packages cannot be empty", packages.size() > 0);
3765
3766            PackageInfo packageInfo = null;
3767
3768            // Find the package with all components specified in the AndroidManifest
3769            // to ensure no null values
3770            for (PackageInfo pi : packages) {
3771                if ("com.android.frameworks.coretests.install_complete_package_info"
3772                        .equals(pi.packageName)) {
3773                    packageInfo = pi;
3774                    break;
3775                }
3776            }
3777            assertNotNull("activities should not be null", packageInfo.activities);
3778            assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3779            assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3780            assertNotNull("permissions should not be null", packageInfo.permissions);
3781            assertNotNull("providers should not be null", packageInfo.providers);
3782            assertNotNull("receivers should not be null", packageInfo.receivers);
3783            assertNotNull("services should not be null", packageInfo.services);
3784            assertNotNull("signatures should not be null", packageInfo.signatures);
3785        } finally {
3786            cleanUpInstall(ip);
3787        }
3788    }
3789
3790    /**
3791     * Test that getInstalledPackages returns all the data specified in
3792     * flags when the GET_UNINSTALLED_PACKAGES flag is set.
3793     */
3794    public void testGetUnInstalledPackagesAll() throws Exception {
3795        final int flags = PackageManager.MATCH_UNINSTALLED_PACKAGES
3796                | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3797                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3798                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3799                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3800                | PackageManager.GET_SIGNATURES;
3801
3802        // first, install the package
3803        final InstallParams ip =
3804                installFromRawResource("install.apk", R.raw.install_complete_package_info,
3805                        0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
3806                        PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
3807        try {
3808            // then, remove it, keeping it's data around
3809            final GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
3810            invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
3811
3812            final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3813            assertNotNull("installed packages cannot be null", packages);
3814            assertTrue("installed packages cannot be empty", packages.size() > 0);
3815
3816            PackageInfo packageInfo = null;
3817
3818            // Find the package with all components specified in the AndroidManifest
3819            // to ensure no null values
3820            for (PackageInfo pi : packages) {
3821                if ("com.android.frameworks.coretests.install_complete_package_info"
3822                        .equals(pi.packageName)) {
3823                    packageInfo = pi;
3824                    break;
3825                }
3826            }
3827            assertNotNull("activities should not be null", packageInfo.activities);
3828            assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3829            assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3830            assertNotNull("permissions should not be null", packageInfo.permissions);
3831            assertNotNull("providers should not be null", packageInfo.providers);
3832            assertNotNull("receivers should not be null", packageInfo.receivers);
3833            assertNotNull("services should not be null", packageInfo.services);
3834            assertNotNull("signatures should not be null", packageInfo.signatures);
3835        } finally {
3836            cleanUpInstall(ip);
3837        }
3838    }
3839
3840    @Suppress
3841    public void testInstall_BadDex_CleanUp() throws Exception {
3842        int retCode = PackageManager.INSTALL_FAILED_DEXOPT;
3843        installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
3844                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3845    }
3846
3847    /*---------- Recommended install location tests ----*/
3848    /*
3849     * TODO's
3850     * check version numbers for upgrades
3851     * check permissions of installed packages
3852     * how to do tests on updated system apps?
3853     * verify updates to system apps cannot be installed on the sdcard.
3854     */
3855}
3856