PackageManagerTests.java revision 6dceb88f1c7c42c6ab43834af2c993d599895d82
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, true,
1233                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1234                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1235    }
1236
1237    @LargeTest
1238    public void testManifestInstallLocationFwdLockedSdcard() {
1239        // Do not run on devices with emulated external storage.
1240        if (Environment.isExternalStorageEmulated()) {
1241            return;
1242        }
1243
1244        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1245                PackageManager.INSTALL_FORWARD_LOCK, true, false,
1246                -1,
1247                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1248    }
1249
1250    /*
1251     * Install a package on internal flash via PackageManager install flag. Replace
1252     * the package via flag to install on sdcard. Make sure the new flag overrides
1253     * the old install location.
1254     */
1255    @LargeTest
1256    public void testReplaceFlagInternalSdcard() {
1257        // Do not run on devices with emulated external storage.
1258        if (Environment.isExternalStorageEmulated()) {
1259            return;
1260        }
1261
1262        int iFlags = 0;
1263        int rFlags = PackageManager.INSTALL_EXTERNAL;
1264        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1265        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1266        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1267        try {
1268            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1269            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
1270        } catch (Exception e) {
1271            failStr("Failed with exception : " + e);
1272        } finally {
1273            cleanUpInstall(ip);
1274        }
1275    }
1276
1277    /*
1278     * Install a package on sdcard via PackageManager install flag. Replace
1279     * the package with no flags or manifest option and make sure the old
1280     * install location is retained.
1281     */
1282    @LargeTest
1283    public void testReplaceFlagSdcardInternal() {
1284        // Do not run on devices with emulated external storage.
1285        if (Environment.isExternalStorageEmulated()) {
1286            return;
1287        }
1288
1289        int iFlags = PackageManager.INSTALL_EXTERNAL;
1290        int rFlags = 0;
1291        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1292        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1293        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1294        try {
1295            invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1296            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1297        } catch (Exception e) {
1298            failStr("Failed with exception : " + e);
1299        } finally {
1300            cleanUpInstall(ip);
1301        }
1302    }
1303
1304    @LargeTest
1305    public void testManifestInstallLocationReplaceInternalSdcard() {
1306        // Do not run on devices with emulated external storage.
1307        if (Environment.isExternalStorageEmulated()) {
1308            return;
1309        }
1310
1311        int iFlags = 0;
1312        int iApk = R.raw.install_loc_internal;
1313        int rFlags = 0;
1314        int rApk = R.raw.install_loc_sdcard;
1315        InstallParams ip = installFromRawResource("install.apk", iApk,
1316                iFlags, false,
1317                false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1318        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1319        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1320        try {
1321            InstallParams rp = installFromRawResource("install.apk", rApk,
1322                    replaceFlags, false,
1323                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1324            assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1325        } catch (Exception e) {
1326            failStr("Failed with exception : " + e);
1327        } finally {
1328            cleanUpInstall(ip);
1329        }
1330    }
1331
1332    @LargeTest
1333    public void testManifestInstallLocationReplaceSdcardInternal() {
1334        // Do not run on devices with emulated external storage.
1335        if (Environment.isExternalStorageEmulated()) {
1336            return;
1337        }
1338
1339        int iFlags = 0;
1340        int iApk = R.raw.install_loc_sdcard;
1341        int rFlags = 0;
1342        int rApk = R.raw.install_loc_unspecified;
1343        InstallParams ip = installFromRawResource("install.apk", iApk,
1344                iFlags, false,
1345                false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1346        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1347        try {
1348            InstallParams rp = installFromRawResource("install.apk", rApk,
1349                    replaceFlags, false,
1350                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1351            assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1352        } catch (Exception e) {
1353            failStr("Failed with exception : " + e);
1354        } finally {
1355            cleanUpInstall(ip);
1356        }
1357    }
1358
1359    class MoveReceiver extends GenericReceiver {
1360        String pkgName;
1361        final static int INVALID = -1;
1362        final static int REMOVED = 1;
1363        final static int ADDED = 2;
1364        int removed = INVALID;
1365
1366        MoveReceiver(String pkgName) {
1367            this.pkgName = pkgName;
1368            filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1369            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1370            super.setFilter(filter);
1371        }
1372
1373        public boolean notifyNow(Intent intent) {
1374            String action = intent.getAction();
1375            Log.i(TAG, "MoveReceiver::" + action);
1376            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1377                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1378                if (list != null) {
1379                    for (String pkg : list) {
1380                        if (pkg.equals(pkgName)) {
1381                            removed = REMOVED;
1382                            break;
1383                        }
1384                    }
1385                }
1386                removed = REMOVED;
1387            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1388                if (removed != REMOVED) {
1389                    return false;
1390                }
1391                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1392                if (list != null) {
1393                    for (String pkg : list) {
1394                        if (pkg.equals(pkgName)) {
1395                            removed = ADDED;
1396                            return true;
1397                        }
1398                    }
1399                }
1400            }
1401            return false;
1402        }
1403    }
1404
1405    private class PackageMoveObserver extends IPackageMoveObserver.Stub {
1406        public int returnCode;
1407        private boolean doneFlag = false;
1408        public String packageName;
1409        public PackageMoveObserver(String pkgName) {
1410            packageName = pkgName;
1411        }
1412        public void packageMoved(String packageName, int returnCode) {
1413            Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode);
1414            if (!packageName.equals(this.packageName)) {
1415                return;
1416            }
1417            synchronized(this) {
1418                this.returnCode = returnCode;
1419                doneFlag = true;
1420                notifyAll();
1421            }
1422        }
1423
1424        public boolean isDone() {
1425            return doneFlag;
1426        }
1427    }
1428
1429    public boolean invokeMovePackage(String pkgName, int flags,
1430            GenericReceiver receiver) throws Exception {
1431        PackageMoveObserver observer = new PackageMoveObserver(pkgName);
1432        final boolean received = false;
1433        mContext.registerReceiver(receiver, receiver.filter);
1434        try {
1435            // Wait on observer
1436            synchronized(observer) {
1437                synchronized (receiver) {
1438                    getPm().movePackage(pkgName, observer, flags);
1439                    long waitTime = 0;
1440                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
1441                        observer.wait(WAIT_TIME_INCR);
1442                        waitTime += WAIT_TIME_INCR;
1443                    }
1444                    if(!observer.isDone()) {
1445                        throw new Exception("Timed out waiting for pkgmove callback");
1446                    }
1447                    if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) {
1448                        return false;
1449                    }
1450                    // Verify we received the broadcast
1451                    waitTime = 0;
1452                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
1453                        receiver.wait(WAIT_TIME_INCR);
1454                        waitTime += WAIT_TIME_INCR;
1455                    }
1456                    if(!receiver.isDone()) {
1457                        throw new Exception("Timed out waiting for MOVE notifications");
1458                    }
1459                    return receiver.received;
1460                }
1461            }
1462        } finally {
1463            mContext.unregisterReceiver(receiver);
1464        }
1465    }
1466    private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
1467        PackageMoveObserver observer = new PackageMoveObserver(pkgName);
1468        try {
1469            // Wait on observer
1470            synchronized(observer) {
1471                getPm().movePackage(pkgName, observer, flags);
1472                long waitTime = 0;
1473                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
1474                    observer.wait(WAIT_TIME_INCR);
1475                    waitTime += WAIT_TIME_INCR;
1476                }
1477                if(!observer.isDone()) {
1478                    throw new Exception("Timed out waiting for pkgmove callback");
1479                }
1480                assertEquals(errCode, observer.returnCode);
1481            }
1482        } finally {
1483        }
1484        return true;
1485    }
1486
1487    private int getDefaultInstallLoc() {
1488        int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1489        try {
1490            origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.DEFAULT_INSTALL_LOCATION);
1491        } catch (SettingNotFoundException e1) {
1492        }
1493        return origDefaultLoc;
1494    }
1495
1496    private void setInstallLoc(int loc) {
1497        Settings.System.putInt(mContext.getContentResolver(),
1498                Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
1499    }
1500    /*
1501     * Tests for moving apps between internal and external storage
1502     */
1503    /*
1504     * Utility function that reads a apk bundled as a raw resource
1505     * copies it into own data directory and invokes
1506     * PackageManager api to install first and then replace it
1507     * again.
1508     */
1509
1510    private void moveFromRawResource(String outFileName,
1511            int rawResId, int installFlags, int moveFlags, boolean cleanUp,
1512            boolean fail, int result) {
1513        int origDefaultLoc = getDefaultInstallLoc();
1514        InstallParams ip = null;
1515        try {
1516            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1517            // Install first
1518            ip = installFromRawResource("install.apk", rawResId, installFlags, false,
1519                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1520            ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1521            if (fail) {
1522                assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1523                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1524                assertNotNull(info);
1525                assertEquals(oldAppInfo.flags, info.flags);
1526            } else {
1527                // Create receiver based on expRetCode
1528                MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1529                boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
1530                        receiver);
1531                assertTrue(retCode);
1532                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1533                assertNotNull("ApplicationInfo for recently installed application should exist",
1534                        info);
1535                if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1536                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set",
1537                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1538                    assertTrue("ApplicationInfo.nativeLibraryDir should start with " + info.dataDir,
1539                            info.nativeLibraryDir.startsWith(info.dataDir));
1540                } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
1541                    assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set",
1542                            (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1543                    assertTrue("ApplicationInfo.nativeLibraryDir should start with " + SECURE_CONTAINERS_PREFIX,
1544                            info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX));
1545                    final File nativeLibSymLink = new File(info.dataDir, "lib");
1546                    assertTrue("The data directory should have a 'lib' symlink that points to the ASEC container",
1547                            nativeLibSymLink.getCanonicalPath().startsWith(SECURE_CONTAINERS_PREFIX));
1548                }
1549            }
1550        } catch (NameNotFoundException e) {
1551            failStr("Pkg hasnt been installed correctly");
1552        } catch (Exception e) {
1553            failStr("Failed with exception : " + e);
1554        } finally {
1555            if (ip != null) {
1556                cleanUpInstall(ip);
1557            }
1558            // Restore default install location
1559            setInstallLoc(origDefaultLoc);
1560        }
1561    }
1562    private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
1563            int result) {
1564        moveFromRawResource("install.apk",
1565                R.raw.install, installFlags, moveFlags, true,
1566                fail, result);
1567    }
1568
1569    @LargeTest
1570    public void testMoveAppInternalToExternal() {
1571        // Do not run on devices with emulated external storage.
1572        if (Environment.isExternalStorageEmulated()) {
1573            return;
1574        }
1575
1576        int installFlags = PackageManager.INSTALL_INTERNAL;
1577        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1578        boolean fail = false;
1579        int result = PackageManager.MOVE_SUCCEEDED;
1580        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1581    }
1582
1583    @LargeTest
1584    public void testMoveAppInternalToInternal() {
1585        int installFlags = PackageManager.INSTALL_INTERNAL;
1586        int moveFlags = PackageManager.MOVE_INTERNAL;
1587        boolean fail = true;
1588        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1589        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1590    }
1591
1592    @LargeTest
1593    public void testMoveAppExternalToExternal() {
1594        // Do not run on devices with emulated external storage.
1595        if (Environment.isExternalStorageEmulated()) {
1596            return;
1597        }
1598
1599        int installFlags = PackageManager.INSTALL_EXTERNAL;
1600        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1601        boolean fail = true;
1602        int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1603        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1604    }
1605
1606    @LargeTest
1607    public void testMoveAppExternalToInternal() {
1608        // Do not run on devices with emulated external storage.
1609        if (Environment.isExternalStorageEmulated()) {
1610            return;
1611        }
1612
1613        int installFlags = PackageManager.INSTALL_EXTERNAL;
1614        int moveFlags = PackageManager.MOVE_INTERNAL;
1615        boolean fail = false;
1616        int result = PackageManager.MOVE_SUCCEEDED;
1617        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1618    }
1619
1620    @LargeTest
1621    public void testMoveAppForwardLocked() {
1622        // Do not run on devices with emulated external storage.
1623        if (Environment.isExternalStorageEmulated()) {
1624            return;
1625        }
1626
1627        int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
1628        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1629        boolean fail = true;
1630        int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
1631        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1632    }
1633
1634    @LargeTest
1635    public void testMoveAppFailInternalToExternalDelete() {
1636        // Do not run on devices with emulated external storage.
1637        if (Environment.isExternalStorageEmulated()) {
1638            return;
1639        }
1640
1641        int installFlags = 0;
1642        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1643        boolean fail = true;
1644        final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
1645
1646        int rawResId = R.raw.install;
1647        int origDefaultLoc = getDefaultInstallLoc();
1648        InstallParams ip = null;
1649        try {
1650            PackageManager pm = getPm();
1651            setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1652            // Install first
1653            ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
1654                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1655            // Delete the package now retaining data.
1656            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1657            invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver);
1658            assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1659        } catch (Exception e) {
1660            failStr(e);
1661        } finally {
1662            if (ip != null) {
1663                cleanUpInstall(ip);
1664            }
1665            // Restore default install location
1666            setInstallLoc(origDefaultLoc);
1667        }
1668    }
1669
1670    /*
1671     * Test that an install error code is returned when media is unmounted
1672     * and package installed on sdcard via package manager flag.
1673     */
1674    @LargeTest
1675    public void testInstallSdcardUnmount() {
1676        // Do not run on devices with emulated external storage.
1677        if (Environment.isExternalStorageEmulated()) {
1678            return;
1679        }
1680
1681        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1682        try {
1683            // Unmount sdcard
1684            assertTrue(unmountMedia());
1685            // Try to install and make sure an error code is returned.
1686            installFromRawResource("install.apk", R.raw.install,
1687                    PackageManager.INSTALL_EXTERNAL, false,
1688                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1689                    PackageInfo.INSTALL_LOCATION_AUTO);
1690        } finally {
1691            // Restore original media state
1692            if (origState) {
1693                mountMedia();
1694            } else {
1695                unmountMedia();
1696            }
1697        }
1698    }
1699
1700    /*
1701     * Unmount sdcard. Try installing an app with manifest option to install
1702     * on sdcard. Make sure it gets installed on internal flash.
1703     */
1704    @LargeTest
1705    public void testInstallManifestSdcardUnmount() {
1706        // Do not run on devices with emulated external storage.
1707        if (Environment.isExternalStorageEmulated()) {
1708            return;
1709        }
1710
1711        boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1712        try {
1713            // Unmount sdcard
1714            assertTrue(unmountMedia());
1715            InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
1716            installFromRawResource(ip, 0, true, false, -1,
1717                    PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1718        } finally {
1719            // Restore original media state
1720            if (origState) {
1721                mountMedia();
1722            } else {
1723                unmountMedia();
1724            }
1725        }
1726    }
1727
1728   /*---------- Recommended install location tests ----*/
1729   /* Precedence: FlagManifestExistingUser
1730    * PrecedenceSuffixes:
1731    * Flag : FlagI, FlagE, FlagF
1732    * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1733    * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1734    * Existing: Existing suffix absent if not existing.
1735    * User: UserI, UserE, UserA, User suffix absent if not existing.
1736    *
1737    */
1738
1739    /*
1740     * Install an app on internal flash
1741     */
1742    @LargeTest
1743    public void testFlagI() {
1744        sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1745    }
1746
1747    /*
1748     * Install an app on sdcard.
1749     */
1750    @LargeTest
1751    public void testFlagE() {
1752        // Do not run on devices with emulated external storage.
1753        if (Environment.isExternalStorageEmulated()) {
1754            return;
1755        }
1756
1757        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1758    }
1759
1760    /*
1761     * Install an app forward-locked.
1762     */
1763    @LargeTest
1764    public void testFlagF() {
1765        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1766    }
1767
1768    /*
1769     * Install an app with both internal and external flags set. should fail
1770     */
1771    @LargeTest
1772    public void testFlagIE() {
1773        installFromRawResource("install.apk", R.raw.install,
1774                PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1775                false,
1776                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1777                PackageInfo.INSTALL_LOCATION_AUTO);
1778    }
1779
1780    /*
1781     * Install an app with both internal and forward-lock flags set.
1782     */
1783    @LargeTest
1784    public void testFlagIF() {
1785        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1786                | PackageManager.INSTALL_INTERNAL, true);
1787    }
1788
1789    /*
1790     * Install an app with both external and forward-lock flags set.
1791     */
1792    @LargeTest
1793    public void testFlagEF() {
1794        // Do not run on devices with emulated external storage.
1795        if (Environment.isExternalStorageEmulated()) {
1796            return;
1797        }
1798
1799        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1800                | PackageManager.INSTALL_EXTERNAL, true);
1801    }
1802
1803    /*
1804     * Install an app with both internal and external flags set with forward
1805     * lock. Should fail.
1806     */
1807    @LargeTest
1808    public void testFlagIEF() {
1809        installFromRawResource("install.apk", R.raw.install,
1810                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1811                PackageManager.INSTALL_EXTERNAL,
1812                false,
1813                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1814                PackageInfo.INSTALL_LOCATION_AUTO);
1815    }
1816
1817   /*
1818    * Install an app with both internal and manifest option set.
1819    * should install on internal.
1820    */
1821   @LargeTest
1822   public void testFlagIManifestI() {
1823       installFromRawResource("install.apk", R.raw.install_loc_internal,
1824               PackageManager.INSTALL_INTERNAL,
1825               true,
1826               false, -1,
1827               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1828   }
1829   /*
1830    * Install an app with both internal and manifest preference for
1831    * preferExternal. Should install on internal.
1832    */
1833   @LargeTest
1834   public void testFlagIManifestE() {
1835       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1836               PackageManager.INSTALL_INTERNAL,
1837               true,
1838               false, -1,
1839               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1840   }
1841   /*
1842    * Install an app with both internal and manifest preference for
1843    * auto. should install internal.
1844    */
1845   @LargeTest
1846   public void testFlagIManifestA() {
1847       installFromRawResource("install.apk", R.raw.install_loc_auto,
1848               PackageManager.INSTALL_INTERNAL,
1849               true,
1850               false, -1,
1851               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1852   }
1853   /*
1854    * Install an app with both external and manifest option set.
1855    * should install externally.
1856    */
1857   @LargeTest
1858   public void testFlagEManifestI() {
1859        // Do not run on devices with emulated external storage.
1860        if (Environment.isExternalStorageEmulated()) {
1861            return;
1862        }
1863
1864       installFromRawResource("install.apk", R.raw.install_loc_internal,
1865               PackageManager.INSTALL_EXTERNAL,
1866               true,
1867               false, -1,
1868               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1869   }
1870
1871   /*
1872    * Install an app with both external and manifest preference for
1873    * preferExternal. Should install externally.
1874    */
1875   @LargeTest
1876   public void testFlagEManifestE() {
1877        // Do not run on devices with emulated external storage.
1878        if (Environment.isExternalStorageEmulated()) {
1879            return;
1880        }
1881
1882        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1883                PackageManager.INSTALL_EXTERNAL,
1884                true,
1885                false, -1,
1886                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1887    }
1888
1889    /*
1890     * Install an app with both external and manifest preference for
1891     * auto. should install on external media.
1892     */
1893    @LargeTest
1894    public void testFlagEManifestA() {
1895        // Do not run on devices with emulated external storage.
1896        if (Environment.isExternalStorageEmulated()) {
1897            return;
1898        }
1899
1900        installFromRawResource("install.apk", R.raw.install_loc_auto,
1901                PackageManager.INSTALL_EXTERNAL,
1902                true,
1903                false, -1,
1904                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1905    }
1906
1907    /*
1908     * Install an app with fwd locked flag set and install location set to
1909     * internal. should install internally.
1910     */
1911    @LargeTest
1912    public void testFlagFManifestI() {
1913        installFromRawResource("install.apk", R.raw.install_loc_internal,
1914                PackageManager.INSTALL_FORWARD_LOCK,
1915                true,
1916                false, -1,
1917                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1918    }
1919
1920    /*
1921     * Install an app with fwd locked flag set and install location set to
1922     * preferExternal. Should install externally.
1923     */
1924    @LargeTest
1925    public void testFlagFManifestE() {
1926        // Do not run on devices with emulated external storage.
1927        if (Environment.isExternalStorageEmulated()) {
1928            return;
1929        }
1930
1931        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1932                PackageManager.INSTALL_FORWARD_LOCK,
1933                true,
1934                false, -1,
1935                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1936    }
1937
1938    /*
1939     * Install an app with fwd locked flag set and install location set to auto.
1940     * should install externally.
1941     */
1942    @LargeTest
1943    public void testFlagFManifestA() {
1944        // Do not run on devices with emulated external storage.
1945        if (Environment.isExternalStorageEmulated()) {
1946            return;
1947        }
1948
1949        installFromRawResource("install.apk", R.raw.install_loc_auto,
1950                PackageManager.INSTALL_FORWARD_LOCK,
1951                true,
1952                false, -1,
1953                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1954    }
1955
1956    /* The following test functions verify install location for existing apps.
1957     * ie existing app can be installed internally or externally. If install
1958     * flag is explicitly set it should override current location. If manifest location
1959     * is set, that should over ride current location too. if not the existing install
1960     * location should be honoured.
1961     * testFlagI/E/F/ExistingI/E -
1962     */
1963    @LargeTest
1964    public void testFlagIExistingI() {
1965        int iFlags = PackageManager.INSTALL_INTERNAL;
1966        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1967        // First install.
1968        installFromRawResource("install.apk", R.raw.install,
1969                iFlags,
1970                false,
1971                false, -1,
1972                -1);
1973        // Replace now
1974        installFromRawResource("install.apk", R.raw.install,
1975                rFlags,
1976                true,
1977                false, -1,
1978                -1);
1979    }
1980
1981    @LargeTest
1982    public void testFlagIExistingE() {
1983        // Do not run on devices with emulated external storage.
1984        if (Environment.isExternalStorageEmulated()) {
1985            return;
1986        }
1987
1988        int iFlags = PackageManager.INSTALL_EXTERNAL;
1989        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1990        // First install.
1991        installFromRawResource("install.apk", R.raw.install,
1992                iFlags,
1993                false,
1994                false, -1,
1995                -1);
1996        // Replace now
1997        installFromRawResource("install.apk", R.raw.install,
1998                rFlags,
1999                true,
2000                false, -1,
2001                -1);
2002    }
2003
2004    @LargeTest
2005    public void testFlagEExistingI() {
2006        // Do not run on devices with emulated external storage.
2007        if (Environment.isExternalStorageEmulated()) {
2008            return;
2009        }
2010
2011        int iFlags = PackageManager.INSTALL_INTERNAL;
2012        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2013        // First install.
2014        installFromRawResource("install.apk", R.raw.install,
2015                iFlags,
2016                false,
2017                false, -1,
2018                -1);
2019        // Replace now
2020        installFromRawResource("install.apk", R.raw.install,
2021                rFlags,
2022                true,
2023                false, -1,
2024                -1);
2025    }
2026
2027    @LargeTest
2028    public void testFlagEExistingE() {
2029        // Do not run on devices with emulated external storage.
2030        if (Environment.isExternalStorageEmulated()) {
2031            return;
2032        }
2033
2034        int iFlags = PackageManager.INSTALL_EXTERNAL;
2035        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2036        // First install.
2037        installFromRawResource("install.apk", R.raw.install,
2038                iFlags,
2039                false,
2040                false, -1,
2041                -1);
2042        // Replace now
2043        installFromRawResource("install.apk", R.raw.install,
2044                rFlags,
2045                true,
2046                false, -1,
2047                -1);
2048    }
2049
2050    @LargeTest
2051    public void testFlagFExistingI() {
2052        int iFlags = PackageManager.INSTALL_INTERNAL;
2053        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2054        // First install.
2055        installFromRawResource("install.apk", R.raw.install,
2056                iFlags,
2057                false,
2058                false, -1,
2059                -1);
2060        // Replace now
2061        installFromRawResource("install.apk", R.raw.install,
2062                rFlags,
2063                true,
2064                false, -1,
2065                -1);
2066    }
2067
2068    @LargeTest
2069    public void testFlagFExistingE() {
2070        // Do not run on devices with emulated external storage.
2071        if (Environment.isExternalStorageEmulated()) {
2072            return;
2073        }
2074
2075        int iFlags = PackageManager.INSTALL_EXTERNAL;
2076        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2077        // First install.
2078        installFromRawResource("install.apk", R.raw.install,
2079                iFlags,
2080                false,
2081                false, -1,
2082                -1);
2083        // Replace now
2084        installFromRawResource("install.apk", R.raw.install,
2085                rFlags,
2086                true,
2087                false, -1,
2088                -1);
2089    }
2090
2091    /*
2092     * The following set of tests verify the installation of apps with
2093     * install location attribute set to internalOnly, preferExternal and auto.
2094     * The manifest option should dictate the install location.
2095     * public void testManifestI/E/A
2096     * TODO out of memory fall back behaviour.
2097     */
2098    @LargeTest
2099    public void testManifestI() {
2100        installFromRawResource("install.apk", R.raw.install_loc_internal,
2101                0,
2102                true,
2103                false, -1,
2104                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2105    }
2106
2107    @LargeTest
2108    public void testManifestE() {
2109        // Do not run on devices with emulated external storage.
2110        if (Environment.isExternalStorageEmulated()) {
2111            return;
2112        }
2113
2114        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2115                0,
2116                true,
2117                false, -1,
2118                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2119    }
2120
2121    @LargeTest
2122    public void testManifestA() {
2123        installFromRawResource("install.apk", R.raw.install_loc_auto,
2124                0,
2125                true,
2126                false, -1,
2127                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2128    }
2129
2130    /*
2131     * The following set of tests verify the installation of apps
2132     * with install location attribute set to internalOnly, preferExternal and auto
2133     * for already existing apps. The manifest option should take precedence.
2134     * TODO add out of memory fall back behaviour.
2135     * testManifestI/E/AExistingI/E
2136     */
2137    @LargeTest
2138    public void testManifestIExistingI() {
2139        int iFlags = PackageManager.INSTALL_INTERNAL;
2140        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2141        // First install.
2142        installFromRawResource("install.apk", R.raw.install,
2143                iFlags,
2144                false,
2145                false, -1,
2146                -1);
2147        // Replace now
2148        installFromRawResource("install.apk", R.raw.install_loc_internal,
2149                rFlags,
2150                true,
2151                false, -1,
2152                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2153    }
2154
2155    @LargeTest
2156    public void testManifestIExistingE() {
2157        // Do not run on devices with emulated external storage.
2158        if (Environment.isExternalStorageEmulated()) {
2159            return;
2160        }
2161
2162        int iFlags = PackageManager.INSTALL_EXTERNAL;
2163        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2164        // First install.
2165        installFromRawResource("install.apk", R.raw.install,
2166                iFlags,
2167                false,
2168                false, -1,
2169                -1);
2170        // Replace now
2171        installFromRawResource("install.apk", R.raw.install_loc_internal,
2172                rFlags,
2173                true,
2174                false, -1,
2175                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2176    }
2177
2178    @LargeTest
2179    public void testManifestEExistingI() {
2180        // Do not run on devices with emulated external storage.
2181        if (Environment.isExternalStorageEmulated()) {
2182            return;
2183        }
2184
2185        int iFlags = PackageManager.INSTALL_INTERNAL;
2186        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2187        // First install.
2188        installFromRawResource("install.apk", R.raw.install,
2189                iFlags,
2190                false,
2191                false, -1,
2192                -1);
2193        // Replace now
2194        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2195                rFlags,
2196                true,
2197                false, -1,
2198                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2199    }
2200
2201    @LargeTest
2202    public void testManifestEExistingE() {
2203        // Do not run on devices with emulated external storage.
2204        if (Environment.isExternalStorageEmulated()) {
2205            return;
2206        }
2207
2208        int iFlags = PackageManager.INSTALL_EXTERNAL;
2209        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2210        // First install.
2211        installFromRawResource("install.apk", R.raw.install,
2212                iFlags,
2213                false,
2214                false, -1,
2215                -1);
2216        // Replace now
2217        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2218                rFlags,
2219                true,
2220                false, -1,
2221                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2222    }
2223
2224    @LargeTest
2225    public void testManifestAExistingI() {
2226        int iFlags = PackageManager.INSTALL_INTERNAL;
2227        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2228        // First install.
2229        installFromRawResource("install.apk", R.raw.install,
2230                iFlags,
2231                false,
2232                false, -1,
2233                -1);
2234        // Replace now
2235        installFromRawResource("install.apk", R.raw.install_loc_auto,
2236                rFlags,
2237                true,
2238                false, -1,
2239                PackageInfo.INSTALL_LOCATION_AUTO);
2240    }
2241
2242    @LargeTest
2243    public void testManifestAExistingE() {
2244        // Do not run on devices with emulated external storage.
2245        if (Environment.isExternalStorageEmulated()) {
2246            return;
2247        }
2248
2249        int iFlags = PackageManager.INSTALL_EXTERNAL;
2250        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2251        // First install.
2252        installFromRawResource("install.apk", R.raw.install,
2253                iFlags,
2254                false,
2255                false, -1,
2256                -1);
2257        // Replace now
2258        installFromRawResource("install.apk", R.raw.install_loc_auto,
2259                rFlags,
2260                true,
2261                false, -1,
2262                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2263    }
2264
2265   /*
2266    * The following set of tests check install location for existing
2267    * application based on user setting.
2268    */
2269   private int getExpectedInstallLocation(int userSetting) {
2270       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2271       boolean enable = getUserSettingSetInstallLocation();
2272       if (enable) {
2273           if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
2274               iloc = PackageInfo.INSTALL_LOCATION_AUTO;
2275           } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
2276               iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
2277           } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
2278               iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
2279           }
2280       }
2281       return iloc;
2282   }
2283   private void setExistingXUserX(int userSetting, int iFlags, int iloc) {
2284       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2285       // First install.
2286       installFromRawResource("install.apk", R.raw.install,
2287               iFlags,
2288               false,
2289               false, -1,
2290               PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2291       int origSetting = getDefaultInstallLoc();
2292       try {
2293           // Set user setting
2294           setInstallLoc(userSetting);
2295           // Replace now
2296           installFromRawResource("install.apk", R.raw.install,
2297                   rFlags,
2298                   true,
2299                   false, -1,
2300                   iloc);
2301       } finally {
2302           setInstallLoc(origSetting);
2303       }
2304   }
2305   @LargeTest
2306   public void testExistingIUserI() {
2307       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2308       int iFlags = PackageManager.INSTALL_INTERNAL;
2309       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2310   }
2311
2312    @LargeTest
2313    public void testExistingIUserE() {
2314        // Do not run on devices with emulated external storage.
2315        if (Environment.isExternalStorageEmulated()) {
2316            return;
2317        }
2318
2319        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2320        int iFlags = PackageManager.INSTALL_INTERNAL;
2321        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2322    }
2323
2324   @LargeTest
2325   public void testExistingIUserA() {
2326       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2327       int iFlags = PackageManager.INSTALL_INTERNAL;
2328       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2329   }
2330
2331    @LargeTest
2332    public void testExistingEUserI() {
2333        // Do not run on devices with emulated external storage.
2334        if (Environment.isExternalStorageEmulated()) {
2335            return;
2336        }
2337
2338        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2339        int iFlags = PackageManager.INSTALL_EXTERNAL;
2340        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2341    }
2342
2343    @LargeTest
2344    public void testExistingEUserE() {
2345        // Do not run on devices with emulated external storage.
2346        if (Environment.isExternalStorageEmulated()) {
2347            return;
2348        }
2349
2350        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2351        int iFlags = PackageManager.INSTALL_EXTERNAL;
2352        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2353    }
2354
2355    @LargeTest
2356    public void testExistingEUserA() {
2357        // Do not run on devices with emulated external storage.
2358        if (Environment.isExternalStorageEmulated()) {
2359            return;
2360        }
2361
2362        int userSetting = PackageHelper.APP_INSTALL_AUTO;
2363        int iFlags = PackageManager.INSTALL_EXTERNAL;
2364        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2365    }
2366
2367   /*
2368    * The following set of tests verify that the user setting defines
2369    * the install location.
2370    *
2371    */
2372   private boolean getUserSettingSetInstallLocation() {
2373       try {
2374           return Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION) != 0;
2375
2376       } catch (SettingNotFoundException e1) {
2377       }
2378       return false;
2379   }
2380
2381   private void setUserSettingSetInstallLocation(boolean value) {
2382       Settings.System.putInt(mContext.getContentResolver(),
2383               Settings.Secure.SET_INSTALL_LOCATION, value ? 1 : 0);
2384   }
2385   private void setUserX(boolean enable, int userSetting, int iloc) {
2386       boolean origUserSetting = getUserSettingSetInstallLocation();
2387       int origSetting = getDefaultInstallLoc();
2388       try {
2389           setUserSettingSetInstallLocation(enable);
2390           // Set user setting
2391           setInstallLoc(userSetting);
2392           // Replace now
2393           installFromRawResource("install.apk", R.raw.install,
2394                   0,
2395                   true,
2396                   false, -1,
2397                   iloc);
2398       } finally {
2399           // Restore original setting
2400           setUserSettingSetInstallLocation(origUserSetting);
2401           setInstallLoc(origSetting);
2402       }
2403   }
2404   @LargeTest
2405   public void testUserI() {
2406       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2407       int iloc = getExpectedInstallLocation(userSetting);
2408       setUserX(true, userSetting, iloc);
2409   }
2410
2411    @LargeTest
2412    public void testUserE() {
2413        // Do not run on devices with emulated external storage.
2414        if (Environment.isExternalStorageEmulated()) {
2415            return;
2416        }
2417
2418        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2419        int iloc = getExpectedInstallLocation(userSetting);
2420        setUserX(true, userSetting, iloc);
2421    }
2422
2423   @LargeTest
2424   public void testUserA() {
2425       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2426       int iloc = getExpectedInstallLocation(userSetting);
2427       setUserX(true, userSetting, iloc);
2428   }
2429   /*
2430    * The following set of tests turn on/off the basic
2431    * user setting for turning on install location.
2432    */
2433   @LargeTest
2434   public void testUserPrefOffUserI() {
2435       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2436       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2437       setUserX(false, userSetting, iloc);
2438   }
2439
2440    @LargeTest
2441    public void testUserPrefOffUserE() {
2442        // Do not run on devices with emulated external storage.
2443        if (Environment.isExternalStorageEmulated()) {
2444            return;
2445        }
2446
2447        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2448        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2449        setUserX(false, userSetting, iloc);
2450    }
2451
2452   @LargeTest
2453   public void testUserPrefOffA() {
2454       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2455       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2456       setUserX(false, userSetting, iloc);
2457   }
2458
2459    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
2460        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
2461        PERM_DEFINED,
2462        "com.android.frameworks.coretests.NORMAL",
2463        "com.android.frameworks.coretests.DANGEROUS",
2464        "com.android.frameworks.coretests.SIGNATURE",
2465    };
2466
2467    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
2468        PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
2469        PERM_UNDEFINED,
2470        "com.android.frameworks.coretests.NORMAL",
2471        "com.android.frameworks.coretests.DANGEROUS",
2472        "com.android.frameworks.coretests.SIGNATURE",
2473    };
2474
2475    static final String BASE_PERMISSIONS_USED[] = new String[] {
2476        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2477        PERM_USED,
2478        "com.android.frameworks.coretests.NORMAL",
2479        "com.android.frameworks.coretests.DANGEROUS",
2480        "com.android.frameworks.coretests.SIGNATURE",
2481    };
2482
2483    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
2484        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2485        PERM_NOTUSED,
2486        "com.android.frameworks.coretests.NORMAL",
2487        "com.android.frameworks.coretests.DANGEROUS",
2488        "com.android.frameworks.coretests.SIGNATURE",
2489    };
2490
2491    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
2492        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2493        PERM_USED,
2494        "com.android.frameworks.coretests.SIGNATURE",
2495        PERM_NOTUSED,
2496        "com.android.frameworks.coretests.NORMAL",
2497        "com.android.frameworks.coretests.DANGEROUS",
2498    };
2499
2500    /*
2501     * Ensure that permissions are properly declared.
2502     */
2503    @LargeTest
2504    public void testInstallDeclaresPermissions() {
2505        InstallParams ip = null;
2506        InstallParams ip2 = null;
2507        try {
2508            // **: Upon installing a package, are its declared permissions published?
2509
2510            int iFlags = PackageManager.INSTALL_INTERNAL;
2511            int iApk = R.raw.install_decl_perm;
2512            ip = installFromRawResource("install.apk", iApk,
2513                    iFlags, false,
2514                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2515            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2516            assertPermissions(BASE_PERMISSIONS_DEFINED);
2517
2518            // **: Upon installing package, are its permissions granted?
2519
2520            int i2Flags = PackageManager.INSTALL_INTERNAL;
2521            int i2Apk = R.raw.install_use_perm_good;
2522            ip2 = installFromRawResource("install2.apk", i2Apk,
2523                    i2Flags, false,
2524                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2525            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2526            assertPermissions(BASE_PERMISSIONS_USED);
2527
2528            // **: Upon removing but not deleting, are permissions retained?
2529
2530            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2531
2532            try {
2533                invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver);
2534            } catch (Exception e) {
2535                failStr(e);
2536            }
2537            assertPermissions(BASE_PERMISSIONS_DEFINED);
2538            assertPermissions(BASE_PERMISSIONS_USED);
2539
2540            // **: Upon re-installing, are permissions retained?
2541
2542            ip = installFromRawResource("install.apk", iApk,
2543                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2544                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2545            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2546            assertPermissions(BASE_PERMISSIONS_DEFINED);
2547            assertPermissions(BASE_PERMISSIONS_USED);
2548
2549            // **: Upon deleting package, are all permissions removed?
2550
2551            try {
2552                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2553                ip = null;
2554            } catch (Exception e) {
2555                failStr(e);
2556            }
2557            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2558            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2559
2560            // **: Delete package using permissions; nothing to check here.
2561
2562            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2563            try {
2564                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2565                ip2 = null;
2566            } catch (Exception e) {
2567                failStr(e);
2568            }
2569
2570            // **: Re-install package using permissions; no permissions can be granted.
2571
2572            ip2 = installFromRawResource("install2.apk", i2Apk,
2573                    i2Flags, false,
2574                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2575            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2576            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2577
2578            // **: Upon installing declaring package, are sig permissions granted
2579            // to other apps (but not other perms)?
2580
2581            ip = installFromRawResource("install.apk", iApk,
2582                    iFlags, false,
2583                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2584            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2585            assertPermissions(BASE_PERMISSIONS_DEFINED);
2586            assertPermissions(BASE_PERMISSIONS_SIGUSED);
2587
2588            // **: Re-install package using permissions; are all permissions granted?
2589
2590            ip2 = installFromRawResource("install2.apk", i2Apk,
2591                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2592                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2593            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2594            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2595
2596            // **: Upon deleting package, are all permissions removed?
2597
2598            try {
2599                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2600                ip = null;
2601            } catch (Exception e) {
2602                failStr(e);
2603            }
2604            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2605            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2606
2607            // **: Delete package using permissions; nothing to check here.
2608
2609            try {
2610                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2611                ip2 = null;
2612            } catch (Exception e) {
2613                failStr(e);
2614            }
2615
2616        } finally {
2617            if (ip2 != null) {
2618                cleanUpInstall(ip2);
2619            }
2620            if (ip != null) {
2621                cleanUpInstall(ip);
2622            }
2623        }
2624    }
2625
2626    /*
2627     * Ensure that permissions are properly declared.
2628     */
2629    @LargeTest
2630    public void testInstallOnSdPermissionsUnmount() {
2631        InstallParams ip = null;
2632        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2633        try {
2634            // **: Upon installing a package, are its declared permissions published?
2635            int iFlags = PackageManager.INSTALL_INTERNAL;
2636            int iApk = R.raw.install_decl_perm;
2637            ip = installFromRawResource("install.apk", iApk,
2638                    iFlags, false,
2639                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2640            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2641            assertPermissions(BASE_PERMISSIONS_DEFINED);
2642            // Unmount media here
2643            assertTrue(unmountMedia());
2644            // Mount media again
2645            mountMedia();
2646            //Check permissions now
2647            assertPermissions(BASE_PERMISSIONS_DEFINED);
2648        } finally {
2649            if (ip != null) {
2650                cleanUpInstall(ip);
2651            }
2652        }
2653    }
2654
2655    /* This test creates a stale container via MountService and then installs
2656     * a package and verifies that the stale container is cleaned up and install
2657     * is successful.
2658     * Please note that this test is very closely tied to the framework's
2659     * naming convention for secure containers.
2660     */
2661    @LargeTest
2662    public void testInstallSdcardStaleContainer() {
2663        // Do not run on devices with emulated external storage.
2664        if (Environment.isExternalStorageEmulated()) {
2665            return;
2666        }
2667
2668        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2669        try {
2670            // Mount media first
2671            mountMedia();
2672            String outFileName = "install.apk";
2673            int rawResId = R.raw.install;
2674            PackageManager pm = mContext.getPackageManager();
2675            File filesDir = mContext.getFilesDir();
2676            File outFile = new File(filesDir, outFileName);
2677            Uri packageURI = getInstallablePackage(rawResId, outFile);
2678            PackageParser.Package pkg = parsePackage(packageURI);
2679            assertNotNull(pkg);
2680            // Install an app on sdcard.
2681            installFromRawResource(outFileName, rawResId,
2682                    PackageManager.INSTALL_EXTERNAL, false,
2683                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2684            // Unmount sdcard
2685            unmountMedia();
2686            // Delete the app on sdcard to leave a stale container on sdcard.
2687            GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2688            assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver));
2689            mountMedia();
2690            // Reinstall the app and make sure it gets installed.
2691            installFromRawResource(outFileName, rawResId,
2692                    PackageManager.INSTALL_EXTERNAL, true,
2693                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2694        } catch (Exception e) {
2695            failStr(e.getMessage());
2696        } finally {
2697            if (origMediaState) {
2698                mountMedia();
2699            } else {
2700                unmountMedia();
2701            }
2702
2703        }
2704    }
2705
2706    /* This test installs an application on sdcard and unmounts media.
2707     * The app is then re-installed on internal storage. The sdcard is mounted
2708     * and verified that the re-installation on internal storage takes precedence.
2709     */
2710    @LargeTest
2711    public void testInstallSdcardStaleContainerReinstall() {
2712        // Do not run on devices with emulated external storage.
2713        if (Environment.isExternalStorageEmulated()) {
2714            return;
2715        }
2716
2717        boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2718        try {
2719            // Mount media first
2720            mountMedia();
2721            String outFileName = "install.apk";
2722            int rawResId = R.raw.install;
2723            PackageManager pm = mContext.getPackageManager();
2724            File filesDir = mContext.getFilesDir();
2725            File outFile = new File(filesDir, outFileName);
2726            Uri packageURI = getInstallablePackage(rawResId, outFile);
2727            PackageParser.Package pkg = parsePackage(packageURI);
2728            assertNotNull(pkg);
2729            // Install an app on sdcard.
2730            installFromRawResource(outFileName, rawResId,
2731                    PackageManager.INSTALL_EXTERNAL, false,
2732                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2733            // Unmount sdcard
2734            unmountMedia();
2735            // Reinstall the app and make sure it gets installed on internal storage.
2736            installFromRawResource(outFileName, rawResId,
2737                    PackageManager.INSTALL_REPLACE_EXISTING, false,
2738                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2739            mountMedia();
2740            // Verify that the app installed is on internal storage.
2741            assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2742        } catch (Exception e) {
2743            failStr(e.getMessage());
2744        } finally {
2745            if (origMediaState) {
2746                mountMedia();
2747            } else {
2748                unmountMedia();
2749            }
2750        }
2751    }
2752
2753    /*
2754     * The following series of tests are related to upgrading apps with
2755     * different certificates.
2756     */
2757    private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
2758    private int APP1_CERT1 = R.raw.install_app1_cert1;
2759    private int APP1_CERT2 = R.raw.install_app1_cert2;
2760    private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
2761    private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
2762    private int APP1_CERT3 = R.raw.install_app1_cert3;
2763    private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
2764    private int APP2_CERT1 = R.raw.install_app2_cert1;
2765    private int APP2_CERT2 = R.raw.install_app2_cert2;
2766    private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
2767    private int APP2_CERT3 = R.raw.install_app2_cert3;
2768
2769    private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode) {
2770        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2771        String apk1Name = "install1.apk";
2772        String apk2Name = "install2.apk";
2773        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2774        try {
2775            InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2776                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2777            installFromRawResource(apk2Name, apk2, rFlags, false,
2778                    fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2779            return ip;
2780        } catch (Exception e) {
2781            failStr(e.getMessage());
2782        } finally {
2783            if (cleanUp) {
2784                cleanUpInstall(pkg1.packageName);
2785            }
2786        }
2787        return null;
2788    }
2789    /*
2790     * Test that an app signed with two certificates can be upgraded by the
2791     * same app signed with two certificates.
2792     */
2793    @LargeTest
2794    public void testReplaceMatchAllCerts() {
2795        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
2796    }
2797
2798    /*
2799     * Test that an app signed with two certificates cannot be upgraded
2800     * by an app signed with a different certificate.
2801     */
2802    @LargeTest
2803    public void testReplaceMatchNoCerts1() {
2804        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
2805                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2806    }
2807    /*
2808     * Test that an app signed with two certificates cannot be upgraded
2809     * by an app signed with a different certificate.
2810     */
2811    @LargeTest
2812    public void testReplaceMatchNoCerts2() {
2813        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
2814                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2815    }
2816    /*
2817     * Test that an app signed with two certificates cannot be upgraded by
2818     * an app signed with a subset of initial certificates.
2819     */
2820    @LargeTest
2821    public void testReplaceMatchSomeCerts1() {
2822        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
2823                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2824    }
2825    /*
2826     * Test that an app signed with two certificates cannot be upgraded by
2827     * an app signed with the last certificate.
2828     */
2829    @LargeTest
2830    public void testReplaceMatchSomeCerts2() {
2831        replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
2832                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2833    }
2834    /*
2835     * Test that an app signed with a certificate can be upgraded by app
2836     * signed with a superset of certificates.
2837     */
2838    @LargeTest
2839    public void testReplaceMatchMoreCerts() {
2840        replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
2841                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2842    }
2843    /*
2844     * Test that an app signed with a certificate can be upgraded by app
2845     * signed with a superset of certificates. Then verify that the an app
2846     * signed with the original set of certs cannot upgrade the new one.
2847     */
2848    @LargeTest
2849    public void testReplaceMatchMoreCertsReplaceSomeCerts() {
2850        InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
2851                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2852        try {
2853            int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2854            installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
2855                    false, -1,
2856                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2857        } catch (Exception e) {
2858            failStr(e.getMessage());
2859        } finally {
2860            if (ip != null) {
2861                cleanUpInstall(ip);
2862            }
2863        }
2864    }
2865    /*
2866     * The following tests are related to testing the checkSignatures
2867     * api.
2868     */
2869    private void checkSignatures(int apk1, int apk2, int expMatchResult) {
2870        checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
2871    }
2872    @LargeTest
2873    public void testCheckSignaturesAllMatch() {
2874        int apk1 = APP1_CERT1_CERT2;
2875        int apk2 = APP2_CERT1_CERT2;
2876        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2877    }
2878    @LargeTest
2879    public void testCheckSignaturesNoMatch() {
2880        int apk1 = APP1_CERT1;
2881        int apk2 = APP2_CERT2;
2882        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2883    }
2884    @LargeTest
2885    public void testCheckSignaturesSomeMatch1() {
2886        int apk1 = APP1_CERT1_CERT2;
2887        int apk2 = APP2_CERT1;
2888        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2889    }
2890    @LargeTest
2891    public void testCheckSignaturesSomeMatch2() {
2892        int apk1 = APP1_CERT1_CERT2;
2893        int apk2 = APP2_CERT2;
2894        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2895    }
2896    @LargeTest
2897    public void testCheckSignaturesMoreMatch() {
2898        int apk1 = APP1_CERT1;
2899        int apk2 = APP2_CERT1_CERT2;
2900        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2901    }
2902    @LargeTest
2903    public void testCheckSignaturesUnknown() {
2904        int apk1 = APP1_CERT1_CERT2;
2905        int apk2 = APP2_CERT1_CERT2;
2906        String apk1Name = "install1.apk";
2907        String apk2Name = "install2.apk";
2908        InstallParams ip1 = null;
2909
2910        try {
2911            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
2912                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2913            PackageManager pm = mContext.getPackageManager();
2914            // Delete app2
2915            File filesDir = mContext.getFilesDir();
2916            File outFile = new File(filesDir, apk2Name);
2917            int rawResId = apk2;
2918            Uri packageURI = getInstallablePackage(rawResId, outFile);
2919            PackageParser.Package pkg = parsePackage(packageURI);
2920            getPm().deletePackage(pkg.packageName, null, 0);
2921            // Check signatures now
2922            int match = mContext.getPackageManager().checkSignatures(
2923                    ip1.pkg.packageName, pkg.packageName);
2924            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
2925        } finally {
2926            if (ip1 != null) {
2927                cleanUpInstall(ip1);
2928            }
2929        }
2930    }
2931    @LargeTest
2932    public void testInstallNoCertificates() {
2933        int apk1 = APP1_UNSIGNED;
2934        String apk1Name = "install1.apk";
2935        InstallParams ip1 = null;
2936
2937        try {
2938            installFromRawResource(apk1Name, apk1, 0, false,
2939                    true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
2940                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2941        } finally {
2942        }
2943    }
2944    /* The following tests are related to apps using shared uids signed
2945     * with different certs.
2946     */
2947    private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
2948    private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
2949    private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
2950    private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
2951    private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
2952    private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
2953    private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
2954    private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
2955    private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult) {
2956        String apk1Name = "install1.apk";
2957        String apk2Name = "install2.apk";
2958        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2959        PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
2960
2961        try {
2962            // Clean up before testing first.
2963            cleanUpInstall(pkg1.packageName);
2964            cleanUpInstall(pkg2.packageName);
2965            installFromRawResource(apk1Name, apk1, 0, false,
2966                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2967            if (fail) {
2968                installFromRawResource(apk2Name, apk2, 0, false,
2969                        true, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2970            } else {
2971                installFromRawResource(apk2Name, apk2, 0, false,
2972                        false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2973                int match = mContext.getPackageManager().checkSignatures(
2974                        pkg1.packageName, pkg2.packageName);
2975                assertEquals(expMatchResult, match);
2976            }
2977        } finally {
2978            if (cleanUp) {
2979                cleanUpInstall(pkg1.packageName);
2980                cleanUpInstall(pkg2.packageName);
2981            }
2982        }
2983    }
2984    @LargeTest
2985    public void testCheckSignaturesSharedAllMatch() {
2986        int apk1 = SHARED1_CERT1_CERT2;
2987        int apk2 = SHARED2_CERT1_CERT2;
2988        boolean fail = false;
2989        int retCode = -1;
2990        int expMatchResult = PackageManager.SIGNATURE_MATCH;
2991        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2992    }
2993    @LargeTest
2994    public void testCheckSignaturesSharedNoMatch() {
2995        int apk1 = SHARED1_CERT1;
2996        int apk2 = SHARED2_CERT2;
2997        boolean fail = true;
2998        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
2999        int expMatchResult = -1;
3000        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3001    }
3002    /*
3003     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone.
3004     */
3005    @LargeTest
3006    public void testCheckSignaturesSharedSomeMatch1() {
3007        int apk1 = SHARED1_CERT1_CERT2;
3008        int apk2 = SHARED2_CERT1;
3009        boolean fail = true;
3010        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3011        int expMatchResult = -1;
3012        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3013    }
3014    /*
3015     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone.
3016     */
3017    @LargeTest
3018    public void testCheckSignaturesSharedSomeMatch2() {
3019        int apk1 = SHARED1_CERT1_CERT2;
3020        int apk2 = SHARED2_CERT2;
3021        boolean fail = true;
3022        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3023        int expMatchResult = -1;
3024        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3025    }
3026    @LargeTest
3027    public void testCheckSignaturesSharedUnknown() {
3028        int apk1 = SHARED1_CERT1_CERT2;
3029        int apk2 = SHARED2_CERT1_CERT2;
3030        String apk1Name = "install1.apk";
3031        String apk2Name = "install2.apk";
3032        InstallParams ip1 = null;
3033
3034        try {
3035            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
3036                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3037            PackageManager pm = mContext.getPackageManager();
3038            // Delete app2
3039            PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
3040            getPm().deletePackage(pkg.packageName, null, 0);
3041            // Check signatures now
3042            int match = mContext.getPackageManager().checkSignatures(
3043                    ip1.pkg.packageName, pkg.packageName);
3044            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3045        } finally {
3046            if (ip1 != null) {
3047                cleanUpInstall(ip1);
3048            }
3049        }
3050    }
3051
3052    @LargeTest
3053    public void testReplaceFirstSharedMatchAllCerts() {
3054        int apk1 = SHARED1_CERT1;
3055        int apk2 = SHARED2_CERT1;
3056        int rapk1 = SHARED1_CERT1;
3057        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3058        replaceCerts(apk1, rapk1, true, false, -1);
3059    }
3060    @LargeTest
3061    public void testReplaceSecondSharedMatchAllCerts() {
3062        int apk1 = SHARED1_CERT1;
3063        int apk2 = SHARED2_CERT1;
3064        int rapk2 = SHARED2_CERT1;
3065        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3066        replaceCerts(apk2, rapk2, true, false, -1);
3067    }
3068    @LargeTest
3069    public void testReplaceFirstSharedMatchSomeCerts() {
3070        int apk1 = SHARED1_CERT1_CERT2;
3071        int apk2 = SHARED2_CERT1_CERT2;
3072        int rapk1 = SHARED1_CERT1;
3073        boolean fail = true;
3074        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3075        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3076        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3077                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3078    }
3079    @LargeTest
3080    public void testReplaceSecondSharedMatchSomeCerts() {
3081        int apk1 = SHARED1_CERT1_CERT2;
3082        int apk2 = SHARED2_CERT1_CERT2;
3083        int rapk2 = SHARED2_CERT1;
3084        boolean fail = true;
3085        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3086        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3087        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3088                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3089    }
3090    @LargeTest
3091    public void testReplaceFirstSharedMatchNoCerts() {
3092        int apk1 = SHARED1_CERT1;
3093        int apk2 = SHARED2_CERT1;
3094        int rapk1 = SHARED1_CERT2;
3095        boolean fail = true;
3096        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3097        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3098        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3099                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3100    }
3101    @LargeTest
3102    public void testReplaceSecondSharedMatchNoCerts() {
3103        int apk1 = SHARED1_CERT1;
3104        int apk2 = SHARED2_CERT1;
3105        int rapk2 = SHARED2_CERT2;
3106        boolean fail = true;
3107        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3108        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3109        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3110                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3111    }
3112    @LargeTest
3113    public void testReplaceFirstSharedMatchMoreCerts() {
3114        int apk1 = SHARED1_CERT1;
3115        int apk2 = SHARED2_CERT1;
3116        int rapk1 = SHARED1_CERT1_CERT2;
3117        boolean fail = true;
3118        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3119        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3120        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3121                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3122    }
3123    @LargeTest
3124    public void testReplaceSecondSharedMatchMoreCerts() {
3125        int apk1 = SHARED1_CERT1;
3126        int apk2 = SHARED2_CERT1;
3127        int rapk2 = SHARED2_CERT1_CERT2;
3128        boolean fail = true;
3129        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3130        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3131        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3132                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3133    }
3134
3135    /**
3136     * Unknown features should be allowed to install. This prevents older phones
3137     * from rejecting new packages that specify features that didn't exist when
3138     * an older phone existed. All older phones are assumed to have those
3139     * features.
3140     * <p>
3141     * Right now we allow all packages to be installed regardless of their
3142     * features.
3143     */
3144    @LargeTest
3145    public void testUsesFeatureUnknownFeature() {
3146        int retCode = PackageManager.INSTALL_SUCCEEDED;
3147        installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode,
3148                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3149    }
3150
3151    @LargeTest
3152    public void testInstallNonexistentFile() {
3153        int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
3154        File invalidFile = new File("/nonexistent-file.apk");
3155        invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
3156    }
3157
3158    @SmallTest
3159    public void testGetVerifierDeviceIdentity() {
3160        PackageManager pm = getPm();
3161        VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity();
3162
3163        assertNotNull("Verifier device identity should not be null", id);
3164    }
3165
3166    /*---------- Recommended install location tests ----*/
3167    /*
3168     * TODO's
3169     * check version numbers for upgrades
3170     * check permissions of installed packages
3171     * how to do tests on updated system apps?
3172     * verify updates to system apps cannot be installed on the sdcard.
3173     */
3174}
3175