PackageManagerTests.java revision 625239a05401bbf18b04d9874cea3f82da7c29a1
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);
985            observer.waitForCompletion(MAX_WAIT_TIME);
986
987            assertUninstalled(info);
988
989            // Verify we received the broadcast
990            long waitTime = 0;
991            while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
992                receiver.wait(WAIT_TIME_INCR);
993                waitTime += WAIT_TIME_INCR;
994            }
995            if (!receiver.isDone()) {
996                throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
997            }
998            return receiver.received;
999        } finally {
1000            mContext.unregisterReceiver(receiver);
1001        }
1002    }
1003
1004    private static void assertUninstalled(ApplicationInfo info) throws Exception {
1005        File nativeLibraryFile = new File(info.nativeLibraryDir);
1006        assertFalse("Native library directory should be erased", nativeLibraryFile.exists());
1007    }
1008
1009    public void deleteFromRawResource(int iFlags, int dFlags) throws Exception {
1010        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1011        boolean retainData = ((dFlags & PackageManager.DELETE_KEEP_DATA) != 0);
1012        GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1013        try {
1014            assertTrue(invokeDeletePackage(ip.pkg.packageName, dFlags, receiver));
1015            ApplicationInfo info = null;
1016            Log.i(TAG, "okay4");
1017            try {
1018                info = getPm().getApplicationInfo(ip.pkg.packageName,
1019                        PackageManager.GET_UNINSTALLED_PACKAGES);
1020            } catch (NameNotFoundException e) {
1021                info = null;
1022            }
1023            if (retainData) {
1024                assertNotNull(info);
1025                assertEquals(info.packageName, ip.pkg.packageName);
1026                File file = new File(info.dataDir);
1027                assertTrue(file.exists());
1028            } else {
1029                assertNull(info);
1030            }
1031        } catch (Exception e) {
1032            failStr(e);
1033        } finally {
1034            cleanUpInstall(ip);
1035        }
1036    }
1037
1038    @LargeTest
1039    public void testDeleteNormalInternal() throws Exception {
1040        deleteFromRawResource(0, 0);
1041    }
1042
1043    @LargeTest
1044    public void testDeleteFwdLockedInternal() throws Exception {
1045        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
1046    }
1047
1048    @LargeTest
1049    public void testDeleteSdcard() throws Exception {
1050        // Do not run on devices with emulated external storage.
1051        if (Environment.isExternalStorageEmulated()) {
1052            return;
1053        }
1054
1055        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
1056    }
1057
1058    @LargeTest
1059    public void testDeleteNormalInternalRetainData() throws Exception {
1060        deleteFromRawResource(0, PackageManager.DELETE_KEEP_DATA);
1061    }
1062
1063    @LargeTest
1064    public void testDeleteFwdLockedInternalRetainData() throws Exception {
1065        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DELETE_KEEP_DATA);
1066    }
1067
1068    @LargeTest
1069    public void testDeleteSdcardRetainData() throws Exception {
1070        // Do not run on devices with emulated external storage.
1071        if (Environment.isExternalStorageEmulated()) {
1072            return;
1073        }
1074
1075        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DELETE_KEEP_DATA);
1076    }
1077
1078    /* sdcard mount/unmount tests ***** */
1079
1080    class SdMountReceiver extends GenericReceiver {
1081        String pkgNames[];
1082
1083        boolean status = true;
1084
1085        SdMountReceiver(String[] pkgNames) {
1086            this.pkgNames = pkgNames;
1087            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1088            super.setFilter(filter);
1089        }
1090
1091        public boolean notifyNow(Intent intent) {
1092            Log.i(TAG, "okay 1");
1093            String action = intent.getAction();
1094            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1095                return false;
1096            }
1097            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1098            for (String pkg : pkgNames) {
1099                boolean found = false;
1100                for (String rpkg : rpkgList) {
1101                    if (rpkg.equals(pkg)) {
1102                        found = true;
1103                        break;
1104                    }
1105                }
1106                if (!found) {
1107                    status = false;
1108                    return true;
1109                }
1110            }
1111            return true;
1112        }
1113    }
1114
1115    class SdUnMountReceiver extends GenericReceiver {
1116        String pkgNames[];
1117
1118        boolean status = true;
1119
1120        SdUnMountReceiver(String[] pkgNames) {
1121            this.pkgNames = pkgNames;
1122            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1123            super.setFilter(filter);
1124        }
1125
1126        public boolean notifyNow(Intent intent) {
1127            String action = intent.getAction();
1128            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1129                return false;
1130            }
1131            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1132            for (String pkg : pkgNames) {
1133                boolean found = false;
1134                for (String rpkg : rpkgList) {
1135                    if (rpkg.equals(pkg)) {
1136                        found = true;
1137                        break;
1138                    }
1139                }
1140                if (!found) {
1141                    status = false;
1142                    return true;
1143                }
1144            }
1145            return true;
1146        }
1147    }
1148
1149    IMountService getMs() {
1150        IBinder service = ServiceManager.getService("mount");
1151        if (service != null) {
1152            return IMountService.Stub.asInterface(service);
1153        } else {
1154            Log.e(TAG, "Can't get mount service");
1155        }
1156        return null;
1157    }
1158
1159    boolean checkMediaState(String desired) {
1160        try {
1161            String mPath = Environment.getExternalStorageDirectory().getPath();
1162            String actual = getMs().getVolumeState(mPath);
1163            if (desired.equals(actual)) {
1164                return true;
1165            } else {
1166                return false;
1167            }
1168        } catch (RemoteException e) {
1169            Log.e(TAG, "Exception while checking media state", e);
1170            return false;
1171        }
1172    }
1173
1174    boolean mountMedia() {
1175        // We can't mount emulated storage.
1176        if (Environment.isExternalStorageEmulated()) {
1177            return true;
1178        }
1179
1180        if (checkMediaState(Environment.MEDIA_MOUNTED)) {
1181            return true;
1182        }
1183
1184        final String path = Environment.getExternalStorageDirectory().toString();
1185        StorageListener observer = new StorageListener(Environment.MEDIA_MOUNTED);
1186        StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
1187        sm.registerListener(observer);
1188        try {
1189            // Wait on observer
1190            synchronized (observer) {
1191                int ret = getMs().mountVolume(path);
1192                if (ret != StorageResultCode.OperationSucceeded) {
1193                    throw new Exception("Could not mount the media");
1194                }
1195                long waitTime = 0;
1196                while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1197                    observer.wait(WAIT_TIME_INCR);
1198                    waitTime += WAIT_TIME_INCR;
1199                }
1200                if (!observer.isDone()) {
1201                    throw new Exception("Timed out waiting for unmount media notification");
1202                }
1203                return true;
1204            }
1205        } catch (Exception e) {
1206            Log.e(TAG, "Exception : " + e);
1207            return false;
1208        } finally {
1209            sm.unregisterListener(observer);
1210        }
1211    }
1212
1213    private boolean unmountMedia() {
1214        // We can't unmount emulated storage.
1215        if (Environment.isExternalStorageEmulated()) {
1216            return true;
1217        }
1218
1219        if (checkMediaState(Environment.MEDIA_UNMOUNTED)) {
1220            return true;
1221        }
1222
1223        final String path = Environment.getExternalStorageDirectory().getPath();
1224        StorageListener observer = new StorageListener(Environment.MEDIA_UNMOUNTED);
1225        StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
1226        sm.registerListener(observer);
1227        try {
1228            // Wait on observer
1229            synchronized (observer) {
1230                getMs().unmountVolume(path, true, false);
1231                long waitTime = 0;
1232                while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1233                    observer.wait(WAIT_TIME_INCR);
1234                    waitTime += WAIT_TIME_INCR;
1235                }
1236                if (!observer.isDone()) {
1237                    throw new Exception("Timed out waiting for unmount media notification");
1238                }
1239                return true;
1240            }
1241        } catch (Exception e) {
1242            Log.e(TAG, "Exception : " + e);
1243            return false;
1244        } finally {
1245            sm.unregisterListener(observer);
1246        }
1247    }
1248
1249    private boolean mountFromRawResource() throws Exception {
1250        // Install pkg on sdcard
1251        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
1252        if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
1253        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1254        boolean registeredReceiver = false;
1255        SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
1256        try {
1257            if (localLOGV) Log.i(TAG, "Unmounting media");
1258            // Unmount media
1259            assertTrue(unmountMedia());
1260            if (localLOGV) Log.i(TAG, "Unmounted media");
1261            // Register receiver here
1262            PackageManager pm = getPm();
1263            mContext.registerReceiver(receiver, receiver.filter);
1264            registeredReceiver = true;
1265
1266            // Wait on receiver
1267            synchronized (receiver) {
1268                if (localLOGV) Log.i(TAG, "Mounting media");
1269                // Mount media again
1270                assertTrue(mountMedia());
1271                if (localLOGV) Log.i(TAG, "Mounted media");
1272                if (localLOGV) Log.i(TAG, "Waiting for notification");
1273                long waitTime = 0;
1274                // Verify we received the broadcast
1275                waitTime = 0;
1276                while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1277                    receiver.wait(WAIT_TIME_INCR);
1278                    waitTime += WAIT_TIME_INCR;
1279                }
1280                if(!receiver.isDone()) {
1281                    failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification");
1282                }
1283                return receiver.received;
1284            }
1285        } catch (InterruptedException e) {
1286            failStr(e);
1287            return false;
1288        } finally {
1289            if (registeredReceiver) {
1290                mContext.unregisterReceiver(receiver);
1291            }
1292            // Restore original media state
1293            if (origState) {
1294                mountMedia();
1295            } else {
1296                unmountMedia();
1297            }
1298            if (localLOGV) Log.i(TAG, "Cleaning up install");
1299            cleanUpInstall(ip);
1300        }
1301    }
1302
1303    /*
1304     * Install package on sdcard. Unmount and then mount the media.
1305     * (Use PackageManagerService private api for now)
1306     * Make sure the installed package is available.
1307     */
1308    @LargeTest
1309    public void testMountSdNormalInternal() throws Exception {
1310        // Do not run on devices with emulated external storage.
1311        if (Environment.isExternalStorageEmulated()) {
1312            return;
1313        }
1314
1315        assertTrue(mountFromRawResource());
1316    }
1317
1318    void cleanUpInstall(InstallParams ip) throws Exception {
1319        if (ip == null) {
1320            return;
1321        }
1322        Runtime.getRuntime().gc();
1323
1324        final String packageName = ip.pkg.packageName;
1325        Log.i(TAG, "Deleting package : " + packageName);
1326
1327        ApplicationInfo info = null;
1328        try {
1329            info = getPm().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
1330        } catch (NameNotFoundException ignored) {
1331        }
1332
1333        DeleteObserver observer = new DeleteObserver(packageName);
1334        getPm().deletePackage(packageName, observer, 0);
1335        observer.waitForCompletion(MAX_WAIT_TIME);
1336
1337        try {
1338            if (info != null) {
1339                assertUninstalled(info);
1340            }
1341        } finally {
1342            File outFile = new File(ip.pkg.mScanPath);
1343            if (outFile != null && outFile.exists()) {
1344                outFile.delete();
1345            }
1346        }
1347    }
1348
1349    private void cleanUpInstall(String pkgName) throws Exception {
1350        if (pkgName == null) {
1351            return;
1352        }
1353        Log.i(TAG, "Deleting package : " + pkgName);
1354        try {
1355            ApplicationInfo info = getPm().getApplicationInfo(pkgName,
1356                    PackageManager.GET_UNINSTALLED_PACKAGES);
1357
1358            if (info != null) {
1359                DeleteObserver observer = new DeleteObserver(pkgName);
1360                getPm().deletePackage(pkgName, observer, 0);
1361                observer.waitForCompletion(MAX_WAIT_TIME);
1362                assertUninstalled(info);
1363            }
1364        } catch (NameNotFoundException e) {
1365        }
1366    }
1367
1368    @LargeTest
1369    public void testManifestInstallLocationInternal() throws Exception {
1370        installFromRawResource("install.apk", R.raw.install_loc_internal,
1371                0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1372    }
1373
1374    @LargeTest
1375    public void testManifestInstallLocationSdcard() throws Exception {
1376        // Do not run on devices with emulated external storage.
1377        if (Environment.isExternalStorageEmulated()) {
1378            return;
1379        }
1380
1381        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1382                0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1383    }
1384
1385    @LargeTest
1386    public void testManifestInstallLocationAuto() throws Exception {
1387        installFromRawResource("install.apk", R.raw.install_loc_auto,
1388                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
1389    }
1390
1391    @LargeTest
1392    public void testManifestInstallLocationUnspecified() throws Exception {
1393        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1394                0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1395    }
1396
1397    @LargeTest
1398    public void testManifestInstallLocationFwdLockedFlagSdcard() throws Exception {
1399        // Do not run on devices with emulated external storage.
1400        if (Environment.isExternalStorageEmulated()) {
1401            return;
1402        }
1403
1404        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1405                PackageManager.INSTALL_FORWARD_LOCK |
1406                PackageManager.INSTALL_EXTERNAL, true, false, -1,
1407                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1408    }
1409
1410    @LargeTest
1411    public void testManifestInstallLocationFwdLockedSdcard() throws Exception {
1412        // Do not run on devices with emulated external storage.
1413        if (Environment.isExternalStorageEmulated()) {
1414            return;
1415        }
1416
1417        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1418                PackageManager.INSTALL_FORWARD_LOCK, true, false, -1,
1419                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1420    }
1421
1422    /*
1423     * Install a package on internal flash via PackageManager install flag. Replace
1424     * the package via flag to install on sdcard. Make sure the new flag overrides
1425     * the old install location.
1426     */
1427    @LargeTest
1428    public void testReplaceFlagInternalSdcard() throws Exception {
1429        // Do not run on devices with emulated external storage.
1430        if (Environment.isExternalStorageEmulated()) {
1431            return;
1432        }
1433
1434        int iFlags = 0;
1435        int rFlags = PackageManager.INSTALL_EXTERNAL;
1436        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1437        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1438        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1439        try {
1440            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1441            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
1442        } catch (Exception e) {
1443            failStr("Failed with exception : " + e);
1444        } finally {
1445            cleanUpInstall(ip);
1446        }
1447    }
1448
1449    /*
1450     * Install a package on sdcard via PackageManager install flag. Replace
1451     * the package with no flags or manifest option and make sure the old
1452     * install location is retained.
1453     */
1454    @LargeTest
1455    public void testReplaceFlagSdcardInternal() throws Exception {
1456        // Do not run on devices with emulated external storage.
1457        if (Environment.isExternalStorageEmulated()) {
1458            return;
1459        }
1460
1461        int iFlags = PackageManager.INSTALL_EXTERNAL;
1462        int rFlags = 0;
1463        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1464        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1465        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1466        try {
1467            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1468            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1469        } catch (Exception e) {
1470            failStr("Failed with exception : " + e);
1471        } finally {
1472            cleanUpInstall(ip);
1473        }
1474    }
1475
1476    @LargeTest
1477    public void testManifestInstallLocationReplaceInternalSdcard() throws Exception {
1478        // Do not run on devices with emulated external storage.
1479        if (Environment.isExternalStorageEmulated()) {
1480            return;
1481        }
1482
1483        int iFlags = 0;
1484        int iApk = R.raw.install_loc_internal;
1485        int rFlags = 0;
1486        int rApk = R.raw.install_loc_sdcard;
1487        InstallParams ip = installFromRawResource("install.apk", iApk,
1488                iFlags, false,
1489                false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1490        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1491        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1492        try {
1493            InstallParams rp = installFromRawResource("install.apk", rApk,
1494                    replaceFlags, false,
1495                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1496            assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1497        } catch (Exception e) {
1498            failStr("Failed with exception : " + e);
1499        } finally {
1500            cleanUpInstall(ip);
1501        }
1502    }
1503
1504    @LargeTest
1505    public void testManifestInstallLocationReplaceSdcardInternal() throws Exception {
1506        // Do not run on devices with emulated external storage.
1507        if (Environment.isExternalStorageEmulated()) {
1508            return;
1509        }
1510
1511        int iFlags = 0;
1512        int iApk = R.raw.install_loc_sdcard;
1513        int rFlags = 0;
1514        int rApk = R.raw.install_loc_unspecified;
1515        InstallParams ip = installFromRawResource("install.apk", iApk,
1516                iFlags, false,
1517                false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1518        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1519        try {
1520            InstallParams rp = installFromRawResource("install.apk", rApk,
1521                    replaceFlags, false,
1522                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1523            assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1524        } catch (Exception e) {
1525            failStr("Failed with exception : " + e);
1526        } finally {
1527            cleanUpInstall(ip);
1528        }
1529    }
1530
1531    class MoveReceiver extends GenericReceiver {
1532        String pkgName;
1533
1534        final static int INVALID = -1;
1535
1536        final static int REMOVED = 1;
1537
1538        final static int ADDED = 2;
1539
1540        int removed = INVALID;
1541
1542        MoveReceiver(String pkgName) {
1543            this.pkgName = pkgName;
1544            filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1545            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1546            super.setFilter(filter);
1547        }
1548
1549        public boolean notifyNow(Intent intent) {
1550            String action = intent.getAction();
1551            Log.i(TAG, "MoveReceiver::" + action);
1552            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1553                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1554                if (list != null) {
1555                    for (String pkg : list) {
1556                        if (pkg.equals(pkgName)) {
1557                            removed = REMOVED;
1558                            break;
1559                        }
1560                    }
1561                }
1562                removed = REMOVED;
1563            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1564                if (removed != REMOVED) {
1565                    return false;
1566                }
1567                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1568                if (list != null) {
1569                    for (String pkg : list) {
1570                        if (pkg.equals(pkgName)) {
1571                            removed = ADDED;
1572                            return true;
1573                        }
1574                    }
1575                }
1576            }
1577            return false;
1578        }
1579    }
1580
1581    private class PackageMoveObserver extends IPackageMoveObserver.Stub {
1582        public int returnCode;
1583
1584        private boolean doneFlag = false;
1585
1586        public String packageName;
1587
1588        public PackageMoveObserver(String pkgName) {
1589            packageName = pkgName;
1590        }
1591
1592        public void packageMoved(String packageName, int returnCode) {
1593            Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode);
1594            if (!packageName.equals(this.packageName)) {
1595                return;
1596            }
1597            synchronized (this) {
1598                this.returnCode = returnCode;
1599                doneFlag = true;
1600                notifyAll();
1601            }
1602        }
1603
1604        public boolean isDone() {
1605            return doneFlag;
1606        }
1607    }
1608
1609    public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)
1610            throws Exception {
1611        PackageMoveObserver observer = new PackageMoveObserver(pkgName);
1612        final boolean received = false;
1613        mContext.registerReceiver(receiver, receiver.filter);
1614        try {
1615            // Wait on observer
1616            synchronized (observer) {
1617                synchronized (receiver) {
1618                    getPm().movePackage(pkgName, observer, flags);
1619                    long waitTime = 0;
1620                    while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1621                        observer.wait(WAIT_TIME_INCR);
1622                        waitTime += WAIT_TIME_INCR;
1623                    }
1624                    if (!observer.isDone()) {
1625                        throw new Exception("Timed out waiting for pkgmove callback");
1626                    }
1627                    if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) {
1628                        return false;
1629                    }
1630                    // Verify we received the broadcast
1631                    waitTime = 0;
1632                    while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1633                        receiver.wait(WAIT_TIME_INCR);
1634                        waitTime += WAIT_TIME_INCR;
1635                    }
1636                    if (!receiver.isDone()) {
1637                        throw new Exception("Timed out waiting for MOVE notifications");
1638                    }
1639                    return receiver.received;
1640                }
1641            }
1642        } finally {
1643            mContext.unregisterReceiver(receiver);
1644        }
1645    }
1646
1647    private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
1648        PackageMoveObserver observer = new PackageMoveObserver(pkgName);
1649        try {
1650            // Wait on observer
1651            synchronized (observer) {
1652                getPm().movePackage(pkgName, observer, flags);
1653                long waitTime = 0;
1654                while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1655                    observer.wait(WAIT_TIME_INCR);
1656                    waitTime += WAIT_TIME_INCR;
1657                }
1658                if (!observer.isDone()) {
1659                    throw new Exception("Timed out waiting for pkgmove callback");
1660                }
1661                assertEquals(errCode, observer.returnCode);
1662            }
1663        } finally {
1664        }
1665        return true;
1666    }
1667
1668    private int getDefaultInstallLoc() {
1669        int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1670        try {
1671            origDefaultLoc = Settings.Global.getInt(mContext.getContentResolver(),
1672                    Settings.Global.DEFAULT_INSTALL_LOCATION);
1673        } catch (SettingNotFoundException e1) {
1674        }
1675        return origDefaultLoc;
1676    }
1677
1678    private void setInstallLoc(int loc) {
1679        Settings.Global.putInt(mContext.getContentResolver(),
1680                Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
1681    }
1682
1683    /*
1684     * Tests for moving apps between internal and external storage
1685     */
1686    /*
1687     * Utility function that reads a apk bundled as a raw resource
1688     * copies it into own data directory and invokes
1689     * PackageManager api to install first and then replace it
1690     * again.
1691     */
1692
1693    private void moveFromRawResource(String outFileName, int rawResId, int installFlags,
1694            int moveFlags, boolean cleanUp, boolean fail, int result) throws Exception {
1695        int origDefaultLoc = getDefaultInstallLoc();
1696        InstallParams ip = null;
1697        try {
1698            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1699            // Install first
1700            ip = installFromRawResource("install.apk", rawResId, installFlags, false,
1701                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1702            ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1703            if (fail) {
1704                assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1705                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1706                assertNotNull(info);
1707                assertEquals(oldAppInfo.flags, info.flags);
1708            } else {
1709                // Create receiver based on expRetCode
1710                MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1711                boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, receiver);
1712                assertTrue(retCode);
1713                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1714                assertNotNull("ApplicationInfo for recently installed application should exist",
1715                        info);
1716                if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1717                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set",
1718                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1719                    assertStartsWith("Native library dir should be in dataDir",
1720                            info.dataDir, info.nativeLibraryDir);
1721                } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0) {
1722                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set",
1723                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1724                    assertStartsWith("Native library dir should point to ASEC",
1725                            SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
1726                    final File nativeLibSymLink = new File(info.dataDir, "lib");
1727                    assertStartsWith("The data directory should have a 'lib' symlink that points to the ASEC container",
1728                            SECURE_CONTAINERS_PREFIX, nativeLibSymLink.getCanonicalPath());
1729                }
1730            }
1731        } catch (NameNotFoundException e) {
1732            failStr("Pkg hasnt been installed correctly");
1733        } catch (Exception e) {
1734            failStr("Failed with exception : " + e);
1735        } finally {
1736            if (ip != null) {
1737                cleanUpInstall(ip);
1738            }
1739            // Restore default install location
1740            setInstallLoc(origDefaultLoc);
1741        }
1742    }
1743
1744    private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
1745            int result) throws Exception {
1746        moveFromRawResource("install.apk",
1747                R.raw.install, installFlags, moveFlags, true,
1748                fail, result);
1749    }
1750
1751    @LargeTest
1752    public void testMoveAppInternalToExternal() throws Exception {
1753        // Do not run on devices with emulated external storage.
1754        if (Environment.isExternalStorageEmulated()) {
1755            return;
1756        }
1757
1758        int installFlags = PackageManager.INSTALL_INTERNAL;
1759        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1760        boolean fail = false;
1761        int result = PackageManager.MOVE_SUCCEEDED;
1762        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1763    }
1764
1765    @LargeTest
1766    public void testMoveAppInternalToInternal() throws Exception {
1767        int installFlags = PackageManager.INSTALL_INTERNAL;
1768        int moveFlags = PackageManager.MOVE_INTERNAL;
1769        boolean fail = true;
1770        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1771        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1772    }
1773
1774    @LargeTest
1775    public void testMoveAppExternalToExternal() throws Exception {
1776        // Do not run on devices with emulated external storage.
1777        if (Environment.isExternalStorageEmulated()) {
1778            return;
1779        }
1780
1781        int installFlags = PackageManager.INSTALL_EXTERNAL;
1782        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1783        boolean fail = true;
1784        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1785        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1786    }
1787
1788    @LargeTest
1789    public void testMoveAppExternalToInternal() throws Exception {
1790        // Do not run on devices with emulated external storage.
1791        if (Environment.isExternalStorageEmulated()) {
1792            return;
1793        }
1794
1795        int installFlags = PackageManager.INSTALL_EXTERNAL;
1796        int moveFlags = PackageManager.MOVE_INTERNAL;
1797        boolean fail = false;
1798        int result = PackageManager.MOVE_SUCCEEDED;
1799        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1800    }
1801
1802    @LargeTest
1803    public void testMoveAppForwardLocked() throws Exception {
1804        // Do not run on devices with emulated external storage.
1805        if (Environment.isExternalStorageEmulated()) {
1806            return;
1807        }
1808
1809        int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
1810        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1811        boolean fail = false;
1812        int result = PackageManager.MOVE_SUCCEEDED;
1813        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1814    }
1815
1816    @LargeTest
1817    public void testMoveAppFailInternalToExternalDelete() throws Exception {
1818        // Do not run on devices with emulated external storage.
1819        if (Environment.isExternalStorageEmulated()) {
1820            return;
1821        }
1822
1823        int installFlags = 0;
1824        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1825        boolean fail = true;
1826        final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
1827
1828        int rawResId = R.raw.install;
1829        int origDefaultLoc = getDefaultInstallLoc();
1830        InstallParams ip = null;
1831        try {
1832            PackageManager pm = getPm();
1833            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1834            // Install first
1835            ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
1836                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1837            // Delete the package now retaining data.
1838            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1839            invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
1840            assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1841        } catch (Exception e) {
1842            failStr(e);
1843        } finally {
1844            if (ip != null) {
1845                cleanUpInstall(ip);
1846            }
1847            // Restore default install location
1848            setInstallLoc(origDefaultLoc);
1849        }
1850    }
1851
1852    /*
1853     * Test that an install error code is returned when media is unmounted
1854     * and package installed on sdcard via package manager flag.
1855     */
1856    @LargeTest
1857    public void testInstallSdcardUnmount() throws Exception {
1858        // Do not run on devices with emulated external storage.
1859        if (Environment.isExternalStorageEmulated()) {
1860            return;
1861        }
1862
1863        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1864        try {
1865            // Unmount sdcard
1866            assertTrue(unmountMedia());
1867            // Try to install and make sure an error code is returned.
1868            installFromRawResource("install.apk", R.raw.install,
1869                    PackageManager.INSTALL_EXTERNAL, false,
1870                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1871                    PackageInfo.INSTALL_LOCATION_AUTO);
1872        } finally {
1873            // Restore original media state
1874            if (origState) {
1875                mountMedia();
1876            } else {
1877                unmountMedia();
1878            }
1879        }
1880    }
1881
1882    /*
1883     * Unmount sdcard. Try installing an app with manifest option to install
1884     * on sdcard. Make sure it gets installed on internal flash.
1885     */
1886    @LargeTest
1887    public void testInstallManifestSdcardUnmount() throws Exception {
1888        // Do not run on devices with emulated external storage.
1889        if (Environment.isExternalStorageEmulated()) {
1890            return;
1891        }
1892
1893        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1894        try {
1895            // Unmount sdcard
1896            assertTrue(unmountMedia());
1897            InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
1898            installFromRawResource(ip, 0, true, false, -1,
1899                    PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1900        } finally {
1901            // Restore original media state
1902            if (origState) {
1903                mountMedia();
1904            } else {
1905                unmountMedia();
1906            }
1907        }
1908    }
1909
1910    /*---------- Recommended install location tests ----*/
1911    /*
1912     * PrecedenceSuffixes:
1913     * Flag : FlagI, FlagE, FlagF
1914     * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1915     * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1916     * Existing: Existing suffix absent if not existing.
1917     * User: UserI, UserE, UserA, User suffix absent if not existing.
1918     *
1919     */
1920
1921    /*
1922     * Install an app on internal flash
1923     */
1924    @LargeTest
1925    public void testFlagI() throws Exception {
1926        sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1927    }
1928
1929    /*
1930     * Install an app on sdcard.
1931     */
1932    @LargeTest
1933    public void testFlagE() throws Exception {
1934        // Do not run on devices with emulated external storage.
1935        if (Environment.isExternalStorageEmulated()) {
1936            return;
1937        }
1938
1939        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1940    }
1941
1942    /*
1943     * Install an app forward-locked.
1944     */
1945    @LargeTest
1946    public void testFlagF() throws Exception {
1947        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1948    }
1949
1950    /*
1951     * Install an app with both internal and external flags set. should fail
1952     */
1953    @LargeTest
1954    public void testFlagIE() throws Exception {
1955        installFromRawResource("install.apk", R.raw.install,
1956                PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1957                false,
1958                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1959                PackageInfo.INSTALL_LOCATION_AUTO);
1960    }
1961
1962    /*
1963     * Install an app with both internal and forward-lock flags set.
1964     */
1965    @LargeTest
1966    public void testFlagIF() throws Exception {
1967        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1968                | PackageManager.INSTALL_INTERNAL, true);
1969    }
1970
1971    /*
1972     * Install an app with both external and forward-lock flags set.
1973     */
1974    @LargeTest
1975    public void testFlagEF() throws Exception {
1976        // Do not run on devices with emulated external storage.
1977        if (Environment.isExternalStorageEmulated()) {
1978            return;
1979        }
1980
1981        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1982                | PackageManager.INSTALL_EXTERNAL, true);
1983    }
1984
1985    /*
1986     * Install an app with both internal and external flags set with forward
1987     * lock. Should fail.
1988     */
1989    @LargeTest
1990    public void testFlagIEF() throws Exception {
1991        installFromRawResource("install.apk", R.raw.install,
1992                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1993                PackageManager.INSTALL_EXTERNAL,
1994                false,
1995                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1996                PackageInfo.INSTALL_LOCATION_AUTO);
1997    }
1998
1999    /*
2000     * Install an app with both internal and manifest option set.
2001     * should install on internal.
2002     */
2003    @LargeTest
2004    public void testFlagIManifestI() throws Exception {
2005        installFromRawResource("install.apk", R.raw.install_loc_internal,
2006                PackageManager.INSTALL_INTERNAL,
2007                true,
2008                false, -1,
2009                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2010    }
2011    /*
2012     * Install an app with both internal and manifest preference for
2013     * preferExternal. Should install on internal.
2014     */
2015    @LargeTest
2016    public void testFlagIManifestE() throws Exception {
2017        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2018                PackageManager.INSTALL_INTERNAL,
2019                true,
2020                false, -1,
2021                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2022    }
2023    /*
2024     * Install an app with both internal and manifest preference for
2025     * auto. should install internal.
2026     */
2027    @LargeTest
2028    public void testFlagIManifestA() throws Exception {
2029        installFromRawResource("install.apk", R.raw.install_loc_auto,
2030                PackageManager.INSTALL_INTERNAL,
2031                true,
2032                false, -1,
2033                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2034    }
2035    /*
2036     * Install an app with both external and manifest option set.
2037     * should install externally.
2038     */
2039    @LargeTest
2040    public void testFlagEManifestI() throws Exception {
2041        // Do not run on devices with emulated external storage.
2042        if (Environment.isExternalStorageEmulated()) {
2043            return;
2044        }
2045
2046        installFromRawResource("install.apk", R.raw.install_loc_internal,
2047                PackageManager.INSTALL_EXTERNAL,
2048                true,
2049                false, -1,
2050                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2051    }
2052
2053    /*
2054     * Install an app with both external and manifest preference for
2055     * preferExternal. Should install externally.
2056     */
2057    @LargeTest
2058    public void testFlagEManifestE() throws Exception {
2059        // Do not run on devices with emulated external storage.
2060        if (Environment.isExternalStorageEmulated()) {
2061            return;
2062        }
2063
2064        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2065                PackageManager.INSTALL_EXTERNAL,
2066                true,
2067                false, -1,
2068                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2069    }
2070
2071    /*
2072     * Install an app with both external and manifest preference for
2073     * auto. should install on external media.
2074     */
2075    @LargeTest
2076    public void testFlagEManifestA() throws Exception {
2077        // Do not run on devices with emulated external storage.
2078        if (Environment.isExternalStorageEmulated()) {
2079            return;
2080        }
2081
2082        installFromRawResource("install.apk", R.raw.install_loc_auto,
2083                PackageManager.INSTALL_EXTERNAL,
2084                true,
2085                false, -1,
2086                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2087    }
2088
2089    /*
2090     * Install an app with fwd locked flag set and install location set to
2091     * internal. should install internally.
2092     */
2093    @LargeTest
2094    public void testFlagFManifestI() throws Exception {
2095        installFromRawResource("install.apk", R.raw.install_loc_internal,
2096                PackageManager.INSTALL_FORWARD_LOCK,
2097                true,
2098                false, -1,
2099                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2100    }
2101
2102    /*
2103     * Install an app with fwd locked flag set and install location set to
2104     * preferExternal. Should install externally.
2105     */
2106    @LargeTest
2107    public void testFlagFManifestE() throws Exception {
2108        // Do not run on devices with emulated external storage.
2109        if (Environment.isExternalStorageEmulated()) {
2110            return;
2111        }
2112
2113        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2114                PackageManager.INSTALL_FORWARD_LOCK,
2115                true,
2116                false, -1,
2117                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2118    }
2119
2120    /*
2121     * Install an app with fwd locked flag set and install location set to auto.
2122     * should install externally.
2123     */
2124    @LargeTest
2125    public void testFlagFManifestA() throws Exception {
2126        // Do not run on devices with emulated external storage.
2127        if (Environment.isExternalStorageEmulated()) {
2128            return;
2129        }
2130
2131        installFromRawResource("install.apk", R.raw.install_loc_auto,
2132                PackageManager.INSTALL_FORWARD_LOCK,
2133                true,
2134                false, -1,
2135                PackageInfo.INSTALL_LOCATION_AUTO);
2136    }
2137
2138    /*
2139     * The following test functions verify install location for existing apps.
2140     * ie existing app can be installed internally or externally. If install
2141     * flag is explicitly set it should override current location. If manifest location
2142     * is set, that should over ride current location too. if not the existing install
2143     * location should be honoured.
2144     * testFlagI/E/F/ExistingI/E -
2145     */
2146    @LargeTest
2147    public void testFlagIExistingI() throws Exception {
2148        int iFlags = PackageManager.INSTALL_INTERNAL;
2149        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2150        // First install.
2151        installFromRawResource("install.apk", R.raw.install,
2152                iFlags,
2153                false,
2154                false, -1,
2155                -1);
2156        // Replace now
2157        installFromRawResource("install.apk", R.raw.install,
2158                rFlags,
2159                true,
2160                false, -1,
2161                -1);
2162    }
2163
2164    @LargeTest
2165    public void testFlagIExistingE() throws Exception {
2166        // Do not run on devices with emulated external storage.
2167        if (Environment.isExternalStorageEmulated()) {
2168            return;
2169        }
2170
2171        int iFlags = PackageManager.INSTALL_EXTERNAL;
2172        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2173        // First install.
2174        installFromRawResource("install.apk", R.raw.install,
2175                iFlags,
2176                false,
2177                false, -1,
2178                -1);
2179        // Replace now
2180        installFromRawResource("install.apk", R.raw.install,
2181                rFlags,
2182                true,
2183                false, -1,
2184                -1);
2185    }
2186
2187    @LargeTest
2188    public void testFlagEExistingI() throws Exception {
2189        // Do not run on devices with emulated external storage.
2190        if (Environment.isExternalStorageEmulated()) {
2191            return;
2192        }
2193
2194        int iFlags = PackageManager.INSTALL_INTERNAL;
2195        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2196        // First install.
2197        installFromRawResource("install.apk", R.raw.install,
2198                iFlags,
2199                false,
2200                false, -1,
2201                -1);
2202        // Replace now
2203        installFromRawResource("install.apk", R.raw.install,
2204                rFlags,
2205                true,
2206                false, -1,
2207                -1);
2208    }
2209
2210    @LargeTest
2211    public void testFlagEExistingE() throws Exception {
2212        // Do not run on devices with emulated external storage.
2213        if (Environment.isExternalStorageEmulated()) {
2214            return;
2215        }
2216
2217        int iFlags = PackageManager.INSTALL_EXTERNAL;
2218        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2219        // First install.
2220        installFromRawResource("install.apk", R.raw.install,
2221                iFlags,
2222                false,
2223                false, -1,
2224                -1);
2225        // Replace now
2226        installFromRawResource("install.apk", R.raw.install,
2227                rFlags,
2228                true,
2229                false, -1,
2230                -1);
2231    }
2232
2233    @LargeTest
2234    public void testFlagFExistingI() throws Exception {
2235        int iFlags = PackageManager.INSTALL_INTERNAL;
2236        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2237        // First install.
2238        installFromRawResource("install.apk", R.raw.install,
2239                iFlags,
2240                false,
2241                false, -1,
2242                -1);
2243        // Replace now
2244        installFromRawResource("install.apk", R.raw.install,
2245                rFlags,
2246                true,
2247                false, -1,
2248                -1);
2249    }
2250
2251    @LargeTest
2252    public void testFlagFExistingE() throws Exception {
2253        // Do not run on devices with emulated external storage.
2254        if (Environment.isExternalStorageEmulated()) {
2255            return;
2256        }
2257
2258        int iFlags = PackageManager.INSTALL_EXTERNAL;
2259        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2260        // First install.
2261        installFromRawResource("install.apk", R.raw.install,
2262                iFlags,
2263                false,
2264                false, -1,
2265                -1);
2266        // Replace now
2267        installFromRawResource("install.apk", R.raw.install,
2268                rFlags,
2269                true,
2270                false, -1,
2271                -1);
2272    }
2273
2274    /*
2275     * The following set of tests verify the installation of apps with
2276     * install location attribute set to internalOnly, preferExternal and auto.
2277     * The manifest option should dictate the install location.
2278     * public void testManifestI/E/A
2279     * TODO out of memory fall back behaviour.
2280     */
2281    @LargeTest
2282    public void testManifestI() throws Exception {
2283        installFromRawResource("install.apk", R.raw.install_loc_internal,
2284                0,
2285                true,
2286                false, -1,
2287                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2288    }
2289
2290    @LargeTest
2291    public void testManifestE() throws Exception {
2292        // Do not run on devices with emulated external storage.
2293        if (Environment.isExternalStorageEmulated()) {
2294            return;
2295        }
2296
2297        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2298                0,
2299                true,
2300                false, -1,
2301                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2302    }
2303
2304    @LargeTest
2305    public void testManifestA() throws Exception {
2306        installFromRawResource("install.apk", R.raw.install_loc_auto,
2307                0,
2308                true,
2309                false, -1,
2310                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2311    }
2312
2313    /*
2314     * The following set of tests verify the installation of apps
2315     * with install location attribute set to internalOnly, preferExternal and auto
2316     * for already existing apps. The manifest option should take precedence.
2317     * TODO add out of memory fall back behaviour.
2318     * testManifestI/E/AExistingI/E
2319     */
2320    @LargeTest
2321    public void testManifestIExistingI() throws Exception {
2322        int iFlags = PackageManager.INSTALL_INTERNAL;
2323        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2324        // First install.
2325        installFromRawResource("install.apk", R.raw.install,
2326                iFlags,
2327                false,
2328                false, -1,
2329                -1);
2330        // Replace now
2331        installFromRawResource("install.apk", R.raw.install_loc_internal,
2332                rFlags,
2333                true,
2334                false, -1,
2335                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2336    }
2337
2338    @LargeTest
2339    public void testManifestIExistingE() throws Exception {
2340        // Do not run on devices with emulated external storage.
2341        if (Environment.isExternalStorageEmulated()) {
2342            return;
2343        }
2344
2345        int iFlags = PackageManager.INSTALL_EXTERNAL;
2346        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2347        // First install.
2348        installFromRawResource("install.apk", R.raw.install,
2349                iFlags,
2350                false,
2351                false, -1,
2352                -1);
2353        // Replace now
2354        installFromRawResource("install.apk", R.raw.install_loc_internal,
2355                rFlags,
2356                true,
2357                false, -1,
2358                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2359    }
2360
2361    @LargeTest
2362    public void testManifestEExistingI() throws Exception {
2363        // Do not run on devices with emulated external storage.
2364        if (Environment.isExternalStorageEmulated()) {
2365            return;
2366        }
2367
2368        int iFlags = PackageManager.INSTALL_INTERNAL;
2369        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2370        // First install.
2371        installFromRawResource("install.apk", R.raw.install,
2372                iFlags,
2373                false,
2374                false, -1,
2375                -1);
2376        // Replace now
2377        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2378                rFlags,
2379                true,
2380                false, -1,
2381                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2382    }
2383
2384    @LargeTest
2385    public void testManifestEExistingE() throws Exception {
2386        // Do not run on devices with emulated external storage.
2387        if (Environment.isExternalStorageEmulated()) {
2388            return;
2389        }
2390
2391        int iFlags = PackageManager.INSTALL_EXTERNAL;
2392        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2393        // First install.
2394        installFromRawResource("install.apk", R.raw.install,
2395                iFlags,
2396                false,
2397                false, -1,
2398                -1);
2399        // Replace now
2400        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2401                rFlags,
2402                true,
2403                false, -1,
2404                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2405    }
2406
2407    @LargeTest
2408    public void testManifestAExistingI() throws Exception {
2409        int iFlags = PackageManager.INSTALL_INTERNAL;
2410        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2411        // First install.
2412        installFromRawResource("install.apk", R.raw.install,
2413                iFlags,
2414                false,
2415                false, -1,
2416                -1);
2417        // Replace now
2418        installFromRawResource("install.apk", R.raw.install_loc_auto,
2419                rFlags,
2420                true,
2421                false, -1,
2422                PackageInfo.INSTALL_LOCATION_AUTO);
2423    }
2424
2425    @LargeTest
2426    public void testManifestAExistingE() throws Exception {
2427        // Do not run on devices with emulated external storage.
2428        if (Environment.isExternalStorageEmulated()) {
2429            return;
2430        }
2431
2432        int iFlags = PackageManager.INSTALL_EXTERNAL;
2433        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2434        // First install.
2435        installFromRawResource("install.apk", R.raw.install,
2436                iFlags,
2437                false,
2438                false, -1,
2439                -1);
2440        // Replace now
2441        installFromRawResource("install.apk", R.raw.install_loc_auto,
2442                rFlags,
2443                true,
2444                false, -1,
2445                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2446    }
2447
2448    /*
2449     * The following set of tests check install location for existing
2450     * application based on user setting.
2451     */
2452    private int getExpectedInstallLocation(int userSetting) {
2453        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2454        boolean enable = getUserSettingSetInstallLocation();
2455        if (enable) {
2456            if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
2457                iloc = PackageInfo.INSTALL_LOCATION_AUTO;
2458            } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
2459                iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
2460            } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
2461                iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
2462            }
2463        }
2464        return iloc;
2465    }
2466
2467    private void setExistingXUserX(int userSetting, int iFlags, int iloc) throws Exception {
2468        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2469        // First install.
2470        installFromRawResource("install.apk", R.raw.install,
2471                iFlags,
2472                false,
2473                false, -1,
2474                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2475        int origSetting = getDefaultInstallLoc();
2476        try {
2477            // Set user setting
2478            setInstallLoc(userSetting);
2479            // Replace now
2480            installFromRawResource("install.apk", R.raw.install,
2481                    rFlags,
2482                    true,
2483                    false, -1,
2484                    iloc);
2485        } finally {
2486            setInstallLoc(origSetting);
2487        }
2488    }
2489    @LargeTest
2490    public void testExistingIUserI() throws Exception {
2491        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2492        int iFlags = PackageManager.INSTALL_INTERNAL;
2493        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2494    }
2495
2496    @LargeTest
2497    public void testExistingIUserE() throws Exception {
2498        // Do not run on devices with emulated external storage.
2499        if (Environment.isExternalStorageEmulated()) {
2500            return;
2501        }
2502
2503        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2504        int iFlags = PackageManager.INSTALL_INTERNAL;
2505        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2506    }
2507
2508    @LargeTest
2509    public void testExistingIUserA() throws Exception {
2510        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2511        int iFlags = PackageManager.INSTALL_INTERNAL;
2512        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2513    }
2514
2515    @LargeTest
2516    public void testExistingEUserI() throws Exception {
2517        // Do not run on devices with emulated external storage.
2518        if (Environment.isExternalStorageEmulated()) {
2519            return;
2520        }
2521
2522        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2523        int iFlags = PackageManager.INSTALL_EXTERNAL;
2524        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2525    }
2526
2527    @LargeTest
2528    public void testExistingEUserE() throws Exception {
2529        // Do not run on devices with emulated external storage.
2530        if (Environment.isExternalStorageEmulated()) {
2531            return;
2532        }
2533
2534        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2535        int iFlags = PackageManager.INSTALL_EXTERNAL;
2536        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2537    }
2538
2539    @LargeTest
2540    public void testExistingEUserA() throws Exception {
2541        // Do not run on devices with emulated external storage.
2542        if (Environment.isExternalStorageEmulated()) {
2543            return;
2544        }
2545
2546        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2547        int iFlags = PackageManager.INSTALL_EXTERNAL;
2548        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2549    }
2550
2551    /*
2552     * The following set of tests verify that the user setting defines
2553     * the install location.
2554     *
2555     */
2556    private boolean getUserSettingSetInstallLocation() {
2557        try {
2558            return Settings.Global.getInt(
2559                    mContext.getContentResolver(), Settings.Global.SET_INSTALL_LOCATION) != 0;
2560        } catch (SettingNotFoundException e1) {
2561        }
2562        return false;
2563    }
2564
2565    private void setUserSettingSetInstallLocation(boolean value) {
2566        Settings.Global.putInt(mContext.getContentResolver(),
2567                Settings.Global.SET_INSTALL_LOCATION, value ? 1 : 0);
2568    }
2569
2570    private void setUserX(boolean enable, int userSetting, int iloc) throws Exception {
2571        boolean origUserSetting = getUserSettingSetInstallLocation();
2572        int origSetting = getDefaultInstallLoc();
2573        try {
2574            setUserSettingSetInstallLocation(enable);
2575            // Set user setting
2576            setInstallLoc(userSetting);
2577            // Replace now
2578            installFromRawResource("install.apk", R.raw.install,
2579                    0,
2580                    true,
2581                    false, -1,
2582                    iloc);
2583        } finally {
2584            // Restore original setting
2585            setUserSettingSetInstallLocation(origUserSetting);
2586            setInstallLoc(origSetting);
2587        }
2588    }
2589    @LargeTest
2590    public void testUserI() throws Exception {
2591        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2592        int iloc = getExpectedInstallLocation(userSetting);
2593        setUserX(true, userSetting, iloc);
2594    }
2595
2596    @LargeTest
2597    public void testUserE() throws Exception {
2598        // Do not run on devices with emulated external storage.
2599        if (Environment.isExternalStorageEmulated()) {
2600            return;
2601        }
2602
2603        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2604        int iloc = getExpectedInstallLocation(userSetting);
2605        setUserX(true, userSetting, iloc);
2606    }
2607
2608    @LargeTest
2609    public void testUserA() throws Exception {
2610        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2611        int iloc = getExpectedInstallLocation(userSetting);
2612        setUserX(true, userSetting, iloc);
2613    }
2614
2615    /*
2616     * The following set of tests turn on/off the basic
2617     * user setting for turning on install location.
2618     */
2619    @LargeTest
2620    public void testUserPrefOffUserI() throws Exception {
2621        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2622        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2623        setUserX(false, userSetting, iloc);
2624    }
2625
2626    @LargeTest
2627    public void testUserPrefOffUserE() throws Exception {
2628        // Do not run on devices with emulated external storage.
2629        if (Environment.isExternalStorageEmulated()) {
2630            return;
2631        }
2632
2633        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2634        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2635        setUserX(false, userSetting, iloc);
2636    }
2637
2638    @LargeTest
2639    public void testUserPrefOffA() throws Exception {
2640        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2641        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2642        setUserX(false, userSetting, iloc);
2643    }
2644
2645    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
2646        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
2647        PERM_DEFINED,
2648        "com.android.frameworks.coretests.NORMAL",
2649        "com.android.frameworks.coretests.DANGEROUS",
2650        "com.android.frameworks.coretests.SIGNATURE",
2651    };
2652
2653    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
2654        PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
2655        PERM_UNDEFINED,
2656        "com.android.frameworks.coretests.NORMAL",
2657        "com.android.frameworks.coretests.DANGEROUS",
2658        "com.android.frameworks.coretests.SIGNATURE",
2659    };
2660
2661    static final String BASE_PERMISSIONS_USED[] = new String[] {
2662        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2663        PERM_USED,
2664        "com.android.frameworks.coretests.NORMAL",
2665        "com.android.frameworks.coretests.DANGEROUS",
2666        "com.android.frameworks.coretests.SIGNATURE",
2667    };
2668
2669    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
2670        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2671        PERM_NOTUSED,
2672        "com.android.frameworks.coretests.NORMAL",
2673        "com.android.frameworks.coretests.DANGEROUS",
2674        "com.android.frameworks.coretests.SIGNATURE",
2675    };
2676
2677    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
2678        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2679        PERM_USED,
2680        "com.android.frameworks.coretests.SIGNATURE",
2681        PERM_NOTUSED,
2682        "com.android.frameworks.coretests.NORMAL",
2683        "com.android.frameworks.coretests.DANGEROUS",
2684    };
2685
2686    /*
2687     * Ensure that permissions are properly declared.
2688     */
2689    @LargeTest
2690    public void testInstallDeclaresPermissions() throws Exception {
2691        InstallParams ip = null;
2692        InstallParams ip2 = null;
2693        try {
2694            // **: Upon installing a package, are its declared permissions published?
2695
2696            int iFlags = PackageManager.INSTALL_INTERNAL;
2697            int iApk = R.raw.install_decl_perm;
2698            ip = installFromRawResource("install.apk", iApk,
2699                    iFlags, false,
2700                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2701            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2702            assertPermissions(BASE_PERMISSIONS_DEFINED);
2703
2704            // **: Upon installing package, are its permissions granted?
2705
2706            int i2Flags = PackageManager.INSTALL_INTERNAL;
2707            int i2Apk = R.raw.install_use_perm_good;
2708            ip2 = installFromRawResource("install2.apk", i2Apk,
2709                    i2Flags, false,
2710                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2711            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2712            assertPermissions(BASE_PERMISSIONS_USED);
2713
2714            // **: Upon removing but not deleting, are permissions retained?
2715
2716            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2717
2718            try {
2719                invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
2720            } catch (Exception e) {
2721                failStr(e);
2722            }
2723            assertPermissions(BASE_PERMISSIONS_DEFINED);
2724            assertPermissions(BASE_PERMISSIONS_USED);
2725
2726            // **: Upon re-installing, are permissions retained?
2727
2728            ip = installFromRawResource("install.apk", iApk,
2729                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2730                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2731            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2732            assertPermissions(BASE_PERMISSIONS_DEFINED);
2733            assertPermissions(BASE_PERMISSIONS_USED);
2734
2735            // **: Upon deleting package, are all permissions removed?
2736
2737            try {
2738                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2739                ip = null;
2740            } catch (Exception e) {
2741                failStr(e);
2742            }
2743            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2744            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2745
2746            // **: Delete package using permissions; nothing to check here.
2747
2748            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2749            try {
2750                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2751                ip2 = null;
2752            } catch (Exception e) {
2753                failStr(e);
2754            }
2755
2756            // **: Re-install package using permissions; no permissions can be granted.
2757
2758            ip2 = installFromRawResource("install2.apk", i2Apk,
2759                    i2Flags, false,
2760                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2761            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2762            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2763
2764            // **: Upon installing declaring package, are sig permissions granted
2765            // to other apps (but not other perms)?
2766
2767            ip = installFromRawResource("install.apk", iApk,
2768                    iFlags, false,
2769                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2770            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2771            assertPermissions(BASE_PERMISSIONS_DEFINED);
2772            assertPermissions(BASE_PERMISSIONS_SIGUSED);
2773
2774            // **: Re-install package using permissions; are all permissions granted?
2775
2776            ip2 = installFromRawResource("install2.apk", i2Apk,
2777                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2778                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2779            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2780            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2781
2782            // **: Upon deleting package, are all permissions removed?
2783
2784            try {
2785                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2786                ip = null;
2787            } catch (Exception e) {
2788                failStr(e);
2789            }
2790            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2791            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2792
2793            // **: Delete package using permissions; nothing to check here.
2794
2795            try {
2796                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2797                ip2 = null;
2798            } catch (Exception e) {
2799                failStr(e);
2800            }
2801
2802        } finally {
2803            if (ip2 != null) {
2804                cleanUpInstall(ip2);
2805            }
2806            if (ip != null) {
2807                cleanUpInstall(ip);
2808            }
2809        }
2810    }
2811
2812    /*
2813     * Ensure that permissions are properly declared.
2814     */
2815    @LargeTest
2816    public void testInstallOnSdPermissionsUnmount() throws Exception {
2817        InstallParams ip = null;
2818        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2819        try {
2820            // **: Upon installing a package, are its declared permissions published?
2821            int iFlags = PackageManager.INSTALL_INTERNAL;
2822            int iApk = R.raw.install_decl_perm;
2823            ip = installFromRawResource("install.apk", iApk,
2824                    iFlags, false,
2825                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2826            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2827            assertPermissions(BASE_PERMISSIONS_DEFINED);
2828            // Unmount media here
2829            assertTrue(unmountMedia());
2830            // Mount media again
2831            mountMedia();
2832            //Check permissions now
2833            assertPermissions(BASE_PERMISSIONS_DEFINED);
2834        } finally {
2835            if (ip != null) {
2836                cleanUpInstall(ip);
2837            }
2838        }
2839    }
2840
2841    /* This test creates a stale container via MountService and then installs
2842     * a package and verifies that the stale container is cleaned up and install
2843     * is successful.
2844     * Please note that this test is very closely tied to the framework's
2845     * naming convention for secure containers.
2846     */
2847    @LargeTest
2848    public void testInstallSdcardStaleContainer() throws Exception {
2849        // Do not run on devices with emulated external storage.
2850        if (Environment.isExternalStorageEmulated()) {
2851            return;
2852        }
2853
2854        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2855        try {
2856            // Mount media first
2857            mountMedia();
2858            String outFileName = "install.apk";
2859            int rawResId = R.raw.install;
2860            PackageManager pm = mContext.getPackageManager();
2861            File filesDir = mContext.getFilesDir();
2862            File outFile = new File(filesDir, outFileName);
2863            Uri packageURI = getInstallablePackage(rawResId, outFile);
2864            PackageParser.Package pkg = parsePackage(packageURI);
2865            assertNotNull(pkg);
2866            // Install an app on sdcard.
2867            installFromRawResource(outFileName, rawResId,
2868                    PackageManager.INSTALL_EXTERNAL, false,
2869                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2870            // Unmount sdcard
2871            unmountMedia();
2872            // Delete the app on sdcard to leave a stale container on sdcard.
2873            GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2874            assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver));
2875            mountMedia();
2876            // Reinstall the app and make sure it gets installed.
2877            installFromRawResource(outFileName, rawResId,
2878                    PackageManager.INSTALL_EXTERNAL, true,
2879                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2880        } catch (Exception e) {
2881            failStr(e.getMessage());
2882        } finally {
2883            if (origMediaState) {
2884                mountMedia();
2885            } else {
2886                unmountMedia();
2887            }
2888
2889        }
2890    }
2891
2892    /* This test installs an application on sdcard and unmounts media.
2893     * The app is then re-installed on internal storage. The sdcard is mounted
2894     * and verified that the re-installation on internal storage takes precedence.
2895     */
2896    @LargeTest
2897    public void testInstallSdcardStaleContainerReinstall() throws Exception {
2898        // Do not run on devices with emulated external storage.
2899        if (Environment.isExternalStorageEmulated()) {
2900            return;
2901        }
2902
2903        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2904        try {
2905            // Mount media first
2906            mountMedia();
2907            String outFileName = "install.apk";
2908            int rawResId = R.raw.install;
2909            PackageManager pm = mContext.getPackageManager();
2910            File filesDir = mContext.getFilesDir();
2911            File outFile = new File(filesDir, outFileName);
2912            Uri packageURI = getInstallablePackage(rawResId, outFile);
2913            PackageParser.Package pkg = parsePackage(packageURI);
2914            assertNotNull(pkg);
2915            // Install an app on sdcard.
2916            installFromRawResource(outFileName, rawResId,
2917                    PackageManager.INSTALL_EXTERNAL, false,
2918                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2919            // Unmount sdcard
2920            unmountMedia();
2921            // Reinstall the app and make sure it gets installed on internal storage.
2922            installFromRawResource(outFileName, rawResId,
2923                    PackageManager.INSTALL_REPLACE_EXISTING, false,
2924                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2925            mountMedia();
2926            // Verify that the app installed is on internal storage.
2927            assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2928        } catch (Exception e) {
2929            failStr(e.getMessage());
2930        } finally {
2931            if (origMediaState) {
2932                mountMedia();
2933            } else {
2934                unmountMedia();
2935            }
2936        }
2937    }
2938
2939    /*
2940     * The following series of tests are related to upgrading apps with
2941     * different certificates.
2942     */
2943    private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
2944
2945    private int APP1_CERT1 = R.raw.install_app1_cert1;
2946
2947    private int APP1_CERT2 = R.raw.install_app1_cert2;
2948
2949    private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
2950
2951    private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
2952
2953    private int APP1_CERT3 = R.raw.install_app1_cert3;
2954
2955    private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
2956
2957    private int APP2_CERT1 = R.raw.install_app2_cert1;
2958
2959    private int APP2_CERT2 = R.raw.install_app2_cert2;
2960
2961    private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
2962
2963    private int APP2_CERT3 = R.raw.install_app2_cert3;
2964
2965    private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail,
2966            int retCode) throws Exception {
2967        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2968        String apk1Name = "install1.apk";
2969        String apk2Name = "install2.apk";
2970        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2971        try {
2972            InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2973                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2974            installFromRawResource(apk2Name, apk2, rFlags, false,
2975                    fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2976            return ip;
2977        } catch (Exception e) {
2978            failStr(e.getMessage());
2979        } finally {
2980            if (cleanUp) {
2981                cleanUpInstall(pkg1.packageName);
2982            }
2983        }
2984        return null;
2985    }
2986
2987    /*
2988     * Test that an app signed with two certificates can be upgraded by the
2989     * same app signed with two certificates.
2990     */
2991    @LargeTest
2992    public void testReplaceMatchAllCerts() throws Exception {
2993        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
2994    }
2995
2996    /*
2997     * Test that an app signed with two certificates cannot be upgraded
2998     * by an app signed with a different certificate.
2999     */
3000    @LargeTest
3001    public void testReplaceMatchNoCerts1() throws Exception {
3002        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
3003                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3004    }
3005
3006    /*
3007     * Test that an app signed with two certificates cannot be upgraded
3008     * by an app signed with a different certificate.
3009     */
3010    @LargeTest
3011    public void testReplaceMatchNoCerts2() throws Exception {
3012        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
3013                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3014    }
3015
3016    /*
3017     * Test that an app signed with two certificates cannot be upgraded by
3018     * an app signed with a subset of initial certificates.
3019     */
3020    @LargeTest
3021    public void testReplaceMatchSomeCerts1() throws Exception {
3022        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
3023                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3024    }
3025
3026    /*
3027     * Test that an app signed with two certificates cannot be upgraded by
3028     * an app signed with the last certificate.
3029     */
3030    @LargeTest
3031    public void testReplaceMatchSomeCerts2() throws Exception {
3032        replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
3033                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3034    }
3035
3036    /*
3037     * Test that an app signed with a certificate can be upgraded by app
3038     * signed with a superset of certificates.
3039     */
3040    @LargeTest
3041    public void testReplaceMatchMoreCerts() throws Exception {
3042        replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
3043                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3044    }
3045
3046    /*
3047     * Test that an app signed with a certificate can be upgraded by app
3048     * signed with a superset of certificates. Then verify that the an app
3049     * signed with the original set of certs cannot upgrade the new one.
3050     */
3051    @LargeTest
3052    public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception {
3053        InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
3054                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
3055        try {
3056            int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
3057            installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
3058                    false, -1,
3059                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3060        } catch (Exception e) {
3061            failStr(e.getMessage());
3062        } finally {
3063            if (ip != null) {
3064                cleanUpInstall(ip);
3065            }
3066        }
3067    }
3068
3069    /**
3070     * The following tests are related to testing the checkSignatures api.
3071     */
3072    private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {
3073        checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
3074    }
3075
3076    @LargeTest
3077    public void testCheckSignaturesAllMatch() throws Exception {
3078        int apk1 = APP1_CERT1_CERT2;
3079        int apk2 = APP2_CERT1_CERT2;
3080        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3081    }
3082
3083    @LargeTest
3084    public void testCheckSignaturesNoMatch() throws Exception {
3085        int apk1 = APP1_CERT1;
3086        int apk2 = APP2_CERT2;
3087        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3088    }
3089
3090    @LargeTest
3091    public void testCheckSignaturesSomeMatch1() throws Exception {
3092        int apk1 = APP1_CERT1_CERT2;
3093        int apk2 = APP2_CERT1;
3094        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3095    }
3096
3097    @LargeTest
3098    public void testCheckSignaturesSomeMatch2() throws Exception {
3099        int apk1 = APP1_CERT1_CERT2;
3100        int apk2 = APP2_CERT2;
3101        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3102    }
3103
3104    @LargeTest
3105    public void testCheckSignaturesMoreMatch() throws Exception {
3106        int apk1 = APP1_CERT1;
3107        int apk2 = APP2_CERT1_CERT2;
3108        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3109    }
3110
3111    @LargeTest
3112    public void testCheckSignaturesUnknown() throws Exception {
3113        int apk1 = APP1_CERT1_CERT2;
3114        int apk2 = APP2_CERT1_CERT2;
3115        String apk1Name = "install1.apk";
3116        String apk2Name = "install2.apk";
3117        InstallParams ip1 = null;
3118
3119        try {
3120            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
3121                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3122            PackageManager pm = mContext.getPackageManager();
3123            // Delete app2
3124            File filesDir = mContext.getFilesDir();
3125            File outFile = new File(filesDir, apk2Name);
3126            int rawResId = apk2;
3127            Uri packageURI = getInstallablePackage(rawResId, outFile);
3128            PackageParser.Package pkg = parsePackage(packageURI);
3129            getPm().deletePackage(pkg.packageName, null, 0);
3130            // Check signatures now
3131            int match = mContext.getPackageManager().checkSignatures(
3132                    ip1.pkg.packageName, pkg.packageName);
3133            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3134        } finally {
3135            if (ip1 != null) {
3136                cleanUpInstall(ip1);
3137            }
3138        }
3139    }
3140
3141    @LargeTest
3142    public void testInstallNoCertificates() throws Exception {
3143        int apk1 = APP1_UNSIGNED;
3144        String apk1Name = "install1.apk";
3145        InstallParams ip1 = null;
3146
3147        try {
3148            installFromRawResource(apk1Name, apk1, 0, false,
3149                    true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
3150                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3151        } finally {
3152        }
3153    }
3154
3155    /*
3156     * The following tests are related to apps using shared uids signed with
3157     * different certs.
3158     */
3159    private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
3160
3161    private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
3162
3163    private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
3164
3165    private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
3166
3167    private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
3168
3169    private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
3170
3171    private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
3172
3173    private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
3174
3175    private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail,
3176            int retCode, int expMatchResult) throws Exception {
3177        String apk1Name = "install1.apk";
3178        String apk2Name = "install2.apk";
3179        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
3180        PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
3181
3182        try {
3183            // Clean up before testing first.
3184            cleanUpInstall(pkg1.packageName);
3185            cleanUpInstall(pkg2.packageName);
3186            installFromRawResource(apk1Name, apk1, 0, false, false, -1,
3187                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3188            if (fail) {
3189                installFromRawResource(apk2Name, apk2, 0, false, true, retCode,
3190                        PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3191            } else {
3192                installFromRawResource(apk2Name, apk2, 0, false, false, -1,
3193                        PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3194                int match = mContext.getPackageManager().checkSignatures(pkg1.packageName,
3195                        pkg2.packageName);
3196                assertEquals(expMatchResult, match);
3197            }
3198        } finally {
3199            if (cleanUp) {
3200                cleanUpInstall(pkg1.packageName);
3201                cleanUpInstall(pkg2.packageName);
3202            }
3203        }
3204    }
3205
3206    @LargeTest
3207    public void testCheckSignaturesSharedAllMatch() throws Exception {
3208        int apk1 = SHARED1_CERT1_CERT2;
3209        int apk2 = SHARED2_CERT1_CERT2;
3210        boolean fail = false;
3211        int retCode = -1;
3212        int expMatchResult = PackageManager.SIGNATURE_MATCH;
3213        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3214    }
3215
3216    @LargeTest
3217    public void testCheckSignaturesSharedNoMatch() throws Exception {
3218        int apk1 = SHARED1_CERT1;
3219        int apk2 = SHARED2_CERT2;
3220        boolean fail = true;
3221        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3222        int expMatchResult = -1;
3223        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3224    }
3225
3226    /*
3227     * Test that an app signed with cert1 and cert2 cannot be replaced when
3228     * signed with cert1 alone.
3229     */
3230    @LargeTest
3231    public void testCheckSignaturesSharedSomeMatch1() throws Exception {
3232        int apk1 = SHARED1_CERT1_CERT2;
3233        int apk2 = SHARED2_CERT1;
3234        boolean fail = true;
3235        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3236        int expMatchResult = -1;
3237        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3238    }
3239
3240    /*
3241     * Test that an app signed with cert1 and cert2 cannot be replaced when
3242     * signed with cert2 alone.
3243     */
3244    @LargeTest
3245    public void testCheckSignaturesSharedSomeMatch2() throws Exception {
3246        int apk1 = SHARED1_CERT1_CERT2;
3247        int apk2 = SHARED2_CERT2;
3248        boolean fail = true;
3249        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3250        int expMatchResult = -1;
3251        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3252    }
3253
3254    @LargeTest
3255    public void testCheckSignaturesSharedUnknown() throws Exception {
3256        int apk1 = SHARED1_CERT1_CERT2;
3257        int apk2 = SHARED2_CERT1_CERT2;
3258        String apk1Name = "install1.apk";
3259        String apk2Name = "install2.apk";
3260        InstallParams ip1 = null;
3261
3262        try {
3263            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
3264                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3265            PackageManager pm = mContext.getPackageManager();
3266            // Delete app2
3267            PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
3268            getPm().deletePackage(pkg.packageName, null, 0);
3269            // Check signatures now
3270            int match = mContext.getPackageManager().checkSignatures(
3271                    ip1.pkg.packageName, pkg.packageName);
3272            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3273        } finally {
3274            if (ip1 != null) {
3275                cleanUpInstall(ip1);
3276            }
3277        }
3278    }
3279
3280    @LargeTest
3281    public void testReplaceFirstSharedMatchAllCerts() throws Exception {
3282        int apk1 = SHARED1_CERT1;
3283        int apk2 = SHARED2_CERT1;
3284        int rapk1 = SHARED1_CERT1;
3285        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3286        replaceCerts(apk1, rapk1, true, false, -1);
3287    }
3288
3289    @LargeTest
3290    public void testReplaceSecondSharedMatchAllCerts() throws Exception {
3291        int apk1 = SHARED1_CERT1;
3292        int apk2 = SHARED2_CERT1;
3293        int rapk2 = SHARED2_CERT1;
3294        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3295        replaceCerts(apk2, rapk2, true, false, -1);
3296    }
3297
3298    @LargeTest
3299    public void testReplaceFirstSharedMatchSomeCerts() throws Exception {
3300        int apk1 = SHARED1_CERT1_CERT2;
3301        int apk2 = SHARED2_CERT1_CERT2;
3302        int rapk1 = SHARED1_CERT1;
3303        boolean fail = true;
3304        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3305        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3306        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3307                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3308    }
3309
3310    @LargeTest
3311    public void testReplaceSecondSharedMatchSomeCerts() throws Exception {
3312        int apk1 = SHARED1_CERT1_CERT2;
3313        int apk2 = SHARED2_CERT1_CERT2;
3314        int rapk2 = SHARED2_CERT1;
3315        boolean fail = true;
3316        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3317        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3318        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3319                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3320    }
3321
3322    @LargeTest
3323    public void testReplaceFirstSharedMatchNoCerts() throws Exception {
3324        int apk1 = SHARED1_CERT1;
3325        int apk2 = SHARED2_CERT1;
3326        int rapk1 = SHARED1_CERT2;
3327        boolean fail = true;
3328        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3329        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3330        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3331                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3332    }
3333
3334    @LargeTest
3335    public void testReplaceSecondSharedMatchNoCerts() throws Exception {
3336        int apk1 = SHARED1_CERT1;
3337        int apk2 = SHARED2_CERT1;
3338        int rapk2 = SHARED2_CERT2;
3339        boolean fail = true;
3340        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3341        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3342        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3343                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3344    }
3345
3346    @LargeTest
3347    public void testReplaceFirstSharedMatchMoreCerts() throws Exception {
3348        int apk1 = SHARED1_CERT1;
3349        int apk2 = SHARED2_CERT1;
3350        int rapk1 = SHARED1_CERT1_CERT2;
3351        boolean fail = true;
3352        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3353        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3354        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3355                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3356    }
3357
3358    @LargeTest
3359    public void testReplaceSecondSharedMatchMoreCerts() throws Exception {
3360        int apk1 = SHARED1_CERT1;
3361        int apk2 = SHARED2_CERT1;
3362        int rapk2 = SHARED2_CERT1_CERT2;
3363        boolean fail = true;
3364        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3365        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3366        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3367                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3368    }
3369
3370    /**
3371     * Unknown features should be allowed to install. This prevents older phones
3372     * from rejecting new packages that specify features that didn't exist when
3373     * an older phone existed. All older phones are assumed to have those
3374     * features.
3375     * <p>
3376     * Right now we allow all packages to be installed regardless of their
3377     * features.
3378     */
3379    @LargeTest
3380    public void testUsesFeatureUnknownFeature() throws Exception {
3381        int retCode = PackageManager.INSTALL_SUCCEEDED;
3382        installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode,
3383                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3384    }
3385
3386    @LargeTest
3387    public void testInstallNonexistentFile() throws Exception {
3388        int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
3389        File invalidFile = new File("/nonexistent-file.apk");
3390        invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
3391    }
3392
3393    @SmallTest
3394    public void testGetVerifierDeviceIdentity() throws Exception {
3395        PackageManager pm = getPm();
3396        VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity();
3397
3398        assertNotNull("Verifier device identity should not be null", id);
3399    }
3400
3401    public void testGetInstalledPackages() throws Exception {
3402        List<PackageInfo> packages = getPm().getInstalledPackages(0);
3403        assertNotNull("installed packages cannot be null", packages);
3404        assertTrue("installed packages cannot be empty", packages.size() > 0);
3405    }
3406
3407    public void testGetUnInstalledPackages() throws Exception {
3408        List<PackageInfo> packages = getPm().getInstalledPackages(
3409                PackageManager.GET_UNINSTALLED_PACKAGES);
3410        assertNotNull("installed packages cannot be null", packages);
3411        assertTrue("installed packages cannot be empty", packages.size() > 0);
3412    }
3413
3414    /**
3415     * Test that getInstalledPackages returns all the data specified in flags.
3416     */
3417    public void testGetInstalledPackagesAll() throws Exception {
3418        int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3419                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3420                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3421                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3422                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
3423
3424        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3425        assertNotNull("installed packages cannot be null", packages);
3426        assertTrue("installed packages cannot be empty", packages.size() > 0);
3427
3428        PackageInfo packageInfo = null;
3429
3430        // Find the package with all components specified in the AndroidManifest
3431        // to ensure no null values
3432        for (PackageInfo pi : packages) {
3433            if ("com.android.frameworks.coretests.install_complete_package_info"
3434                    .equals(pi.packageName)) {
3435                packageInfo = pi;
3436                break;
3437            }
3438        }
3439        assertNotNull("activities should not be null", packageInfo.activities);
3440        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3441        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3442        assertNotNull("permissions should not be null", packageInfo.permissions);
3443        assertNotNull("providers should not be null", packageInfo.providers);
3444        assertNotNull("receivers should not be null", packageInfo.receivers);
3445        assertNotNull("services should not be null", packageInfo.services);
3446        assertNotNull("signatures should not be null", packageInfo.signatures);
3447    }
3448
3449    /**
3450     * Test that getInstalledPackages returns all the data specified in
3451     * flags when the GET_UNINSTALLED_PACKAGES flag is set.
3452     */
3453    public void testGetUnInstalledPackagesAll() throws Exception {
3454        int flags = PackageManager.GET_UNINSTALLED_PACKAGES
3455                | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3456                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3457                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3458                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3459                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
3460
3461        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3462        assertNotNull("installed packages cannot be null", packages);
3463        assertTrue("installed packages cannot be empty", packages.size() > 0);
3464
3465        PackageInfo packageInfo = null;
3466
3467        // Find the package with all components specified in the AndroidManifest
3468        // to ensure no null values
3469        for (PackageInfo pi : packages) {
3470            if ("com.android.frameworks.coretests.install_complete_package_info"
3471                    .equals(pi.packageName)) {
3472                packageInfo = pi;
3473                break;
3474            }
3475        }
3476        assertNotNull("activities should not be null", packageInfo.activities);
3477        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3478        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3479        assertNotNull("permissions should not be null", packageInfo.permissions);
3480        assertNotNull("providers should not be null", packageInfo.providers);
3481        assertNotNull("receivers should not be null", packageInfo.receivers);
3482        assertNotNull("services should not be null", packageInfo.services);
3483        assertNotNull("signatures should not be null", packageInfo.signatures);
3484    }
3485
3486    public void testInstall_BadDex_CleanUp() throws Exception {
3487        int retCode = PackageManager.INSTALL_FAILED_DEXOPT;
3488        installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
3489                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3490    }
3491
3492    /*---------- Recommended install location tests ----*/
3493    /*
3494     * TODO's
3495     * check version numbers for upgrades
3496     * check permissions of installed packages
3497     * how to do tests on updated system apps?
3498     * verify updates to system apps cannot be installed on the sdcard.
3499     */
3500}
3501