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