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