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