PackageManagerTests.java revision 9a212adcffbc4b32d51f512889b33ba584647aa9
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    @MediumTest
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            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1465            invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver);
1466            assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1467        } catch (Exception e) {
1468            failStr(e);
1469        } finally {
1470            if (ip != null) {
1471                cleanUpInstall(ip);
1472            }
1473            // Restore default install location
1474            setInstallLoc(origDefaultLoc);
1475        }
1476    }
1477    /*
1478     * Test that an install error code is returned when media is unmounted
1479     * and package installed on sdcard via package manager flag.
1480     */
1481    @MediumTest
1482    public void testInstallSdcardUnmount() {
1483        boolean origState = getMediaState();
1484        try {
1485            // Unmount sdcard
1486            assertTrue(unmountMedia());
1487            // Try to install and make sure an error code is returned.
1488            installFromRawResource("install.apk", R.raw.install,
1489                    PackageManager.INSTALL_EXTERNAL, false,
1490                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1491                    PackageInfo.INSTALL_LOCATION_AUTO);
1492        } finally {
1493            // Restore original media state
1494            if (origState) {
1495                mountMedia();
1496            } else {
1497                unmountMedia();
1498            }
1499        }
1500    }
1501
1502    /*
1503     * Unmount sdcard. Try installing an app with manifest option to install
1504     * on sdcard. Make sure it gets installed on internal flash.
1505     */
1506    @MediumTest
1507    public void testInstallManifestSdcardUnmount() {
1508       boolean origState = getMediaState();
1509       try {
1510           // Unmount sdcard
1511           assertTrue(unmountMedia());
1512           InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
1513           installFromRawResource(ip, 0, true, false, -1,
1514                   PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1515       } finally {
1516           // Restore original media state
1517           if (origState) {
1518               mountMedia();
1519           } else {
1520               unmountMedia();
1521           }
1522       }
1523   }
1524
1525   /*---------- Recommended install location tests ----*/
1526   /* Precedence: FlagManifestExistingUser
1527    * PrecedenceSuffixes:
1528    * Flag : FlagI, FlagE, FlagF
1529    * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1530    * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1531    * Existing: Existing suffix absent if not existing.
1532    * User: UserI, UserE, UserA, User suffix absent if not existing.
1533    *
1534    */
1535   /*
1536    * Install an app on internal flash
1537    */
1538   @MediumTest
1539   public void testFlagI() {
1540       sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1541   }
1542   /*
1543    * Install an app on sdcard.
1544    */
1545   @MediumTest
1546   public void testFlagE() {
1547       sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1548   }
1549
1550   /*
1551    * Install an app on sdcard.
1552    */
1553   @MediumTest
1554   public void testFlagF() {
1555       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1556   }
1557   /*
1558    * Install an app with both internal and external flags set. should fail
1559    */
1560   @MediumTest
1561   public void testFlagIE() {
1562       installFromRawResource("install.apk", R.raw.install,
1563               PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1564               false,
1565               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1566               PackageInfo.INSTALL_LOCATION_AUTO);
1567   }
1568
1569   /*
1570    * Install an app with both internal and external flags set. should fail
1571    */
1572   @MediumTest
1573   public void testFlagIF() {
1574       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
1575               PackageManager.INSTALL_INTERNAL, true);
1576   }
1577   /*
1578    * Install an app with both internal and external flags set. should fail
1579    */
1580   @MediumTest
1581   public void testFlagEF() {
1582       installFromRawResource("install.apk", R.raw.install,
1583               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
1584               false,
1585               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1586               PackageInfo.INSTALL_LOCATION_AUTO);
1587   }
1588   /*
1589    * Install an app with both internal and external flags set. should fail
1590    */
1591   @MediumTest
1592   public void testFlagIEF() {
1593       installFromRawResource("install.apk", R.raw.install,
1594               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1595               PackageManager.INSTALL_EXTERNAL,
1596               false,
1597               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1598               PackageInfo.INSTALL_LOCATION_AUTO);
1599   }
1600   /*
1601    * Install an app with both internal and manifest option set.
1602    * should install on internal.
1603    */
1604   @MediumTest
1605   public void testFlagIManifestI() {
1606       installFromRawResource("install.apk", R.raw.install_loc_internal,
1607               PackageManager.INSTALL_INTERNAL,
1608               true,
1609               false, -1,
1610               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1611   }
1612   /*
1613    * Install an app with both internal and manifest preference for
1614    * preferExternal. Should install on internal.
1615    */
1616   @MediumTest
1617   public void testFlagIManifestE() {
1618       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1619               PackageManager.INSTALL_INTERNAL,
1620               true,
1621               false, -1,
1622               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1623   }
1624   /*
1625    * Install an app with both internal and manifest preference for
1626    * auto. should install internal.
1627    */
1628   @MediumTest
1629   public void testFlagIManifestA() {
1630       installFromRawResource("install.apk", R.raw.install_loc_auto,
1631               PackageManager.INSTALL_INTERNAL,
1632               true,
1633               false, -1,
1634               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1635   }
1636   /*
1637    * Install an app with both external and manifest option set.
1638    * should install externally.
1639    */
1640   @MediumTest
1641   public void testFlagEManifestI() {
1642       installFromRawResource("install.apk", R.raw.install_loc_internal,
1643               PackageManager.INSTALL_EXTERNAL,
1644               true,
1645               false, -1,
1646               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1647   }
1648   /*
1649    * Install an app with both external and manifest preference for
1650    * preferExternal. Should install externally.
1651    */
1652   @MediumTest
1653   public void testFlagEManifestE() {
1654       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1655               PackageManager.INSTALL_EXTERNAL,
1656               true,
1657               false, -1,
1658               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1659   }
1660   /*
1661    * Install an app with both external and manifest preference for
1662    * auto. should install on external media.
1663    */
1664   @MediumTest
1665   public void testFlagEManifestA() {
1666       installFromRawResource("install.apk", R.raw.install_loc_auto,
1667               PackageManager.INSTALL_EXTERNAL,
1668               true,
1669               false, -1,
1670               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1671   }
1672   /*
1673    * Install an app with fwd locked flag set and install location set to
1674    * internal. should install internally.
1675    */
1676   @MediumTest
1677   public void testFlagFManifestI() {
1678       installFromRawResource("install.apk", R.raw.install_loc_internal,
1679               PackageManager.INSTALL_EXTERNAL,
1680               true,
1681               false, -1,
1682               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1683   }
1684   /*
1685    * Install an app with fwd locked flag set and install location set to
1686    * preferExternal. should install internally.
1687    */
1688   @MediumTest
1689   public void testFlagFManifestE() {
1690       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1691               PackageManager.INSTALL_EXTERNAL,
1692               true,
1693               false, -1,
1694               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1695   }
1696   /*
1697    * Install an app with fwd locked flag set and install location set to
1698    * auto. should install internally.
1699    */
1700   @MediumTest
1701   public void testFlagFManifestA() {
1702       installFromRawResource("install.apk", R.raw.install_loc_auto,
1703               PackageManager.INSTALL_EXTERNAL,
1704               true,
1705               false, -1,
1706               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1707   }
1708   /* The following test functions verify install location for existing apps.
1709    * ie existing app can be installed internally or externally. If install
1710    * flag is explicitly set it should override current location. If manifest location
1711    * is set, that should over ride current location too. if not the existing install
1712    * location should be honoured.
1713    * testFlagI/E/F/ExistingI/E -
1714    */
1715   @MediumTest
1716   public void testFlagIExistingI() {
1717       int iFlags = PackageManager.INSTALL_INTERNAL;
1718       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1719       // First install.
1720       installFromRawResource("install.apk", R.raw.install,
1721               iFlags,
1722               false,
1723               false, -1,
1724               -1);
1725       // Replace now
1726       installFromRawResource("install.apk", R.raw.install,
1727               rFlags,
1728               true,
1729               false, -1,
1730               -1);
1731   }
1732   @MediumTest
1733   public void testFlagIExistingE() {
1734       int iFlags = PackageManager.INSTALL_EXTERNAL;
1735       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1736       // First install.
1737       installFromRawResource("install.apk", R.raw.install,
1738               iFlags,
1739               false,
1740               false, -1,
1741               -1);
1742       // Replace now
1743       installFromRawResource("install.apk", R.raw.install,
1744               rFlags,
1745               true,
1746               false, -1,
1747               -1);
1748   }
1749   @MediumTest
1750   public void testFlagEExistingI() {
1751       int iFlags = PackageManager.INSTALL_INTERNAL;
1752       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1753       // First install.
1754       installFromRawResource("install.apk", R.raw.install,
1755               iFlags,
1756               false,
1757               false, -1,
1758               -1);
1759       // Replace now
1760       installFromRawResource("install.apk", R.raw.install,
1761               rFlags,
1762               true,
1763               false, -1,
1764               -1);
1765   }
1766   @MediumTest
1767   public void testFlagEExistingE() {
1768       int iFlags = PackageManager.INSTALL_EXTERNAL;
1769       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1770       // First install.
1771       installFromRawResource("install.apk", R.raw.install,
1772               iFlags,
1773               false,
1774               false, -1,
1775               -1);
1776       // Replace now
1777       installFromRawResource("install.apk", R.raw.install,
1778               rFlags,
1779               true,
1780               false, -1,
1781               -1);
1782   }
1783   @MediumTest
1784   public void testFlagFExistingI() {
1785       int iFlags = PackageManager.INSTALL_INTERNAL;
1786       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
1787       // First install.
1788       installFromRawResource("install.apk", R.raw.install,
1789               iFlags,
1790               false,
1791               false, -1,
1792               -1);
1793       // Replace now
1794       installFromRawResource("install.apk", R.raw.install,
1795               rFlags,
1796               true,
1797               false, -1,
1798               -1);
1799   }
1800   @MediumTest
1801   public void testFlagFExistingE() {
1802       int iFlags = PackageManager.INSTALL_EXTERNAL;
1803       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
1804       // First install.
1805       installFromRawResource("install.apk", R.raw.install,
1806               iFlags,
1807               false,
1808               false, -1,
1809               -1);
1810       // Replace now
1811       installFromRawResource("install.apk", R.raw.install,
1812               rFlags,
1813               true,
1814               false, -1,
1815               -1);
1816   }
1817   /*
1818    * The following set of tests verify the installation of apps with
1819    * install location attribute set to internalOnly, preferExternal and auto.
1820    * The manifest option should dictate the install location.
1821    * public void testManifestI/E/A
1822    * TODO out of memory fall back behaviour.
1823    */
1824   @MediumTest
1825   public void testManifestI() {
1826       installFromRawResource("install.apk", R.raw.install_loc_internal,
1827               0,
1828               true,
1829               false, -1,
1830               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1831   }
1832   @MediumTest
1833   public void testManifestE() {
1834       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1835               0,
1836               true,
1837               false, -1,
1838               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1839   }
1840   @MediumTest
1841   public void testManifestA() {
1842       installFromRawResource("install.apk", R.raw.install_loc_auto,
1843               0,
1844               true,
1845               false, -1,
1846               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1847   }
1848   /*
1849    * The following set of tests verify the installation of apps
1850    * with install location attribute set to internalOnly, preferExternal and auto
1851    * for already existing apps. The manifest option should take precedence.
1852    * TODO add out of memory fall back behaviour.
1853    * testManifestI/E/AExistingI/E
1854    */
1855   @MediumTest
1856   public void testManifestIExistingI() {
1857       int iFlags = PackageManager.INSTALL_INTERNAL;
1858       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1859       // First install.
1860       installFromRawResource("install.apk", R.raw.install,
1861               iFlags,
1862               false,
1863               false, -1,
1864               -1);
1865       // Replace now
1866       installFromRawResource("install.apk", R.raw.install_loc_internal,
1867               rFlags,
1868               true,
1869               false, -1,
1870               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1871   }
1872   @MediumTest
1873   public void testManifestIExistingE() {
1874       int iFlags = PackageManager.INSTALL_EXTERNAL;
1875       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1876       // First install.
1877       installFromRawResource("install.apk", R.raw.install,
1878               iFlags,
1879               false,
1880               false, -1,
1881               -1);
1882       // Replace now
1883       installFromRawResource("install.apk", R.raw.install_loc_internal,
1884               rFlags,
1885               true,
1886               false, -1,
1887               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1888   }
1889   @MediumTest
1890   public void testManifestEExistingI() {
1891       int iFlags = PackageManager.INSTALL_INTERNAL;
1892       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1893       // First install.
1894       installFromRawResource("install.apk", R.raw.install,
1895               iFlags,
1896               false,
1897               false, -1,
1898               -1);
1899       // Replace now
1900       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1901               rFlags,
1902               true,
1903               false, -1,
1904               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1905   }
1906   @MediumTest
1907   public void testManifestEExistingE() {
1908       int iFlags = PackageManager.INSTALL_EXTERNAL;
1909       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1910       // First install.
1911       installFromRawResource("install.apk", R.raw.install,
1912               iFlags,
1913               false,
1914               false, -1,
1915               -1);
1916       // Replace now
1917       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1918               rFlags,
1919               true,
1920               false, -1,
1921               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1922   }
1923   @MediumTest
1924   public void testManifestAExistingI() {
1925       int iFlags = PackageManager.INSTALL_INTERNAL;
1926       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1927       // First install.
1928       installFromRawResource("install.apk", R.raw.install,
1929               iFlags,
1930               false,
1931               false, -1,
1932               -1);
1933       // Replace now
1934       installFromRawResource("install.apk", R.raw.install_loc_auto,
1935               rFlags,
1936               true,
1937               false, -1,
1938               PackageInfo.INSTALL_LOCATION_AUTO);
1939   }
1940   @MediumTest
1941   public void testManifestAExistingE() {
1942       int iFlags = PackageManager.INSTALL_EXTERNAL;
1943       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1944       // First install.
1945       installFromRawResource("install.apk", R.raw.install,
1946               iFlags,
1947               false,
1948               false, -1,
1949               -1);
1950       // Replace now
1951       installFromRawResource("install.apk", R.raw.install_loc_auto,
1952               rFlags,
1953               true,
1954               false, -1,
1955               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1956   }
1957   /*
1958    * The following set of tests check install location for existing
1959    * application based on user setting.
1960    */
1961   private int getExpectedInstallLocation(int userSetting) {
1962       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1963       boolean enable = getUserSettingSetInstallLocation();
1964       if (enable) {
1965           if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
1966               iloc = PackageInfo.INSTALL_LOCATION_AUTO;
1967           } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
1968               iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
1969           } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
1970               iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
1971           }
1972       }
1973       return iloc;
1974   }
1975   private void setExistingXUserX(int userSetting, int iFlags, int iloc) {
1976       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1977       // First install.
1978       installFromRawResource("install.apk", R.raw.install,
1979               iFlags,
1980               false,
1981               false, -1,
1982               PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1983       int origSetting = getDefaultInstallLoc();
1984       try {
1985           // Set user setting
1986           setInstallLoc(userSetting);
1987           // Replace now
1988           installFromRawResource("install.apk", R.raw.install,
1989                   rFlags,
1990                   true,
1991                   false, -1,
1992                   iloc);
1993       } finally {
1994           setInstallLoc(origSetting);
1995       }
1996   }
1997   @MediumTest
1998   public void testExistingIUserI() {
1999       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2000       int iFlags = PackageManager.INSTALL_INTERNAL;
2001       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2002   }
2003   @MediumTest
2004   public void testExistingIUserE() {
2005       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2006       int iFlags = PackageManager.INSTALL_INTERNAL;
2007       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2008   }
2009   @MediumTest
2010   public void testExistingIUserA() {
2011       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2012       int iFlags = PackageManager.INSTALL_INTERNAL;
2013       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2014   }
2015   @MediumTest
2016   public void testExistingEUserI() {
2017       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2018       int iFlags = PackageManager.INSTALL_EXTERNAL;
2019       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2020   }
2021   @MediumTest
2022   public void testExistingEUserE() {
2023       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2024       int iFlags = PackageManager.INSTALL_EXTERNAL;
2025       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2026   }
2027   @MediumTest
2028   public void testExistingEUserA() {
2029       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2030       int iFlags = PackageManager.INSTALL_EXTERNAL;
2031       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2032   }
2033   /*
2034    * The following set of tests verify that the user setting defines
2035    * the install location.
2036    *
2037    */
2038   private boolean getUserSettingSetInstallLocation() {
2039       try {
2040           return Settings.System.getInt(mContext.getContentResolver(), Settings.Secure.SET_INSTALL_LOCATION) != 0;
2041
2042       } catch (SettingNotFoundException e1) {
2043       }
2044       return false;
2045   }
2046
2047   private void setUserSettingSetInstallLocation(boolean value) {
2048       Settings.System.putInt(mContext.getContentResolver(),
2049               Settings.Secure.SET_INSTALL_LOCATION, value ? 1 : 0);
2050   }
2051   private void setUserX(boolean enable, int userSetting, int iloc) {
2052       boolean origUserSetting = getUserSettingSetInstallLocation();
2053       int origSetting = getDefaultInstallLoc();
2054       try {
2055           setUserSettingSetInstallLocation(enable);
2056           // Set user setting
2057           setInstallLoc(userSetting);
2058           // Replace now
2059           installFromRawResource("install.apk", R.raw.install,
2060                   0,
2061                   true,
2062                   false, -1,
2063                   iloc);
2064       } finally {
2065           // Restore original setting
2066           setUserSettingSetInstallLocation(origUserSetting);
2067           setInstallLoc(origSetting);
2068       }
2069   }
2070   @MediumTest
2071   public void testUserI() {
2072       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2073       int iloc = getExpectedInstallLocation(userSetting);
2074       setUserX(true, userSetting, iloc);
2075   }
2076   @MediumTest
2077   public void testUserE() {
2078       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2079       int iloc = getExpectedInstallLocation(userSetting);
2080       setUserX(true, userSetting, iloc);
2081   }
2082   @MediumTest
2083   public void testUserA() {
2084       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2085       int iloc = getExpectedInstallLocation(userSetting);
2086       setUserX(true, userSetting, iloc);
2087   }
2088   /*
2089    * The following set of tests turn on/off the basic
2090    * user setting for turning on install location.
2091    */
2092   @MediumTest
2093   public void testUserPrefOffUserI() {
2094       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2095       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2096       setUserX(false, userSetting, iloc);
2097   }
2098   @MediumTest
2099   public void testUserPrefOffUserE() {
2100       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2101       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2102       setUserX(false, userSetting, iloc);
2103   }
2104   @MediumTest
2105   public void testUserPrefOffA() {
2106       int userSetting = PackageHelper.APP_INSTALL_AUTO;
2107       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2108       setUserX(false, userSetting, iloc);
2109   }
2110
2111    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
2112        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
2113        PERM_DEFINED,
2114        "com.android.frameworks.coretests.NORMAL",
2115        "com.android.frameworks.coretests.DANGEROUS",
2116        "com.android.frameworks.coretests.SIGNATURE",
2117    };
2118
2119    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
2120        PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
2121        PERM_UNDEFINED,
2122        "com.android.frameworks.coretests.NORMAL",
2123        "com.android.frameworks.coretests.DANGEROUS",
2124        "com.android.frameworks.coretests.SIGNATURE",
2125    };
2126
2127    static final String BASE_PERMISSIONS_USED[] = new String[] {
2128        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2129        PERM_USED,
2130        "com.android.frameworks.coretests.NORMAL",
2131        "com.android.frameworks.coretests.DANGEROUS",
2132        "com.android.frameworks.coretests.SIGNATURE",
2133    };
2134
2135    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
2136        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2137        PERM_NOTUSED,
2138        "com.android.frameworks.coretests.NORMAL",
2139        "com.android.frameworks.coretests.DANGEROUS",
2140        "com.android.frameworks.coretests.SIGNATURE",
2141    };
2142
2143    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
2144        PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2145        PERM_USED,
2146        "com.android.frameworks.coretests.SIGNATURE",
2147        PERM_NOTUSED,
2148        "com.android.frameworks.coretests.NORMAL",
2149        "com.android.frameworks.coretests.DANGEROUS",
2150    };
2151
2152    /*
2153     * Ensure that permissions are properly declared.
2154     */
2155    @LargeTest
2156    public void testInstallDeclaresPermissions() {
2157        InstallParams ip = null;
2158        InstallParams ip2 = null;
2159        try {
2160            // **: Upon installing a package, are its declared permissions published?
2161
2162            int iFlags = PackageManager.INSTALL_INTERNAL;
2163            int iApk = R.raw.install_decl_perm;
2164            ip = installFromRawResource("install.apk", iApk,
2165                    iFlags, false,
2166                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2167            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2168            assertPermissions(BASE_PERMISSIONS_DEFINED);
2169
2170            // **: Upon installing package, are its permissions granted?
2171
2172            int i2Flags = PackageManager.INSTALL_INTERNAL;
2173            int i2Apk = R.raw.install_use_perm_good;
2174            ip2 = installFromRawResource("install2.apk", i2Apk,
2175                    i2Flags, false,
2176                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2177            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2178            assertPermissions(BASE_PERMISSIONS_USED);
2179
2180            // **: Upon removing but not deleting, are permissions retained?
2181
2182            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2183
2184            try {
2185                invokeDeletePackage(ip.pkg.packageName, PackageManager.DONT_DELETE_DATA, receiver);
2186            } catch (Exception e) {
2187                failStr(e);
2188            }
2189            assertPermissions(BASE_PERMISSIONS_DEFINED);
2190            assertPermissions(BASE_PERMISSIONS_USED);
2191
2192            // **: Upon re-installing, are permissions retained?
2193
2194            ip = installFromRawResource("install.apk", iApk,
2195                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2196                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2197            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2198            assertPermissions(BASE_PERMISSIONS_DEFINED);
2199            assertPermissions(BASE_PERMISSIONS_USED);
2200
2201            // **: Upon deleting package, are all permissions removed?
2202
2203            try {
2204                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2205                ip = null;
2206            } catch (Exception e) {
2207                failStr(e);
2208            }
2209            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2210            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2211
2212            // **: Delete package using permissions; nothing to check here.
2213
2214            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2215            try {
2216                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2217                ip2 = null;
2218            } catch (Exception e) {
2219                failStr(e);
2220            }
2221
2222            // **: Re-install package using permissions; no permissions can be granted.
2223
2224            ip2 = installFromRawResource("install2.apk", i2Apk,
2225                    i2Flags, false,
2226                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2227            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2228            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2229
2230            // **: Upon installing declaring package, are sig permissions granted
2231            // to other apps (but not other perms)?
2232
2233            ip = installFromRawResource("install.apk", iApk,
2234                    iFlags, false,
2235                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2236            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2237            assertPermissions(BASE_PERMISSIONS_DEFINED);
2238            assertPermissions(BASE_PERMISSIONS_SIGUSED);
2239
2240            // **: Re-install package using permissions; are all permissions granted?
2241
2242            ip2 = installFromRawResource("install2.apk", i2Apk,
2243                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2244                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2245            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2246            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2247
2248            // **: Upon deleting package, are all permissions removed?
2249
2250            try {
2251                invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2252                ip = null;
2253            } catch (Exception e) {
2254                failStr(e);
2255            }
2256            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2257            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2258
2259            // **: Delete package using permissions; nothing to check here.
2260
2261            try {
2262                invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2263                ip2 = null;
2264            } catch (Exception e) {
2265                failStr(e);
2266            }
2267
2268        } finally {
2269            if (ip2 != null) {
2270                cleanUpInstall(ip2);
2271            }
2272            if (ip != null) {
2273                cleanUpInstall(ip);
2274            }
2275        }
2276    }
2277
2278    /*
2279     * Ensure that permissions are properly declared.
2280     */
2281    @MediumTest
2282    public void testInstallOnSdPermissionsUnmount() {
2283        InstallParams ip = null;
2284        boolean origMediaState = getMediaState();
2285        try {
2286            // **: Upon installing a package, are its declared permissions published?
2287            int iFlags = PackageManager.INSTALL_INTERNAL;
2288            int iApk = R.raw.install_decl_perm;
2289            ip = installFromRawResource("install.apk", iApk,
2290                    iFlags, false,
2291                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2292            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2293            assertPermissions(BASE_PERMISSIONS_DEFINED);
2294            // Unmount media here
2295            assertTrue(unmountMedia());
2296            // Mount media again
2297            mountMedia();
2298            //Check permissions now
2299            assertPermissions(BASE_PERMISSIONS_DEFINED);
2300        } finally {
2301            if (ip != null) {
2302                cleanUpInstall(ip);
2303            }
2304        }
2305    }
2306
2307    /* This test creates a stale container via MountService and then installs
2308     * a package and verifies that the stale container is cleaned up and install
2309     * is successful.
2310     * Please note that this test is very closely tied to the framework's
2311     * naming convention for secure containers.
2312     */
2313    @MediumTest
2314    public void testInstallSdcardStaleContainer() {
2315        boolean origMediaState = getMediaState();
2316        try {
2317            String outFileName = "install.apk";
2318            int rawResId = R.raw.install;
2319            PackageManager pm = mContext.getPackageManager();
2320            File filesDir = mContext.getFilesDir();
2321            File outFile = new File(filesDir, outFileName);
2322            Uri packageURI = getInstallablePackage(rawResId, outFile);
2323            PackageParser.Package pkg = parsePackage(packageURI);
2324            assertNotNull(pkg);
2325            // Install an app on sdcard.
2326            installFromRawResource(outFileName, rawResId,
2327                    PackageManager.INSTALL_EXTERNAL, false,
2328                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2329            // Unmount sdcard
2330            unmountMedia();
2331            // Delete the app on sdcard to leave a stale container on sdcard.
2332            GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2333            assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver));
2334            mountMedia();
2335            // Reinstall the app and make sure it gets installed.
2336            installFromRawResource(outFileName, rawResId,
2337                    PackageManager.INSTALL_EXTERNAL, true,
2338                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2339        } catch (Exception e) {
2340            failStr(e.getMessage());
2341        } finally {
2342            if (origMediaState) {
2343                mountMedia();
2344            } else {
2345                unmountMedia();
2346            }
2347
2348        }
2349    }
2350
2351    /* This test installs an application on sdcard and unmounts media.
2352     * The app is then re-installed on internal storage. The sdcard is mounted
2353     * and verified that the re-installation on internal storage takes precedence.
2354     */
2355    @MediumTest
2356    public void testInstallSdcardStaleContainerReinstall() {
2357        boolean origMediaState = getMediaState();
2358        try {
2359            // Mount media first
2360            mountMedia();
2361            String outFileName = "install.apk";
2362            int rawResId = R.raw.install;
2363            PackageManager pm = mContext.getPackageManager();
2364            File filesDir = mContext.getFilesDir();
2365            File outFile = new File(filesDir, outFileName);
2366            Uri packageURI = getInstallablePackage(rawResId, outFile);
2367            PackageParser.Package pkg = parsePackage(packageURI);
2368            assertNotNull(pkg);
2369            // Install an app on sdcard.
2370            installFromRawResource(outFileName, rawResId,
2371                    PackageManager.INSTALL_EXTERNAL, false,
2372                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2373            // Unmount sdcard
2374            unmountMedia();
2375            // Reinstall the app and make sure it gets installed on internal storage.
2376            installFromRawResource(outFileName, rawResId,
2377                    PackageManager.INSTALL_REPLACE_EXISTING, false,
2378                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2379            mountMedia();
2380            // Verify that the app installed is on internal storage.
2381            assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2382        } catch (Exception e) {
2383            failStr(e.getMessage());
2384        } finally {
2385            if (origMediaState) {
2386                mountMedia();
2387            } else {
2388                unmountMedia();
2389            }
2390
2391        }
2392    }
2393    /*
2394     * The following series of tests are related to upgrading apps with
2395     * different certificates.
2396     */
2397    private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
2398    private int APP1_CERT1 = R.raw.install_app1_cert1;
2399    private int APP1_CERT2 = R.raw.install_app1_cert2;
2400    private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
2401    private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
2402    private int APP1_CERT3 = R.raw.install_app1_cert3;
2403    private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
2404    private int APP2_CERT1 = R.raw.install_app2_cert1;
2405    private int APP2_CERT2 = R.raw.install_app2_cert2;
2406    private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
2407    private int APP2_CERT3 = R.raw.install_app2_cert3;
2408
2409    private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode) {
2410        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2411        String apk1Name = "install1.apk";
2412        String apk2Name = "install2.apk";
2413        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2414        try {
2415            InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2416                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2417            installFromRawResource(apk2Name, apk2, rFlags, false,
2418                    fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2419            return ip;
2420        } catch (Exception e) {
2421            failStr(e.getMessage());
2422        } finally {
2423            if (cleanUp) {
2424                cleanUpInstall(pkg1.packageName);
2425            }
2426        }
2427        return null;
2428    }
2429    /*
2430     * Test that an app signed with two certificates can be upgraded by the
2431     * same app signed with two certificates.
2432     */
2433    @MediumTest
2434    public void testReplaceMatchAllCerts() {
2435        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
2436    }
2437
2438    /*
2439     * Test that an app signed with two certificates cannot be upgraded
2440     * by an app signed with a different certificate.
2441     */
2442    @MediumTest
2443    public void testReplaceMatchNoCerts1() {
2444        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
2445                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2446    }
2447    /*
2448     * Test that an app signed with two certificates cannot be upgraded
2449     * by an app signed with a different certificate.
2450     */
2451    @MediumTest
2452    public void testReplaceMatchNoCerts2() {
2453        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
2454                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2455    }
2456    /*
2457     * Test that an app signed with two certificates cannot be upgraded by
2458     * an app signed with a subset of initial certificates.
2459     */
2460    @MediumTest
2461    public void testReplaceMatchSomeCerts1() {
2462        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
2463                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2464    }
2465    /*
2466     * Test that an app signed with two certificates cannot be upgraded by
2467     * an app signed with the last certificate.
2468     */
2469    @MediumTest
2470    public void testReplaceMatchSomeCerts2() {
2471        replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
2472                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2473    }
2474    /*
2475     * Test that an app signed with a certificate can be upgraded by app
2476     * signed with a superset of certificates.
2477     */
2478    @MediumTest
2479    public void testReplaceMatchMoreCerts() {
2480        replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
2481                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2482    }
2483    /*
2484     * Test that an app signed with a certificate can be upgraded by app
2485     * signed with a superset of certificates. Then verify that the an app
2486     * signed with the original set of certs cannot upgrade the new one.
2487     */
2488    @MediumTest
2489    public void testReplaceMatchMoreCertsReplaceSomeCerts() {
2490        InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
2491                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
2492        try {
2493            int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2494            installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
2495                    false, -1,
2496                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2497        } catch (Exception e) {
2498            failStr(e.getMessage());
2499        } finally {
2500            if (ip != null) {
2501                cleanUpInstall(ip);
2502            }
2503        }
2504    }
2505    /*
2506     * The following tests are related to testing the checkSignatures
2507     * api.
2508     */
2509    private void checkSignatures(int apk1, int apk2, int expMatchResult) {
2510        checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
2511    }
2512    @MediumTest
2513    public void testCheckSignaturesAllMatch() {
2514        int apk1 = APP1_CERT1_CERT2;
2515        int apk2 = APP2_CERT1_CERT2;
2516        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2517    }
2518    @MediumTest
2519    public void testCheckSignaturesNoMatch() {
2520        int apk1 = APP1_CERT1;
2521        int apk2 = APP2_CERT2;
2522        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2523    }
2524    @MediumTest
2525    public void testCheckSignaturesSomeMatch1() {
2526        int apk1 = APP1_CERT1_CERT2;
2527        int apk2 = APP2_CERT1;
2528        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2529    }
2530    @MediumTest
2531    public void testCheckSignaturesSomeMatch2() {
2532        int apk1 = APP1_CERT1_CERT2;
2533        int apk2 = APP2_CERT2;
2534        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2535    }
2536    @MediumTest
2537    public void testCheckSignaturesMoreMatch() {
2538        int apk1 = APP1_CERT1;
2539        int apk2 = APP2_CERT1_CERT2;
2540        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2541    }
2542    @MediumTest
2543    public void testCheckSignaturesUnknown() {
2544        int apk1 = APP1_CERT1_CERT2;
2545        int apk2 = APP2_CERT1_CERT2;
2546        String apk1Name = "install1.apk";
2547        String apk2Name = "install2.apk";
2548        InstallParams ip1 = null;
2549
2550        try {
2551            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
2552                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2553            PackageManager pm = mContext.getPackageManager();
2554            // Delete app2
2555            File filesDir = mContext.getFilesDir();
2556            File outFile = new File(filesDir, apk2Name);
2557            int rawResId = apk2;
2558            Uri packageURI = getInstallablePackage(rawResId, outFile);
2559            PackageParser.Package pkg = parsePackage(packageURI);
2560            getPm().deletePackage(pkg.packageName, null, 0);
2561            // Check signatures now
2562            int match = mContext.getPackageManager().checkSignatures(
2563                    ip1.pkg.packageName, pkg.packageName);
2564            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
2565        } finally {
2566            if (ip1 != null) {
2567                cleanUpInstall(ip1);
2568            }
2569        }
2570    }
2571    @MediumTest
2572    public void testInstallNoCertificates() {
2573        int apk1 = APP1_UNSIGNED;
2574        String apk1Name = "install1.apk";
2575        InstallParams ip1 = null;
2576
2577        try {
2578            installFromRawResource(apk1Name, apk1, 0, false,
2579                    true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
2580                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2581        } finally {
2582        }
2583    }
2584    /* The following tests are related to apps using shared uids signed
2585     * with different certs.
2586     */
2587    private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
2588    private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
2589    private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
2590    private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
2591    private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
2592    private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
2593    private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
2594    private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
2595    private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult) {
2596        String apk1Name = "install1.apk";
2597        String apk2Name = "install2.apk";
2598        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2599        PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
2600
2601        try {
2602            // Clean up before testing first.
2603            cleanUpInstall(pkg1.packageName);
2604            cleanUpInstall(pkg2.packageName);
2605            installFromRawResource(apk1Name, apk1, 0, false,
2606                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2607            if (fail) {
2608                installFromRawResource(apk2Name, apk2, 0, false,
2609                        true, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2610            } else {
2611                installFromRawResource(apk2Name, apk2, 0, false,
2612                        false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2613                int match = mContext.getPackageManager().checkSignatures(
2614                        pkg1.packageName, pkg2.packageName);
2615                assertEquals(expMatchResult, match);
2616            }
2617        } finally {
2618            if (cleanUp) {
2619                cleanUpInstall(pkg1.packageName);
2620                cleanUpInstall(pkg2.packageName);
2621            }
2622        }
2623    }
2624    @MediumTest
2625    public void testCheckSignaturesSharedAllMatch() {
2626        int apk1 = SHARED1_CERT1_CERT2;
2627        int apk2 = SHARED2_CERT1_CERT2;
2628        boolean fail = false;
2629        int retCode = -1;
2630        int expMatchResult = PackageManager.SIGNATURE_MATCH;
2631        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2632    }
2633    @MediumTest
2634    public void testCheckSignaturesSharedNoMatch() {
2635        int apk1 = SHARED1_CERT1;
2636        int apk2 = SHARED2_CERT2;
2637        boolean fail = true;
2638        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
2639        int expMatchResult = -1;
2640        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2641    }
2642    /*
2643     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone.
2644     */
2645    @MediumTest
2646    public void testCheckSignaturesSharedSomeMatch1() {
2647        int apk1 = SHARED1_CERT1_CERT2;
2648        int apk2 = SHARED2_CERT1;
2649        boolean fail = true;
2650        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
2651        int expMatchResult = -1;
2652        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2653    }
2654    /*
2655     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone.
2656     */
2657    @MediumTest
2658    public void testCheckSignaturesSharedSomeMatch2() {
2659        int apk1 = SHARED1_CERT1_CERT2;
2660        int apk2 = SHARED2_CERT2;
2661        boolean fail = true;
2662        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
2663        int expMatchResult = -1;
2664        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2665    }
2666    @MediumTest
2667    public void testCheckSignaturesSharedUnknown() {
2668        int apk1 = SHARED1_CERT1_CERT2;
2669        int apk2 = SHARED2_CERT1_CERT2;
2670        String apk1Name = "install1.apk";
2671        String apk2Name = "install2.apk";
2672        InstallParams ip1 = null;
2673
2674        try {
2675            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
2676                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2677            PackageManager pm = mContext.getPackageManager();
2678            // Delete app2
2679            PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
2680            getPm().deletePackage(pkg.packageName, null, 0);
2681            // Check signatures now
2682            int match = mContext.getPackageManager().checkSignatures(
2683                    ip1.pkg.packageName, pkg.packageName);
2684            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
2685        } finally {
2686            if (ip1 != null) {
2687                cleanUpInstall(ip1);
2688            }
2689        }
2690    }
2691
2692    @MediumTest
2693    public void testReplaceFirstSharedMatchAllCerts() {
2694        int apk1 = SHARED1_CERT1;
2695        int apk2 = SHARED2_CERT1;
2696        int rapk1 = SHARED1_CERT1;
2697        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2698        replaceCerts(apk1, rapk1, true, false, -1);
2699    }
2700    @MediumTest
2701    public void testReplaceSecondSharedMatchAllCerts() {
2702        int apk1 = SHARED1_CERT1;
2703        int apk2 = SHARED2_CERT1;
2704        int rapk2 = SHARED2_CERT1;
2705        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2706        replaceCerts(apk2, rapk2, true, false, -1);
2707    }
2708    @MediumTest
2709    public void testReplaceFirstSharedMatchSomeCerts() {
2710        int apk1 = SHARED1_CERT1_CERT2;
2711        int apk2 = SHARED2_CERT1_CERT2;
2712        int rapk1 = SHARED1_CERT1;
2713        boolean fail = true;
2714        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2715        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2716        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2717                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2718    }
2719    @MediumTest
2720    public void testReplaceSecondSharedMatchSomeCerts() {
2721        int apk1 = SHARED1_CERT1_CERT2;
2722        int apk2 = SHARED2_CERT1_CERT2;
2723        int rapk2 = SHARED2_CERT1;
2724        boolean fail = true;
2725        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2726        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2727        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2728                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2729    }
2730    @MediumTest
2731    public void testReplaceFirstSharedMatchNoCerts() {
2732        int apk1 = SHARED1_CERT1;
2733        int apk2 = SHARED2_CERT1;
2734        int rapk1 = SHARED1_CERT2;
2735        boolean fail = true;
2736        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2737        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2738        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2739                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2740    }
2741    @MediumTest
2742    public void testReplaceSecondSharedMatchNoCerts() {
2743        int apk1 = SHARED1_CERT1;
2744        int apk2 = SHARED2_CERT1;
2745        int rapk2 = SHARED2_CERT2;
2746        boolean fail = true;
2747        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2748        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2749        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2750                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2751    }
2752    @MediumTest
2753    public void testReplaceFirstSharedMatchMoreCerts() {
2754        int apk1 = SHARED1_CERT1;
2755        int apk2 = SHARED2_CERT1;
2756        int rapk1 = SHARED1_CERT1_CERT2;
2757        boolean fail = true;
2758        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2759        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2760        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2761                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2762    }
2763    @MediumTest
2764    public void testReplaceSecondSharedMatchMoreCerts() {
2765        int apk1 = SHARED1_CERT1;
2766        int apk2 = SHARED2_CERT1;
2767        int rapk2 = SHARED2_CERT1_CERT2;
2768        boolean fail = true;
2769        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
2770        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2771        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2772                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2773    }
2774    /*---------- Recommended install location tests ----*/
2775    /*
2776     * TODO's
2777     * check version numbers for upgrades
2778     * check permissions of installed packages
2779     * how to do tests on updated system apps?
2780     * verify updates to system apps cannot be installed on the sdcard.
2781     */
2782}
2783