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