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