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