PackageManagerTests.java revision a3de74555120cc4dc205a3f93ef44c843b8d64a8
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content.pm;
18
19import com.android.frameworks.coretests.R;
20import com.android.internal.content.PackageHelper;
21
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.content.pm.PackageManager.NameNotFoundException;
27import android.content.res.Resources;
28import android.content.res.Resources.NotFoundException;
29import android.net.Uri;
30import android.os.Environment;
31import android.os.FileUtils;
32import android.os.IBinder;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.os.StatFs;
36import android.os.storage.IMountService;
37import android.os.storage.StorageListener;
38import android.os.storage.StorageManager;
39import android.os.storage.StorageResultCode;
40import android.provider.Settings;
41import android.provider.Settings.SettingNotFoundException;
42import android.test.AndroidTestCase;
43import android.util.DisplayMetrics;
44import android.util.Log;
45
46import java.io.File;
47import java.io.InputStream;
48
49public class PackageManagerTests extends AndroidTestCase {
50    private static final boolean localLOGV = true;
51    public static final String TAG="PackageManagerTests";
52    public final long MAX_WAIT_TIME = 25*1000;
53    public final long WAIT_TIME_INCR = 5*1000;
54    private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
55    private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
56    private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
57    private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
58    private boolean mOrigState;
59
60    void failStr(String errMsg) {
61        Log.w(TAG, "errMsg="+errMsg);
62        fail(errMsg);
63    }
64    void failStr(Exception e) {
65        failStr(e.getMessage());
66    }
67
68    @Override
69    protected void setUp() throws Exception {
70        super.setUp();
71        mOrigState = getMediaState();
72        if (!mountMedia()) {
73            Log.i(TAG, "sdcard not mounted? Some of these tests might fail");
74        }
75    }
76
77    @Override
78    protected void tearDown() throws Exception {
79        // Restore media state.
80        boolean newState = getMediaState();
81        if (newState != mOrigState) {
82            if (mOrigState) {
83                getMs().mountVolume(Environment.getExternalStorageDirectory().getPath());
84            } else {
85                getMs().unmountVolume(Environment.getExternalStorageDirectory().getPath(), true);
86            }
87        }
88        super.tearDown();
89    }
90
91    private class PackageInstallObserver extends IPackageInstallObserver.Stub {
92        public int returnCode;
93        private boolean doneFlag = false;
94
95        public void packageInstalled(String packageName, int returnCode) {
96            synchronized(this) {
97                this.returnCode = returnCode;
98                doneFlag = true;
99                notifyAll();
100            }
101        }
102
103        public boolean isDone() {
104            return doneFlag;
105        }
106    }
107
108    abstract class GenericReceiver extends BroadcastReceiver {
109        private boolean doneFlag = false;
110        boolean received = false;
111        Intent intent;
112        IntentFilter filter;
113        abstract boolean notifyNow(Intent intent);
114        @Override
115        public void onReceive(Context context, Intent intent) {
116            if (notifyNow(intent)) {
117                synchronized (this) {
118                    received = true;
119                    doneFlag = true;
120                    this.intent = intent;
121                    notifyAll();
122                }
123            }
124        }
125
126        public boolean isDone() {
127            return doneFlag;
128        }
129
130        public void setFilter(IntentFilter filter) {
131            this.filter = filter;
132        }
133    }
134
135    class InstallReceiver extends GenericReceiver {
136        String pkgName;
137
138        InstallReceiver(String pkgName) {
139            this.pkgName = pkgName;
140            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
141            filter.addDataScheme("package");
142            super.setFilter(filter);
143        }
144
145        public boolean notifyNow(Intent intent) {
146            String action = intent.getAction();
147            if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) {
148                return false;
149            }
150            Uri data = intent.getData();
151            String installedPkg = data.getEncodedSchemeSpecificPart();
152            if (pkgName.equals(installedPkg)) {
153                return true;
154            }
155            return false;
156        }
157    }
158
159    PackageManager getPm() {
160        return mContext.getPackageManager();
161    }
162
163    public boolean invokeInstallPackage(Uri packageURI, int flags,
164            final String pkgName, GenericReceiver receiver) throws Exception {
165        PackageInstallObserver observer = new PackageInstallObserver();
166        final boolean received = false;
167        mContext.registerReceiver(receiver, receiver.filter);
168        final boolean DEBUG = true;
169        try {
170            // Wait on observer
171            synchronized(observer) {
172                synchronized (receiver) {
173                    getPm().installPackage(packageURI, observer, flags, null);
174                    long waitTime = 0;
175                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
176                        observer.wait(WAIT_TIME_INCR);
177                        waitTime += WAIT_TIME_INCR;
178                    }
179                    if(!observer.isDone()) {
180                        throw new Exception("Timed out waiting for packageInstalled callback");
181                    }
182                    if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) {
183                        Log.i(TAG, "Failed to install with error code = " + observer.returnCode);
184                        return false;
185                    }
186                    // Verify we received the broadcast
187                    waitTime = 0;
188                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
189                        receiver.wait(WAIT_TIME_INCR);
190                        waitTime += WAIT_TIME_INCR;
191                    }
192                    if(!receiver.isDone()) {
193                        throw new Exception("Timed out waiting for PACKAGE_ADDED notification");
194                    }
195                    return receiver.received;
196                }
197            }
198        } finally {
199            mContext.unregisterReceiver(receiver);
200        }
201    }
202
203    public boolean invokeInstallPackageFail(Uri packageURI, int flags,
204            final String pkgName, int result) throws Exception {
205        PackageInstallObserver observer = new PackageInstallObserver();
206        try {
207            // Wait on observer
208            synchronized(observer) {
209                getPm().installPackage(packageURI, observer, flags, null);
210                long waitTime = 0;
211                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
212                    observer.wait(WAIT_TIME_INCR);
213                    waitTime += WAIT_TIME_INCR;
214                }
215                if(!observer.isDone()) {
216                    throw new Exception("Timed out waiting for packageInstalled callback");
217                }
218                return (observer.returnCode == result);
219            }
220        } finally {
221        }
222    }
223
224    Uri getInstallablePackage(int fileResId, File outFile) {
225        Resources res = mContext.getResources();
226        InputStream is = null;
227        try {
228            is = res.openRawResource(fileResId);
229        } catch (NotFoundException e) {
230            failStr("Failed to load resource with id: " + fileResId);
231        }
232        FileUtils.setPermissions(outFile.getPath(),
233                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
234                -1, -1);
235        assertTrue(FileUtils.copyToFile(is, outFile));
236        FileUtils.setPermissions(outFile.getPath(),
237                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
238                -1, -1);
239        return Uri.fromFile(outFile);
240    }
241
242    private PackageParser.Package parsePackage(Uri packageURI) {
243        final String archiveFilePath = packageURI.getPath();
244        PackageParser packageParser = new PackageParser(archiveFilePath);
245        File sourceFile = new File(archiveFilePath);
246        DisplayMetrics metrics = new DisplayMetrics();
247        metrics.setToDefaults();
248        PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
249        packageParser = null;
250        return pkg;
251    }
252    private boolean checkSd(long pkgLen) {
253        String status = Environment.getExternalStorageState();
254        if (!status.equals(Environment.MEDIA_MOUNTED)) {
255            return false;
256        }
257        long sdSize = -1;
258        StatFs sdStats = new StatFs(
259                Environment.getExternalStorageDirectory().getPath());
260        sdSize = (long)sdStats.getAvailableBlocks() *
261                (long)sdStats.getBlockSize();
262        // TODO check for thesholds here
263        return pkgLen <= sdSize;
264
265    }
266    private boolean checkInt(long pkgLen) {
267        StatFs intStats = new StatFs(Environment.getDataDirectory().getPath());
268        long intSize = (long)intStats.getBlockCount() *
269                (long)intStats.getBlockSize();
270        long iSize = (long)intStats.getAvailableBlocks() *
271                (long)intStats.getBlockSize();
272        // TODO check for thresholds here?
273        return pkgLen <= iSize;
274    }
275    private static final int INSTALL_LOC_INT = 1;
276    private static final int INSTALL_LOC_SD = 2;
277    private static final int INSTALL_LOC_ERR = -1;
278    private int checkDefaultPolicy(long pkgLen) {
279        // Check for free memory internally
280        if (checkInt(pkgLen)) {
281            return INSTALL_LOC_INT;
282        }
283        // Check for free memory externally
284        if (checkSd(pkgLen)) {
285            return INSTALL_LOC_SD;
286        }
287        return INSTALL_LOC_ERR;
288    }
289    private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
290        // Flags explicitly over ride everything else.
291        if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) {
292            return INSTALL_LOC_INT;
293        } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) {
294            return INSTALL_LOC_SD;
295        } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
296            return INSTALL_LOC_INT;
297        }
298        // Manifest option takes precedence next
299        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
300            // TODO fitsonSd check
301            if (checkSd(pkgLen)) {
302               return INSTALL_LOC_SD;
303            }
304            if (checkInt(pkgLen)) {
305                return INSTALL_LOC_INT;
306            }
307            return INSTALL_LOC_ERR;
308        }
309        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
310            if (checkInt(pkgLen)) {
311                return INSTALL_LOC_INT;
312            }
313            return INSTALL_LOC_ERR;
314        }
315        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
316            return checkDefaultPolicy(pkgLen);
317        }
318        // Check for settings preference.
319        boolean checkSd = false;
320        int setLoc = 0;
321        try {
322            setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION);
323        } catch (SettingNotFoundException e) {
324            failStr(e);
325        }
326        if (setLoc == 1) {
327            int userPref = APP_INSTALL_AUTO;
328            try {
329                userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
330            } catch (SettingNotFoundException e) {
331                failStr(e);
332            }
333            if (userPref == APP_INSTALL_DEVICE) {
334                if (checkInt(pkgLen)) {
335                    return INSTALL_LOC_INT;
336                }
337                return INSTALL_LOC_ERR;
338            } else if (userPref == APP_INSTALL_SDCARD) {
339                if (checkSd(pkgLen)) {
340                    return INSTALL_LOC_SD;
341                }
342                return INSTALL_LOC_ERR;
343            }
344        }
345        return checkDefaultPolicy(pkgLen);
346    }
347
348    private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
349        try {
350            String pkgName = pkg.packageName;
351            ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
352            assertNotNull(info);
353            assertEquals(pkgName, info.packageName);
354            File dataDir = Environment.getDataDirectory();
355            String appInstallPath = new File(dataDir, "app").getPath();
356            String drmInstallPath = new File(dataDir, "app-private").getPath();
357            File srcDir = new File(info.sourceDir);
358            String srcPath = srcDir.getParent();
359            File publicSrcDir = new File(info.publicSourceDir);
360            String publicSrcPath = publicSrcDir.getParent();
361            long pkgLen = new File(info.sourceDir).length();
362
363            if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
364                assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
365                assertEquals(srcPath, drmInstallPath);
366                assertEquals(publicSrcPath, appInstallPath);
367            } else {
368                assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
369                int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
370                if (rLoc == INSTALL_LOC_INT) {
371                    assertEquals(srcPath, appInstallPath);
372                    assertEquals(publicSrcPath, appInstallPath);
373                    assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
374                } else if (rLoc == INSTALL_LOC_SD){
375                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
376                    assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
377                    assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
378                } else {
379                    // TODO handle error. Install should have failed.
380                }
381            }
382        } catch (NameNotFoundException e) {
383            failStr("failed with exception : " + e);
384        }
385    }
386
387    private void assertNotInstalled(String pkgName) {
388        try {
389            ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
390            fail(pkgName + " shouldnt be installed");
391        } catch (NameNotFoundException e) {
392        }
393    }
394
395    class InstallParams {
396        String outFileName;
397        Uri packageURI;
398        PackageParser.Package pkg;
399        InstallParams(PackageParser.Package pkg, String outFileName, Uri packageURI) {
400            this.outFileName = outFileName;
401            this.packageURI = packageURI;
402            this.pkg = pkg;
403        }
404    }
405
406    private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
407        return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
408                false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
409    }
410
411    static final String PERM_PACKAGE = "package";
412    static final String PERM_DEFINED = "defined";
413    static final String PERM_UNDEFINED = "undefined";
414    static final String PERM_USED = "used";
415    static final String PERM_NOTUSED = "notused";
416
417    private void assertPermissions(String[] cmds) {
418        final PackageManager pm = getPm();
419        String pkg = null;
420        PackageInfo pkgInfo = null;
421        String mode = PERM_DEFINED;
422        int i = 0;
423        while (i < cmds.length) {
424            String cmd = cmds[i++];
425            if (cmd == PERM_PACKAGE) {
426                pkg = cmds[i++];
427                try {
428                    pkgInfo = pm.getPackageInfo(pkg,
429                            PackageManager.GET_PERMISSIONS
430                            | PackageManager.GET_UNINSTALLED_PACKAGES);
431                } catch (NameNotFoundException e) {
432                    pkgInfo = null;
433                }
434            } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED
435                    || cmd == PERM_USED || cmd == PERM_NOTUSED) {
436                mode = cmds[i++];
437            } else {
438                if (mode == PERM_DEFINED) {
439                    try {
440                        PermissionInfo pi = pm.getPermissionInfo(cmd, 0);
441                        assertNotNull(pi);
442                        assertEquals(pi.packageName, pkg);
443                        assertEquals(pi.name, cmd);
444                        assertNotNull(pkgInfo);
445                        boolean found = false;
446                        for (int j=0; j<pkgInfo.permissions.length && !found; j++) {
447                            if (pkgInfo.permissions[j].name.equals(cmd)) {
448                                found = true;
449                            }
450                        }
451                        if (!found) {
452                            fail("Permission not found: " + cmd);
453                        }
454                    } catch (NameNotFoundException e) {
455                        throw new RuntimeException(e);
456                    }
457                } else if (mode == PERM_UNDEFINED) {
458                    try {
459                        pm.getPermissionInfo(cmd, 0);
460                        throw new RuntimeException("Permission exists: " + cmd);
461                    } catch (NameNotFoundException e) {
462                    }
463                    if (pkgInfo != null) {
464                        boolean found = false;
465                        for (int j=0; j<pkgInfo.permissions.length && !found; j++) {
466                            if (pkgInfo.permissions[j].name.equals(cmd)) {
467                                found = true;
468                            }
469                        }
470                        if (found) {
471                            fail("Permission still exists: " + cmd);
472                        }
473                    }
474                } else if (mode == PERM_USED || mode == PERM_NOTUSED) {
475                    boolean found = false;
476                    for (int j=0; j<pkgInfo.requestedPermissions.length && !found; j++) {
477                        if (pkgInfo.requestedPermissions[j].equals(cmd)) {
478                            found = true;
479                        }
480                    }
481                    if (!found) {
482                        fail("Permission not requested: " + cmd);
483                    }
484                    if (mode == PERM_USED) {
485                        if (pm.checkPermission(cmd, pkg)
486                                != PackageManager.PERMISSION_GRANTED) {
487                            fail("Permission not granted: " + cmd);
488                        }
489                    } else {
490                        if (pm.checkPermission(cmd, pkg)
491                                != PackageManager.PERMISSION_DENIED) {
492                            fail("Permission granted: " + cmd);
493                        }
494                    }
495                }
496            }
497        }
498    }
499
500    /*
501     * Utility function that reads a apk bundled as a raw resource
502     * copies it into own data directory and invokes
503     * PackageManager api to install it.
504     */
505    private InstallParams installFromRawResource(String outFileName,
506            int rawResId, int flags, boolean cleanUp, boolean fail, int result,
507            int expInstallLocation) {
508        PackageManager pm = mContext.getPackageManager();
509        File filesDir = mContext.getFilesDir();
510        File outFile = new File(filesDir, outFileName);
511        Uri packageURI = getInstallablePackage(rawResId, outFile);
512        PackageParser.Package pkg = parsePackage(packageURI);
513        assertNotNull(pkg);
514        if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
515            // Make sure the package doesn't exist
516            try {
517                ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
518                        PackageManager.GET_UNINSTALLED_PACKAGES);
519                GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
520                invokeDeletePackage(packageURI, 0,
521                        pkg.packageName, receiver);
522            } catch (NameNotFoundException e1) {
523            } catch (Exception e) {
524                failStr(e);
525            }
526        }
527        InstallParams ip = null;
528        try {
529            if (fail) {
530                assertTrue(invokeInstallPackageFail(packageURI, flags,
531                        pkg.packageName, result));
532                assertNotInstalled(pkg.packageName);
533            } else {
534                InstallReceiver receiver = new InstallReceiver(pkg.packageName);
535                assertTrue(invokeInstallPackage(packageURI, flags,
536                        pkg.packageName, receiver));
537                // Verify installed information
538                assertInstall(pkg, flags, expInstallLocation);
539                ip = new InstallParams(pkg, outFileName, packageURI);
540            }
541            return ip;
542        } catch (Exception e) {
543            failStr("Failed with exception : " + e);
544        } finally {
545            if (cleanUp) {
546                cleanUpInstall(ip);
547            }
548        }
549        return ip;
550    }
551
552    public void testInstallNormalInternal() {
553        sampleInstallFromRawResource(0, true);
554    }
555
556    public void testInstallFwdLockedInternal() {
557        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
558    }
559
560    public void testInstallSdcard() {
561        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
562    }
563
564    /* ------------------------- Test replacing packages --------------*/
565    class ReplaceReceiver extends GenericReceiver {
566        String pkgName;
567        final static int INVALID = -1;
568        final static int REMOVED = 1;
569        final static int ADDED = 2;
570        final static int REPLACED = 3;
571        int removed = INVALID;
572        // for updated system apps only
573        boolean update = false;
574
575        ReplaceReceiver(String pkgName) {
576            this.pkgName = pkgName;
577            filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
578            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
579            if (update) {
580                filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
581            }
582            filter.addDataScheme("package");
583            super.setFilter(filter);
584        }
585
586        public boolean notifyNow(Intent intent) {
587            String action = intent.getAction();
588            Uri data = intent.getData();
589            String installedPkg = data.getEncodedSchemeSpecificPart();
590            if (pkgName == null || !pkgName.equals(installedPkg)) {
591                return false;
592            }
593            if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
594                removed = REMOVED;
595            } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
596                if (removed != REMOVED) {
597                    return false;
598                }
599                boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
600                if (!replacing) {
601                    return false;
602                }
603                removed = ADDED;
604                if (!update) {
605                    return true;
606                }
607            } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
608                if (removed != ADDED) {
609                    return false;
610                }
611                removed = REPLACED;
612                return true;
613            }
614            return false;
615        }
616    }
617
618    /*
619     * Utility function that reads a apk bundled as a raw resource
620     * copies it into own data directory and invokes
621     * PackageManager api to install first and then replace it
622     * again.
623     */
624    public void replaceFromRawResource(int flags) {
625        InstallParams ip = sampleInstallFromRawResource(flags, false);
626        boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
627        Log.i(TAG, "replace=" + replace);
628        GenericReceiver receiver;
629        if (replace) {
630            receiver = new ReplaceReceiver(ip.pkg.packageName);
631            Log.i(TAG, "Creating replaceReceiver");
632        } else {
633            receiver = new InstallReceiver(ip.pkg.packageName);
634        }
635        try {
636            try {
637                assertEquals(invokeInstallPackage(ip.packageURI, flags,
638                        ip.pkg.packageName, receiver), replace);
639                if (replace) {
640                    assertInstall(ip.pkg, flags, ip.pkg.installLocation);
641                }
642            } catch (Exception e) {
643                failStr("Failed with exception : " + e);
644            }
645        } finally {
646            cleanUpInstall(ip);
647        }
648    }
649
650    public void testReplaceFailNormalInternal() {
651        replaceFromRawResource(0);
652    }
653
654    public void testReplaceFailFwdLockedInternal() {
655        replaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
656    }
657
658    public void testReplaceFailSdcard() {
659        replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
660    }
661
662    public void testReplaceNormalInternal() {
663        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
664    }
665
666    public void testReplaceFwdLockedInternal() {
667        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
668                PackageManager.INSTALL_FORWARD_LOCK);
669    }
670
671    public void testReplaceSdcard() {
672        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
673                PackageManager.INSTALL_EXTERNAL);
674    }
675
676    /* -------------- Delete tests ---*/
677    class DeleteObserver extends IPackageDeleteObserver.Stub {
678
679        public boolean succeeded;
680        private boolean doneFlag = false;
681
682        public boolean isDone() {
683            return doneFlag;
684        }
685
686        public void packageDeleted(boolean succeeded) throws RemoteException {
687            synchronized(this) {
688                this.succeeded = succeeded;
689                doneFlag = true;
690                notifyAll();
691            }
692        }
693    }
694
695    class DeleteReceiver extends GenericReceiver {
696        String pkgName;
697
698        DeleteReceiver(String pkgName) {
699            this.pkgName = pkgName;
700            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
701            filter.addDataScheme("package");
702            super.setFilter(filter);
703        }
704
705        public boolean notifyNow(Intent intent) {
706            String action = intent.getAction();
707            if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
708                return false;
709            }
710            Uri data = intent.getData();
711            String installedPkg = data.getEncodedSchemeSpecificPart();
712            if (pkgName.equals(installedPkg)) {
713                return true;
714            }
715            return false;
716        }
717    }
718
719    public boolean invokeDeletePackage(Uri packageURI, int flags,
720            final String pkgName, GenericReceiver receiver) throws Exception {
721        DeleteObserver observer = new DeleteObserver();
722        final boolean received = false;
723        mContext.registerReceiver(receiver, receiver.filter);
724        try {
725            // Wait on observer
726            synchronized(observer) {
727                synchronized (receiver) {
728                    getPm().deletePackage(pkgName, observer, flags);
729                    long waitTime = 0;
730                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
731                        observer.wait(WAIT_TIME_INCR);
732                        waitTime += WAIT_TIME_INCR;
733                    }
734                    if(!observer.isDone()) {
735                        throw new Exception("Timed out waiting for packageInstalled callback");
736                    }
737                    // Verify we received the broadcast
738                    waitTime = 0;
739                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
740                        receiver.wait(WAIT_TIME_INCR);
741                        waitTime += WAIT_TIME_INCR;
742                    }
743                    if(!receiver.isDone()) {
744                        throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
745                    }
746                    return receiver.received;
747                }
748            }
749        } finally {
750            mContext.unregisterReceiver(receiver);
751        }
752    }
753
754    public void deleteFromRawResource(int iFlags, int dFlags) {
755        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
756        boolean retainData = ((dFlags & PackageManager.DONT_DELETE_DATA) != 0);
757        GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
758        DeleteObserver observer = new DeleteObserver();
759        try {
760            assertTrue(invokeDeletePackage(ip.packageURI, dFlags,
761                    ip.pkg.packageName, receiver));
762            ApplicationInfo info = null;
763            Log.i(TAG, "okay4");
764            try {
765            info = getPm().getApplicationInfo(ip.pkg.packageName,
766                    PackageManager.GET_UNINSTALLED_PACKAGES);
767            } catch (NameNotFoundException e) {
768                info = null;
769            }
770            if (retainData) {
771                assertNotNull(info);
772                assertEquals(info.packageName, ip.pkg.packageName);
773                File file = new File(info.dataDir);
774                assertTrue(file.exists());
775            } else {
776                assertNull(info);
777            }
778        } catch (Exception e) {
779            failStr(e);
780        } finally {
781            cleanUpInstall(ip);
782        }
783    }
784
785    public void testDeleteNormalInternal() {
786        deleteFromRawResource(0, 0);
787    }
788
789    public void testDeleteFwdLockedInternal() {
790        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
791    }
792
793    public void testDeleteSdcard() {
794        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
795    }
796
797    public void testDeleteNormalInternalRetainData() {
798        deleteFromRawResource(0, PackageManager.DONT_DELETE_DATA);
799    }
800
801    public void testDeleteFwdLockedInternalRetainData() {
802        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DONT_DELETE_DATA);
803    }
804
805    public void testDeleteSdcardRetainData() {
806        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
807    }
808
809    /* sdcard mount/unmount tests ******/
810
811    class SdMountReceiver extends GenericReceiver {
812        String pkgNames[];
813        boolean status = true;
814
815        SdMountReceiver(String[] pkgNames) {
816            this.pkgNames = pkgNames;
817            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
818            super.setFilter(filter);
819        }
820
821        public boolean notifyNow(Intent intent) {
822            Log.i(TAG, "okay 1");
823            String action = intent.getAction();
824            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
825                return false;
826            }
827            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
828            for (String pkg : pkgNames) {
829                boolean found = false;
830                for (String rpkg : rpkgList) {
831                    if (rpkg.equals(pkg)) {
832                        found = true;
833                        break;
834                    }
835                }
836                if (!found) {
837                    status = false;
838                    return true;
839                }
840            }
841            return true;
842        }
843    }
844
845    class SdUnMountReceiver extends GenericReceiver {
846        String pkgNames[];
847        boolean status = true;
848
849        SdUnMountReceiver(String[] pkgNames) {
850            this.pkgNames = pkgNames;
851            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
852            super.setFilter(filter);
853        }
854
855        public boolean notifyNow(Intent intent) {
856            String action = intent.getAction();
857            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
858                return false;
859            }
860            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
861            for (String pkg : pkgNames) {
862                boolean found = false;
863                for (String rpkg : rpkgList) {
864                    if (rpkg.equals(pkg)) {
865                        found = true;
866                        break;
867                    }
868                }
869                if (!found) {
870                    status = false;
871                    return true;
872                }
873            }
874            return true;
875        }
876    }
877
878    IMountService getMs() {
879        IBinder service = ServiceManager.getService("mount");
880        if (service != null) {
881            return IMountService.Stub.asInterface(service);
882        } else {
883            Log.e(TAG, "Can't get mount service");
884        }
885        return null;
886    }
887
888    boolean getMediaState() {
889        try {
890        String mPath = Environment.getExternalStorageDirectory().toString();
891        String state = getMs().getVolumeState(mPath);
892        return Environment.MEDIA_MOUNTED.equals(state);
893        } catch (RemoteException e) {
894            return false;
895        }
896    }
897
898    boolean mountMedia() {
899        if (getMediaState()) {
900            return true;
901        }
902        try {
903        String mPath = Environment.getExternalStorageDirectory().toString();
904        int ret = getMs().mountVolume(mPath);
905        return ret == StorageResultCode.OperationSucceeded;
906        } catch (RemoteException e) {
907            return false;
908        }
909    }
910
911
912
913    private boolean unmountMedia() {
914        if (!getMediaState()) {
915            return true;
916        }
917        String path = Environment.getExternalStorageDirectory().toString();
918        StorageListener observer = new StorageListener();
919        StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
920        sm.registerListener(observer);
921        try {
922            // Wait on observer
923            synchronized(observer) {
924                getMs().unmountVolume(path, true);
925                long waitTime = 0;
926                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
927                    observer.wait(WAIT_TIME_INCR);
928                    waitTime += WAIT_TIME_INCR;
929                }
930                if(!observer.isDone()) {
931                    throw new Exception("Timed out waiting for packageInstalled callback");
932                }
933                return true;
934            }
935        } catch (Exception e) {
936            return false;
937        } finally {
938            sm.unregisterListener(observer);
939        }
940    }
941
942    private boolean mountFromRawResource() {
943        // Install pkg on sdcard
944        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
945        if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
946        boolean origState = getMediaState();
947        boolean registeredReceiver = false;
948        SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
949        try {
950            if (localLOGV) Log.i(TAG, "Unmounting media");
951            // Unmount media
952            assertTrue(unmountMedia());
953            if (localLOGV) Log.i(TAG, "Unmounted media");
954            // Register receiver here
955            PackageManager pm = getPm();
956            mContext.registerReceiver(receiver, receiver.filter);
957            registeredReceiver = true;
958
959            // Wait on receiver
960            synchronized (receiver) {
961                if (localLOGV) Log.i(TAG, "Mounting media");
962                // Mount media again
963                assertTrue(mountMedia());
964                if (localLOGV) Log.i(TAG, "Mounted media");
965                if (localLOGV) Log.i(TAG, "Waiting for notification");
966                long waitTime = 0;
967                // Verify we received the broadcast
968                waitTime = 0;
969                while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
970                    receiver.wait(WAIT_TIME_INCR);
971                    waitTime += WAIT_TIME_INCR;
972                }
973                if(!receiver.isDone()) {
974                    failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification");
975                }
976                return receiver.received;
977            }
978        } catch (InterruptedException e) {
979            failStr(e);
980            return false;
981        } finally {
982            if (registeredReceiver) mContext.unregisterReceiver(receiver);
983            // Restore original media state
984            if (origState) {
985                mountMedia();
986            } else {
987                unmountMedia();
988            }
989            if (localLOGV) Log.i(TAG, "Cleaning up install");
990            cleanUpInstall(ip);
991        }
992    }
993
994    /*
995     * Install package on sdcard. Unmount and then mount the media.
996     * (Use PackageManagerService private api for now)
997     * Make sure the installed package is available.
998     * STOPSHIP will uncomment when MountService api's to mount/unmount
999     * are made asynchronous.
1000     */
1001    public void xxxtestMountSdNormalInternal() {
1002        assertTrue(mountFromRawResource());
1003    }
1004
1005    void cleanUpInstall(InstallParams ip) {
1006        if (ip == null) {
1007            return;
1008        }
1009        Runtime.getRuntime().gc();
1010        Log.i(TAG, "Deleting package : " + ip.pkg.packageName);
1011        getPm().deletePackage(ip.pkg.packageName, null, 0);
1012        File outFile = new File(ip.outFileName);
1013        if (outFile != null && outFile.exists()) {
1014            outFile.delete();
1015        }
1016    }
1017
1018    public void testManifestInstallLocationInternal() {
1019        installFromRawResource("install.apk", R.raw.install_loc_internal,
1020                0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1021    }
1022
1023    public void testManifestInstallLocationSdcard() {
1024        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1025                0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1026    }
1027
1028    public void testManifestInstallLocationAuto() {
1029        installFromRawResource("install.apk", R.raw.install_loc_auto,
1030                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
1031    }
1032
1033    public void testManifestInstallLocationUnspecified() {
1034        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1035                0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1036    }
1037
1038    public void testManifestInstallLocationFwdLockedFlagSdcard() {
1039        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1040                PackageManager.INSTALL_FORWARD_LOCK |
1041                PackageManager.INSTALL_EXTERNAL, true, true,
1042                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1043                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1044    }
1045
1046    public void testManifestInstallLocationFwdLockedSdcard() {
1047        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1048                PackageManager.INSTALL_FORWARD_LOCK, true, false,
1049                -1,
1050                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1051    }
1052
1053    /*
1054     * Install a package on internal flash via PackageManager install flag. Replace
1055     * the package via flag to install on sdcard. Make sure the new flag overrides
1056     * the old install location.
1057     */
1058    public void testReplaceFlagInternalSdcard() {
1059        int iFlags = 0;
1060        int rFlags = PackageManager.INSTALL_EXTERNAL;
1061        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1062        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1063        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1064        try {
1065            assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
1066                    ip.pkg.packageName, receiver), true);
1067            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
1068        } catch (Exception e) {
1069            failStr("Failed with exception : " + e);
1070        } finally {
1071            cleanUpInstall(ip);
1072        }
1073    }
1074
1075    /*
1076     * Install a package on sdcard via PackageManager install flag. Replace
1077     * the package with no flags or manifest option and make sure the old
1078     * install location is retained.
1079     */
1080    public void testReplaceFlagSdcardInternal() {
1081        int iFlags = PackageManager.INSTALL_EXTERNAL;
1082        int rFlags = 0;
1083        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1084        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1085        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1086        try {
1087            assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
1088                    ip.pkg.packageName, receiver), true);
1089            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1090        } catch (Exception e) {
1091            failStr("Failed with exception : " + e);
1092        } finally {
1093            cleanUpInstall(ip);
1094        }
1095    }
1096
1097    public void testManifestInstallLocationReplaceInternalSdcard() {
1098        int iFlags = 0;
1099        int iApk = R.raw.install_loc_internal;
1100        int rFlags = 0;
1101        int rApk = R.raw.install_loc_sdcard;
1102        InstallParams ip = installFromRawResource("install.apk", iApk,
1103                iFlags, false,
1104                false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1105        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1106        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1107        try {
1108            InstallParams rp = installFromRawResource("install.apk", rApk,
1109                    replaceFlags, false,
1110                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1111            assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1112        } catch (Exception e) {
1113            failStr("Failed with exception : " + e);
1114        } finally {
1115            cleanUpInstall(ip);
1116        }
1117    }
1118
1119    public void testManifestInstallLocationReplaceSdcardInternal() {
1120        int iFlags = 0;
1121        int iApk = R.raw.install_loc_sdcard;
1122        int rFlags = 0;
1123        int rApk = R.raw.install_loc_unspecified;
1124        InstallParams ip = installFromRawResource("install.apk", iApk,
1125                iFlags, false,
1126                false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1127        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1128        try {
1129            InstallParams rp = installFromRawResource("install.apk", rApk,
1130                    replaceFlags, false,
1131                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1132            assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1133        } catch (Exception e) {
1134            failStr("Failed with exception : " + e);
1135        } finally {
1136            cleanUpInstall(ip);
1137        }
1138    }
1139
1140    class MoveReceiver extends GenericReceiver {
1141        String pkgName;
1142        final static int INVALID = -1;
1143        final static int REMOVED = 1;
1144        final static int ADDED = 2;
1145        int removed = INVALID;
1146
1147        MoveReceiver(String pkgName) {
1148            this.pkgName = pkgName;
1149            filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1150            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1151            super.setFilter(filter);
1152        }
1153
1154        public boolean notifyNow(Intent intent) {
1155            String action = intent.getAction();
1156            Log.i(TAG, "MoveReceiver::" + action);
1157            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1158                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1159                if (list != null) {
1160                    for (String pkg : list) {
1161                        if (pkg.equals(pkgName)) {
1162                            removed = REMOVED;
1163                            break;
1164                        }
1165                    }
1166                }
1167                removed = REMOVED;
1168            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1169                if (removed != REMOVED) {
1170                    return false;
1171                }
1172                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1173                if (list != null) {
1174                    for (String pkg : list) {
1175                        if (pkg.equals(pkgName)) {
1176                            removed = ADDED;
1177                            return true;
1178                        }
1179                    }
1180                }
1181            }
1182            return false;
1183        }
1184    }
1185
1186    private class PackageMoveObserver extends IPackageMoveObserver.Stub {
1187        public int returnCode;
1188        private boolean doneFlag = false;
1189
1190        public void packageMoved(String packageName, int returnCode) {
1191            synchronized(this) {
1192                this.returnCode = returnCode;
1193                doneFlag = true;
1194                notifyAll();
1195            }
1196        }
1197
1198        public boolean isDone() {
1199            return doneFlag;
1200        }
1201    }
1202
1203    public boolean invokeMovePackage(String pkgName, int flags,
1204            GenericReceiver receiver) throws Exception {
1205        PackageMoveObserver observer = new PackageMoveObserver();
1206        final boolean received = false;
1207        mContext.registerReceiver(receiver, receiver.filter);
1208        try {
1209            // Wait on observer
1210            synchronized(observer) {
1211                synchronized (receiver) {
1212                    getPm().movePackage(pkgName, observer, flags);
1213                    long waitTime = 0;
1214                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
1215                        observer.wait(WAIT_TIME_INCR);
1216                        waitTime += WAIT_TIME_INCR;
1217                    }
1218                    if(!observer.isDone()) {
1219                        throw new Exception("Timed out waiting for pkgmove callback");
1220                    }
1221                    if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) {
1222                        return false;
1223                    }
1224                    // Verify we received the broadcast
1225                    waitTime = 0;
1226                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
1227                        receiver.wait(WAIT_TIME_INCR);
1228                        waitTime += WAIT_TIME_INCR;
1229                    }
1230                    if(!receiver.isDone()) {
1231                        throw new Exception("Timed out waiting for MOVE notifications");
1232                    }
1233                    return receiver.received;
1234                }
1235            }
1236        } finally {
1237            mContext.unregisterReceiver(receiver);
1238        }
1239    }
1240
1241    private int getInstallLoc() {
1242        boolean userSetting = false;
1243        int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1244        try {
1245            userSetting = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
1246            origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
1247        } catch (SettingNotFoundException e1) {
1248        }
1249        return origDefaultLoc;
1250    }
1251
1252    private void setInstallLoc(int loc) {
1253        Settings.System.putInt(mContext.getContentResolver(),
1254                Settings.System.DEFAULT_INSTALL_LOCATION, loc);
1255    }
1256    /*
1257     * Utility function that reads a apk bundled as a raw resource
1258     * copies it into own data directory and invokes
1259     * PackageManager api to install first and then replace it
1260     * again.
1261     */
1262    public void moveFromRawResource(int installFlags, int moveFlags,
1263            int expRetCode) {
1264        int origDefaultLoc = getInstallLoc();
1265        setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1266        // Install first
1267        InstallParams ip = sampleInstallFromRawResource(installFlags, false);
1268        ApplicationInfo oldAppInfo = null;
1269        try {
1270            oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1271        } catch (NameNotFoundException e) {
1272            failStr("Pkg hasnt been installed correctly");
1273        }
1274
1275        // Create receiver based on expRetCode
1276        MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1277        try {
1278            boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
1279                    receiver);
1280            if (expRetCode == PackageManager.MOVE_SUCCEEDED) {
1281                assertTrue(retCode);
1282                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1283                assertNotNull(info);
1284                if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1285                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1286                } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
1287                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1288                }
1289            } else {
1290                assertFalse(retCode);
1291                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1292                assertNotNull(info);
1293                assertEquals(oldAppInfo.flags, info.flags);
1294            }
1295        } catch (Exception e) {
1296            failStr("Failed with exception : " + e);
1297        } finally {
1298            cleanUpInstall(ip);
1299            // Restore default install location
1300            setInstallLoc(origDefaultLoc);
1301        }
1302    }
1303
1304    public void testMoveAppInternalToExternal() {
1305        moveFromRawResource(0, PackageManager.MOVE_EXTERNAL_MEDIA,
1306                PackageManager.MOVE_SUCCEEDED);
1307    }
1308
1309    public void testMoveAppInternalToInternal() {
1310        moveFromRawResource(0, PackageManager.MOVE_INTERNAL,
1311                PackageManager.MOVE_FAILED_INVALID_LOCATION);
1312    }
1313
1314    public void testMoveAppExternalToExternal() {
1315        moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_EXTERNAL_MEDIA,
1316                PackageManager.MOVE_FAILED_INVALID_LOCATION);
1317    }
1318    public void testMoveAppExternalToInternal() {
1319        moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL,
1320                PackageManager.MOVE_SUCCEEDED);
1321    }
1322
1323    /*
1324     * Test that an install error code is returned when media is unmounted
1325     * and package installed on sdcard via package manager flag.
1326     */
1327    public void testInstallSdcardUnmount() {
1328        boolean origState = getMediaState();
1329        try {
1330            // Unmount sdcard
1331            assertTrue(unmountMedia());
1332            // Try to install and make sure an error code is returned.
1333            assertNull(installFromRawResource("install.apk", R.raw.install,
1334                    PackageManager.INSTALL_EXTERNAL, false,
1335                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1336                    PackageInfo.INSTALL_LOCATION_AUTO));
1337        } finally {
1338            // Restore original media state
1339            if (origState) {
1340                mountMedia();
1341            } else {
1342                unmountMedia();
1343            }
1344        }
1345    }
1346
1347    /*
1348    * Unmount sdcard. Try installing an app with manifest option to install
1349    * on sdcard. Make sure it gets installed on internal flash.
1350    */
1351   public void testInstallManifestSdcardUnmount() {
1352       boolean origState = getMediaState();
1353       try {
1354           // Unmount sdcard
1355           assertTrue(unmountMedia());
1356           // Try to install and make sure an error code is returned.
1357           assertNotNull(installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1358                   0, false,
1359                   false, -1,
1360                   PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY));
1361       } finally {
1362           // Restore original media state
1363           if (origState) {
1364               mountMedia();
1365           } else {
1366               unmountMedia();
1367           }
1368       }
1369   }
1370
1371   /*---------- Recommended install location tests ----*/
1372   /* Precedence: FlagManifestExistingUser
1373    * PrecedenceSuffixes:
1374    * Flag : FlagI, FlagE, FlagF
1375    * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1376    * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1377    * Existing: Existing suffix absent if not existing.
1378    * User: UserI, UserE, UserA, User suffix absent if not existing.
1379    *
1380    */
1381   /*
1382    * Install an app on internal flash
1383    */
1384   public void testFlagI() {
1385       sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1386   }
1387   /*
1388    * Install an app on sdcard.
1389    */
1390   public void testFlagE() {
1391       sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1392   }
1393
1394   /*
1395    * Install an app on sdcard.
1396    */
1397   public void testFlagF() {
1398       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1399   }
1400   /*
1401    * Install an app with both internal and external flags set. should fail
1402    */
1403   public void testFlagIE() {
1404       installFromRawResource("install.apk", R.raw.install,
1405               PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1406               false,
1407               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1408               PackageInfo.INSTALL_LOCATION_AUTO);
1409   }
1410
1411   /*
1412    * Install an app with both internal and external flags set. should fail
1413    */
1414   public void testFlagIF() {
1415       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
1416               PackageManager.INSTALL_INTERNAL, true);
1417   }
1418   /*
1419    * Install an app with both internal and external flags set. should fail
1420    */
1421   public void testFlagEF() {
1422       installFromRawResource("install.apk", R.raw.install,
1423               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
1424               false,
1425               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1426               PackageInfo.INSTALL_LOCATION_AUTO);
1427   }
1428   /*
1429    * Install an app with both internal and external flags set. should fail
1430    */
1431   public void testFlagIEF() {
1432       installFromRawResource("install.apk", R.raw.install,
1433               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1434               PackageManager.INSTALL_EXTERNAL,
1435               false,
1436               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1437               PackageInfo.INSTALL_LOCATION_AUTO);
1438   }
1439   /*
1440    * Install an app with both internal and manifest option set.
1441    * should install on internal.
1442    */
1443   public void testFlagIManifestI() {
1444       installFromRawResource("install.apk", R.raw.install_loc_internal,
1445               PackageManager.INSTALL_INTERNAL,
1446               true,
1447               false, -1,
1448               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1449   }
1450   /*
1451    * Install an app with both internal and manifest preference for
1452    * preferExternal. Should install on internal.
1453    */
1454   public void testFlagIManifestE() {
1455       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1456               PackageManager.INSTALL_INTERNAL,
1457               true,
1458               false, -1,
1459               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1460   }
1461   /*
1462    * Install an app with both internal and manifest preference for
1463    * auto. should install internal.
1464    */
1465   public void testFlagIManifestA() {
1466       installFromRawResource("install.apk", R.raw.install_loc_auto,
1467               PackageManager.INSTALL_INTERNAL,
1468               true,
1469               false, -1,
1470               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1471   }
1472   /*
1473    * Install an app with both external and manifest option set.
1474    * should install externally.
1475    */
1476   public void testFlagEManifestI() {
1477       installFromRawResource("install.apk", R.raw.install_loc_internal,
1478               PackageManager.INSTALL_EXTERNAL,
1479               true,
1480               false, -1,
1481               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1482   }
1483   /*
1484    * Install an app with both external and manifest preference for
1485    * preferExternal. Should install externally.
1486    */
1487   public void testFlagEManifestE() {
1488       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1489               PackageManager.INSTALL_EXTERNAL,
1490               true,
1491               false, -1,
1492               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1493   }
1494   /*
1495    * Install an app with both external and manifest preference for
1496    * auto. should install on external media.
1497    */
1498   public void testFlagEManifestA() {
1499       installFromRawResource("install.apk", R.raw.install_loc_auto,
1500               PackageManager.INSTALL_EXTERNAL,
1501               true,
1502               false, -1,
1503               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1504   }
1505   /*
1506    * Install an app with fwd locked flag set and install location set to
1507    * internal. should install internally.
1508    */
1509   public void testFlagFManifestI() {
1510       installFromRawResource("install.apk", R.raw.install_loc_internal,
1511               PackageManager.INSTALL_EXTERNAL,
1512               true,
1513               false, -1,
1514               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1515   }
1516   /*
1517    * Install an app with fwd locked flag set and install location set to
1518    * preferExternal. should install internally.
1519    */
1520   public void testFlagFManifestE() {
1521       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1522               PackageManager.INSTALL_EXTERNAL,
1523               true,
1524               false, -1,
1525               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1526   }
1527   /*
1528    * Install an app with fwd locked flag set and install location set to
1529    * auto. should install internally.
1530    */
1531   public void testFlagFManifestA() {
1532       installFromRawResource("install.apk", R.raw.install_loc_auto,
1533               PackageManager.INSTALL_EXTERNAL,
1534               true,
1535               false, -1,
1536               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1537   }
1538   /* The following test functions verify install location for existing apps.
1539    * ie existing app can be installed internally or externally. If install
1540    * flag is explicitly set it should override current location. If manifest location
1541    * is set, that should over ride current location too. if not the existing install
1542    * location should be honoured.
1543    * testFlagI/E/F/ExistingI/E -
1544    */
1545   public void testFlagIExistingI() {
1546       int iFlags = PackageManager.INSTALL_INTERNAL;
1547       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1548       // First install.
1549       installFromRawResource("install.apk", R.raw.install,
1550               iFlags,
1551               false,
1552               false, -1,
1553               -1);
1554       // Replace now
1555       installFromRawResource("install.apk", R.raw.install,
1556               rFlags,
1557               true,
1558               false, -1,
1559               -1);
1560   }
1561   public void testFlagIExistingE() {
1562       int iFlags = PackageManager.INSTALL_EXTERNAL;
1563       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1564       // First install.
1565       installFromRawResource("install.apk", R.raw.install,
1566               iFlags,
1567               false,
1568               false, -1,
1569               -1);
1570       // Replace now
1571       installFromRawResource("install.apk", R.raw.install,
1572               rFlags,
1573               true,
1574               false, -1,
1575               -1);
1576   }
1577   public void testFlagEExistingI() {
1578       int iFlags = PackageManager.INSTALL_INTERNAL;
1579       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1580       // First install.
1581       installFromRawResource("install.apk", R.raw.install,
1582               iFlags,
1583               false,
1584               false, -1,
1585               -1);
1586       // Replace now
1587       installFromRawResource("install.apk", R.raw.install,
1588               rFlags,
1589               true,
1590               false, -1,
1591               -1);
1592   }
1593   public void testFlagEExistingE() {
1594       int iFlags = PackageManager.INSTALL_EXTERNAL;
1595       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1596       // First install.
1597       installFromRawResource("install.apk", R.raw.install,
1598               iFlags,
1599               false,
1600               false, -1,
1601               -1);
1602       // Replace now
1603       installFromRawResource("install.apk", R.raw.install,
1604               rFlags,
1605               true,
1606               false, -1,
1607               -1);
1608   }
1609   public void testFlagFExistingI() {
1610       int iFlags = PackageManager.INSTALL_INTERNAL;
1611       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
1612       // First install.
1613       installFromRawResource("install.apk", R.raw.install,
1614               iFlags,
1615               false,
1616               false, -1,
1617               -1);
1618       // Replace now
1619       installFromRawResource("install.apk", R.raw.install,
1620               rFlags,
1621               true,
1622               false, -1,
1623               -1);
1624   }
1625   public void testFlagFExistingE() {
1626       int iFlags = PackageManager.INSTALL_EXTERNAL;
1627       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
1628       // First install.
1629       installFromRawResource("install.apk", R.raw.install,
1630               iFlags,
1631               false,
1632               false, -1,
1633               -1);
1634       // Replace now
1635       installFromRawResource("install.apk", R.raw.install,
1636               rFlags,
1637               true,
1638               false, -1,
1639               -1);
1640   }
1641   /*
1642    * The following set of tests verify the installation of apps with
1643    * install location attribute set to internalOnly, preferExternal and auto.
1644    * The manifest option should dictate the install location.
1645    * public void testManifestI/E/A
1646    * TODO out of memory fall back behaviour.
1647    */
1648   public void testManifestI() {
1649       installFromRawResource("install.apk", R.raw.install_loc_internal,
1650               0,
1651               true,
1652               false, -1,
1653               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1654   }
1655   public void testManifestE() {
1656       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1657               0,
1658               true,
1659               false, -1,
1660               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1661   }
1662   public void testManifestA() {
1663       installFromRawResource("install.apk", R.raw.install_loc_auto,
1664               0,
1665               true,
1666               false, -1,
1667               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1668   }
1669   /*
1670    * The following set of tests verify the installation of apps
1671    * with install location attribute set to internalOnly, preferExternal and auto
1672    * for already existing apps. The manifest option should take precedence.
1673    * TODO add out of memory fall back behaviour.
1674    * testManifestI/E/AExistingI/E
1675    */
1676   public void testManifestIExistingI() {
1677       int iFlags = PackageManager.INSTALL_INTERNAL;
1678       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1679       // First install.
1680       installFromRawResource("install.apk", R.raw.install,
1681               iFlags,
1682               false,
1683               false, -1,
1684               -1);
1685       // Replace now
1686       installFromRawResource("install.apk", R.raw.install_loc_internal,
1687               rFlags,
1688               true,
1689               false, -1,
1690               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1691   }
1692   public void testManifestIExistingE() {
1693       int iFlags = PackageManager.INSTALL_EXTERNAL;
1694       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1695       // First install.
1696       installFromRawResource("install.apk", R.raw.install,
1697               iFlags,
1698               false,
1699               false, -1,
1700               -1);
1701       // Replace now
1702       installFromRawResource("install.apk", R.raw.install_loc_internal,
1703               rFlags,
1704               true,
1705               false, -1,
1706               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1707   }
1708   public void testManifestEExistingI() {
1709       int iFlags = PackageManager.INSTALL_INTERNAL;
1710       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1711       // First install.
1712       installFromRawResource("install.apk", R.raw.install,
1713               iFlags,
1714               false,
1715               false, -1,
1716               -1);
1717       // Replace now
1718       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1719               rFlags,
1720               true,
1721               false, -1,
1722               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1723   }
1724   public void testManifestEExistingE() {
1725       int iFlags = PackageManager.INSTALL_EXTERNAL;
1726       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1727       // First install.
1728       installFromRawResource("install.apk", R.raw.install,
1729               iFlags,
1730               false,
1731               false, -1,
1732               -1);
1733       // Replace now
1734       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1735               rFlags,
1736               true,
1737               false, -1,
1738               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1739   }
1740   public void testManifestAExistingI() {
1741       int iFlags = PackageManager.INSTALL_INTERNAL;
1742       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1743       // First install.
1744       installFromRawResource("install.apk", R.raw.install,
1745               iFlags,
1746               false,
1747               false, -1,
1748               -1);
1749       // Replace now
1750       installFromRawResource("install.apk", R.raw.install_loc_auto,
1751               rFlags,
1752               true,
1753               false, -1,
1754               PackageInfo.INSTALL_LOCATION_AUTO);
1755   }
1756   public void testManifestAExistingE() {
1757       int iFlags = PackageManager.INSTALL_EXTERNAL;
1758       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1759       // First install.
1760       installFromRawResource("install.apk", R.raw.install,
1761               iFlags,
1762               false,
1763               false, -1,
1764               -1);
1765       // Replace now
1766       installFromRawResource("install.apk", R.raw.install_loc_auto,
1767               rFlags,
1768               true,
1769               false, -1,
1770               PackageInfo.INSTALL_LOCATION_AUTO);
1771   }
1772   /*
1773    * The following set of tests check install location for existing
1774    * application based on user setting.
1775    */
1776   private int getExpectedInstallLocation(int userSetting) {
1777       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1778       boolean enable = getUserSettingSetInstallLocation();
1779       if (enable) {
1780           if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
1781               iloc = PackageInfo.INSTALL_LOCATION_AUTO;
1782           } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
1783               iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
1784           } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
1785               iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
1786           }
1787       }
1788       return iloc;
1789   }
1790   private void setExistingXUserX(int userSetting, int iFlags, int iloc) {
1791       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1792       // First install.
1793       installFromRawResource("install.apk", R.raw.install,
1794               iFlags,
1795               false,
1796               false, -1,
1797               PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1798       int origSetting = getInstallLoc();
1799       try {
1800           // Set user setting
1801           setInstallLoc(userSetting);
1802           // Replace now
1803           installFromRawResource("install.apk", R.raw.install,
1804                   rFlags,
1805                   true,
1806                   false, -1,
1807                   iloc);
1808       } finally {
1809           setInstallLoc(origSetting);
1810       }
1811   }
1812   public void testExistingIUserI() {
1813       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1814       int iFlags = PackageManager.INSTALL_INTERNAL;
1815       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1816   }
1817   public void testExistingIUserE() {
1818       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1819       int iFlags = PackageManager.INSTALL_INTERNAL;
1820       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1821   }
1822   public void testExistingIUserA() {
1823       int userSetting = PackageHelper.APP_INSTALL_AUTO;
1824       int iFlags = PackageManager.INSTALL_INTERNAL;
1825       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1826   }
1827   public void testExistingEUserI() {
1828       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1829       int iFlags = PackageManager.INSTALL_EXTERNAL;
1830       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1831   }
1832   public void testExistingEUserE() {
1833       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1834       int iFlags = PackageManager.INSTALL_EXTERNAL;
1835       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1836   }
1837   public void testExistingEUserA() {
1838       int userSetting = PackageHelper.APP_INSTALL_AUTO;
1839       int iFlags = PackageManager.INSTALL_EXTERNAL;
1840       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1841   }
1842   /*
1843    * The following set of tests verify that the user setting defines
1844    * the install location.
1845    *
1846    */
1847   private boolean getUserSettingSetInstallLocation() {
1848       try {
1849           return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
1850
1851       } catch (SettingNotFoundException e1) {
1852       }
1853       return false;
1854   }
1855
1856   private void setUserSettingSetInstallLocation(boolean value) {
1857       Settings.System.putInt(mContext.getContentResolver(),
1858               Settings.System.SET_INSTALL_LOCATION, value ? 1 : 0);
1859   }
1860   private void setUserX(boolean enable, int userSetting, int iloc) {
1861       boolean origUserSetting = getUserSettingSetInstallLocation();
1862       int origSetting = getInstallLoc();
1863       try {
1864           setUserSettingSetInstallLocation(enable);
1865           // Set user setting
1866           setInstallLoc(userSetting);
1867           // Replace now
1868           installFromRawResource("install.apk", R.raw.install,
1869                   0,
1870                   true,
1871                   false, -1,
1872                   iloc);
1873       } finally {
1874           // Restore original setting
1875           setUserSettingSetInstallLocation(origUserSetting);
1876           setInstallLoc(origSetting);
1877       }
1878   }
1879   public void testUserI() {
1880       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1881       int iloc = getExpectedInstallLocation(userSetting);
1882       setUserX(true, userSetting, iloc);
1883   }
1884   public void testUserE() {
1885       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1886       int iloc = getExpectedInstallLocation(userSetting);
1887       setUserX(true, userSetting, iloc);
1888   }
1889   public void testUserA() {
1890       int userSetting = PackageHelper.APP_INSTALL_AUTO;
1891       int iloc = getExpectedInstallLocation(userSetting);
1892       setUserX(true, userSetting, iloc);
1893   }
1894   /*
1895    * The following set of tests turn on/off the basic
1896    * user setting for turning on install location.
1897    */
1898   public void testUserPrefOffUserI() {
1899       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1900       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1901       setUserX(false, userSetting, iloc);
1902   }
1903   public void testUserPrefOffUserE() {
1904       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1905       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1906       setUserX(false, userSetting, iloc);
1907   }
1908   public void testUserPrefOffA() {
1909       int userSetting = PackageHelper.APP_INSTALL_AUTO;
1910       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1911       setUserX(false, userSetting, iloc);
1912   }
1913
1914    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
1915        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
1916        PERM_DEFINED,
1917        "com.android.unit_tests.NORMAL",
1918        "com.android.unit_tests.DANGEROUS",
1919        "com.android.unit_tests.SIGNATURE",
1920    };
1921
1922    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
1923        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
1924        PERM_UNDEFINED,
1925        "com.android.unit_tests.NORMAL",
1926        "com.android.unit_tests.DANGEROUS",
1927        "com.android.unit_tests.SIGNATURE",
1928    };
1929
1930    static final String BASE_PERMISSIONS_USED[] = new String[] {
1931        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
1932        PERM_USED,
1933        "com.android.unit_tests.NORMAL",
1934        "com.android.unit_tests.DANGEROUS",
1935        "com.android.unit_tests.SIGNATURE",
1936    };
1937
1938    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
1939        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
1940        PERM_NOTUSED,
1941        "com.android.unit_tests.NORMAL",
1942        "com.android.unit_tests.DANGEROUS",
1943        "com.android.unit_tests.SIGNATURE",
1944    };
1945
1946    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
1947        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
1948        PERM_USED,
1949        "com.android.unit_tests.SIGNATURE",
1950        PERM_NOTUSED,
1951        "com.android.unit_tests.NORMAL",
1952        "com.android.unit_tests.DANGEROUS",
1953    };
1954
1955    /*
1956     * Ensure that permissions are properly declared.
1957     */
1958    public void testInstallDeclaresPermissions() {
1959        InstallParams ip = null;
1960        InstallParams ip2 = null;
1961        try {
1962            // **: Upon installing a package, are its declared permissions published?
1963
1964            int iFlags = PackageManager.INSTALL_INTERNAL;
1965            int iApk = R.raw.install_decl_perm;
1966            ip = installFromRawResource("install.apk", iApk,
1967                    iFlags, false,
1968                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1969            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1970            assertPermissions(BASE_PERMISSIONS_DEFINED);
1971
1972            // **: Upon installing package, are its permissions granted?
1973
1974            int i2Flags = PackageManager.INSTALL_INTERNAL;
1975            int i2Apk = R.raw.install_use_perm_good;
1976            ip2 = installFromRawResource("install2.apk", i2Apk,
1977                    i2Flags, false,
1978                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1979            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
1980            assertPermissions(BASE_PERMISSIONS_USED);
1981
1982            // **: Upon removing but not deleting, are permissions retained?
1983
1984            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1985
1986            try {
1987                invokeDeletePackage(ip.packageURI, PackageManager.DONT_DELETE_DATA,
1988                        ip.pkg.packageName, receiver);
1989            } catch (Exception e) {
1990                failStr(e);
1991            }
1992            assertPermissions(BASE_PERMISSIONS_DEFINED);
1993            assertPermissions(BASE_PERMISSIONS_USED);
1994
1995            // **: Upon re-installing, are permissions retained?
1996
1997            ip = installFromRawResource("install.apk", iApk,
1998                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
1999                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2000            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2001            assertPermissions(BASE_PERMISSIONS_DEFINED);
2002            assertPermissions(BASE_PERMISSIONS_USED);
2003
2004            // **: Upon deleting package, are all permissions removed?
2005
2006            try {
2007                invokeDeletePackage(ip.packageURI, 0,
2008                        ip.pkg.packageName, receiver);
2009                ip = null;
2010            } catch (Exception e) {
2011                failStr(e);
2012            }
2013            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2014            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2015
2016            // **: Delete package using permissions; nothing to check here.
2017
2018            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2019            try {
2020                invokeDeletePackage(ip2.packageURI, 0,
2021                        ip2.pkg.packageName, receiver);
2022                ip2 = null;
2023            } catch (Exception e) {
2024                failStr(e);
2025            }
2026
2027            // **: Re-install package using permissions; no permissions can be granted.
2028
2029            ip2 = installFromRawResource("install2.apk", i2Apk,
2030                    i2Flags, false,
2031                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2032            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2033            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2034
2035            // **: Upon installing declaring package, are sig permissions granted
2036            // to other apps (but not other perms)?
2037
2038            ip = installFromRawResource("install.apk", iApk,
2039                    iFlags, false,
2040                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2041            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2042            assertPermissions(BASE_PERMISSIONS_DEFINED);
2043            assertPermissions(BASE_PERMISSIONS_SIGUSED);
2044
2045            // **: Re-install package using permissions; are all permissions granted?
2046
2047            ip2 = installFromRawResource("install2.apk", i2Apk,
2048                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2049                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2050            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2051            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2052
2053            // **: Upon deleting package, are all permissions removed?
2054
2055            try {
2056                invokeDeletePackage(ip.packageURI, 0,
2057                        ip.pkg.packageName, receiver);
2058                ip = null;
2059            } catch (Exception e) {
2060                failStr(e);
2061            }
2062            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2063            assertPermissions(BASE_PERMISSIONS_NOTUSED);
2064
2065            // **: Delete package using permissions; nothing to check here.
2066
2067            try {
2068                invokeDeletePackage(ip2.packageURI, 0,
2069                        ip2.pkg.packageName, receiver);
2070                ip2 = null;
2071            } catch (Exception e) {
2072                failStr(e);
2073            }
2074
2075        } finally {
2076            if (ip2 != null) {
2077                cleanUpInstall(ip2);
2078            }
2079            if (ip != null) {
2080                cleanUpInstall(ip);
2081            }
2082        }
2083    }
2084
2085    /*
2086     * Ensure that permissions are properly declared.
2087     */
2088    public void testInstallOnSdPermissionsUnmount() {
2089        InstallParams ip = null;
2090        boolean origMediaState = getMediaState();
2091        try {
2092            // **: Upon installing a package, are its declared permissions published?
2093            int iFlags = PackageManager.INSTALL_INTERNAL;
2094            int iApk = R.raw.install_decl_perm;
2095            ip = installFromRawResource("install.apk", iApk,
2096                    iFlags, false,
2097                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2098            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2099            assertPermissions(BASE_PERMISSIONS_DEFINED);
2100            // Unmount media here
2101            assertTrue(unmountMedia());
2102            // Mount media again
2103            mountMedia();
2104            //Check permissions now
2105            assertPermissions(BASE_PERMISSIONS_DEFINED);
2106        } finally {
2107            if (ip != null) {
2108                cleanUpInstall(ip);
2109            }
2110        }
2111    }
2112
2113    /* This test creates a stale container via MountService and then installs
2114     * a package and verifies that the stale container is cleaned up and install
2115     * is successful.
2116     * Please note that this test is very closely tied to the framework's
2117     * naming convention for secure containers.
2118     */
2119    public void testInstallSdcardStaleContainer() {
2120        boolean origMediaState = getMediaState();
2121        try {
2122            String outFileName = "install.apk";
2123            int rawResId = R.raw.install;
2124            PackageManager pm = mContext.getPackageManager();
2125            File filesDir = mContext.getFilesDir();
2126            File outFile = new File(filesDir, outFileName);
2127            Uri packageURI = getInstallablePackage(rawResId, outFile);
2128            PackageParser.Package pkg = parsePackage(packageURI);
2129            assertNotNull(pkg);
2130            // Install an app on sdcard.
2131            installFromRawResource(outFileName, rawResId,
2132                    PackageManager.INSTALL_EXTERNAL, false,
2133                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2134            // Unmount sdcard
2135            unmountMedia();
2136            // Delete the app on sdcard to leave a stale container on sdcard.
2137            GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2138            assertTrue(invokeDeletePackage(packageURI, 0, pkg.packageName, receiver));
2139            mountMedia();
2140            // Reinstall the app and make sure it gets installed.
2141            installFromRawResource(outFileName, rawResId,
2142                    PackageManager.INSTALL_EXTERNAL, true,
2143                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2144        } catch (Exception e) {
2145            failStr(e.getMessage());
2146        } finally {
2147            if (origMediaState) {
2148                mountMedia();
2149            } else {
2150                unmountMedia();
2151            }
2152
2153        }
2154    }
2155    /*---------- Recommended install location tests ----*/
2156    /*
2157     * TODO's
2158     * check version numbers for upgrades
2159     * check permissions of installed packages
2160     * how to do tests on updated system apps?
2161     * verify updates to system apps cannot be installed on the sdcard.
2162     */
2163}
2164