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