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