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