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