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