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