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