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