/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.unit_tests;

import com.android.internal.content.PackageHelper;

import android.os.storage.IMountService.Stub;

import android.net.Uri;
import android.os.FileUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageStats;
import android.content.pm.IPackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.DisplayMetrics;
import android.util.Log;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.storage.IMountService;
import android.os.storage.IMountServiceListener;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageResultCode;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StatFs;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;

public class PackageManagerTests extends AndroidTestCase {
    private static final boolean localLOGV = true;
    public static final String TAG="PackageManagerTests";
    public final long MAX_WAIT_TIME = 25*1000;
    public final long WAIT_TIME_INCR = 5*1000;
    private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
    private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
    private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
    private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
    private boolean mOrigState;

    void failStr(String errMsg) {
        Log.w(TAG, "errMsg="+errMsg);
        fail(errMsg);
    }
    void failStr(Exception e) {
        Log.w(TAG, "e.getMessage="+e.getMessage());
        Log.w(TAG, "e="+e);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mOrigState = getMediaState();
    }

    @Override
    protected void tearDown() throws Exception {
        // Restore media state.
        boolean newState = getMediaState();
        if (newState != mOrigState) {
            if (mOrigState) {
                getMs().mountVolume(Environment.getExternalStorageDirectory().getPath());
            } else {
                getMs().unmountVolume(Environment.getExternalStorageDirectory().getPath(), true);
            }
        }
        super.tearDown();
    }

    private class PackageInstallObserver extends IPackageInstallObserver.Stub {
        public int returnCode;
        private boolean doneFlag = false;

        public void packageInstalled(String packageName, int returnCode) {
            synchronized(this) {
                this.returnCode = returnCode;
                doneFlag = true;
                notifyAll();
            }
        }

        public boolean isDone() {
            return doneFlag;
        }
    }

    abstract class GenericReceiver extends BroadcastReceiver {
        private boolean doneFlag = false;
        boolean received = false;
        Intent intent;
        IntentFilter filter;
        abstract boolean notifyNow(Intent intent);
        @Override
        public void onReceive(Context context, Intent intent) {
            if (notifyNow(intent)) {
                synchronized (this) {
                    received = true;
                    doneFlag = true;
                    this.intent = intent;
                    notifyAll();
                }
            }
        }

        public boolean isDone() {
            return doneFlag;
        }

        public void setFilter(IntentFilter filter) {
            this.filter = filter;
        }
    }

    class InstallReceiver extends GenericReceiver {
        String pkgName;

        InstallReceiver(String pkgName) {
            this.pkgName = pkgName;
            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
            filter.addDataScheme("package");
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            String action = intent.getAction();
            if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                return false;
            }
            Uri data = intent.getData();
            String installedPkg = data.getEncodedSchemeSpecificPart();
            if (pkgName.equals(installedPkg)) {
                return true;
            }
            return false;
        }
    }

    PackageManager getPm() {
        return mContext.getPackageManager();
    }

    public boolean invokeInstallPackage(Uri packageURI, int flags,
            final String pkgName, GenericReceiver receiver) throws Exception {
        PackageInstallObserver observer = new PackageInstallObserver();
        final boolean received = false;
        mContext.registerReceiver(receiver, receiver.filter);
        final boolean DEBUG = true;
        try {
            // Wait on observer
            synchronized(observer) {
                synchronized (receiver) {
                    getPm().installPackage(packageURI, observer, flags, null);
                    long waitTime = 0;
                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        observer.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!observer.isDone()) {
                        throw new Exception("Timed out waiting for packageInstalled callback");
                    }
                    if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) {
                        Log.i(TAG, "Failed to install with error code = " + observer.returnCode);
                        return false;
                    }
                    // Verify we received the broadcast
                    waitTime = 0;
                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        receiver.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!receiver.isDone()) {
                        throw new Exception("Timed out waiting for PACKAGE_ADDED notification");
                    }
                    return receiver.received;
                }
            }
        } finally {
            mContext.unregisterReceiver(receiver);
        }
    }

    public boolean invokeInstallPackageFail(Uri packageURI, int flags,
            final String pkgName, int result) throws Exception {
        PackageInstallObserver observer = new PackageInstallObserver();
        try {
            // Wait on observer
            synchronized(observer) {
                getPm().installPackage(packageURI, observer, flags, null);
                long waitTime = 0;
                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                    observer.wait(WAIT_TIME_INCR);
                    waitTime += WAIT_TIME_INCR;
                }
                if(!observer.isDone()) {
                    throw new Exception("Timed out waiting for packageInstalled callback");
                }
                return (observer.returnCode == result);
            }
        } finally {
        }
    }

    Uri getInstallablePackage(int fileResId, File outFile) {
        Resources res = mContext.getResources();
        InputStream is = null;
        try {
            is = res.openRawResource(fileResId);
        } catch (NotFoundException e) {
            failStr("Failed to load resource with id: " + fileResId);
        }
        FileUtils.setPermissions(outFile.getPath(),
                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
                -1, -1);
        assertTrue(FileUtils.copyToFile(is, outFile));
        FileUtils.setPermissions(outFile.getPath(),
                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
                -1, -1);
        return Uri.fromFile(outFile);
    }

    private PackageParser.Package parsePackage(Uri packageURI) {
        final String archiveFilePath = packageURI.getPath();
        PackageParser packageParser = new PackageParser(archiveFilePath);
        File sourceFile = new File(archiveFilePath);
        DisplayMetrics metrics = new DisplayMetrics();
        metrics.setToDefaults();
        PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
        packageParser = null;
        return pkg;
    }
    private boolean checkSd(long pkgLen) {
        String status = Environment.getExternalStorageState();
        if (!status.equals(Environment.MEDIA_MOUNTED)) {
            return false;
        }
        long sdSize = -1;
        StatFs sdStats = new StatFs(
                Environment.getExternalStorageDirectory().getPath());
        sdSize = (long)sdStats.getAvailableBlocks() *
                (long)sdStats.getBlockSize();
        // TODO check for thesholds here
        return pkgLen <= sdSize;
        
    }
    private boolean checkInt(long pkgLen) {
        StatFs intStats = new StatFs(Environment.getDataDirectory().getPath());
        long intSize = (long)intStats.getBlockCount() *
                (long)intStats.getBlockSize();
        long iSize = (long)intStats.getAvailableBlocks() *
                (long)intStats.getBlockSize();
        // TODO check for thresholds here?
        return pkgLen <= iSize;
    }
    private static final int INSTALL_LOC_INT = 1;
    private static final int INSTALL_LOC_SD = 2;
    private static final int INSTALL_LOC_ERR = -1;
    private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
        // Flags explicitly over ride everything else.
        if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) {
            return INSTALL_LOC_INT;
        } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) {
            return INSTALL_LOC_SD;
        } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
            return INSTALL_LOC_INT;
        }
        // Manifest option takes precedence next
        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
            // TODO fitsonSd check
            if (checkSd(pkgLen)) {
               return INSTALL_LOC_SD;
            }
            if (checkInt(pkgLen)) {
                return INSTALL_LOC_INT;
            }
            return INSTALL_LOC_ERR;
        }
        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
            if (checkInt(pkgLen)) {
                return INSTALL_LOC_INT;
            }
            return INSTALL_LOC_ERR;
        }
        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
            // Check for free memory internally
            if (checkInt(pkgLen)) {
                return INSTALL_LOC_INT;
            }
            // Check for free memory externally
            if (checkSd(pkgLen)) {
                return INSTALL_LOC_SD;
            }
            return INSTALL_LOC_ERR;
        }
        // Check for settings preference.
        boolean checkSd = false;
        int setLoc = 0;
        try {
            setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION);
        } catch (SettingNotFoundException e) {
            failStr(e);
        }
        if (setLoc == 1) {
            int userPref = APP_INSTALL_AUTO;
            try {
                userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
            } catch (SettingNotFoundException e) {
                failStr(e);
            }
            if (userPref == APP_INSTALL_DEVICE) {
                if (checkInt(pkgLen)) {
                    return INSTALL_LOC_INT;
                }
                return INSTALL_LOC_ERR;
            } else if (userPref == APP_INSTALL_SDCARD) {
                if (checkSd(pkgLen)) {
                    return INSTALL_LOC_SD;
                }
                return INSTALL_LOC_ERR;
            } else if (userPref == APP_INSTALL_AUTO) {
                if (checkInt(pkgLen)) {
                    return INSTALL_LOC_INT;
                }
                // Check for free memory externally
                if (checkSd(pkgLen)) {
                    return INSTALL_LOC_SD;
                }
                return INSTALL_LOC_ERR;
                
            }
        } 
        return INSTALL_LOC_ERR;
    }
    
    private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
        try {
            String pkgName = pkg.packageName;
            ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
            assertNotNull(info);
            assertEquals(pkgName, info.packageName);
            File dataDir = Environment.getDataDirectory();
            String appInstallPath = new File(dataDir, "app").getPath();
            String drmInstallPath = new File(dataDir, "app-private").getPath();
            File srcDir = new File(info.sourceDir);
            String srcPath = srcDir.getParent();
            File publicSrcDir = new File(info.publicSourceDir);
            String publicSrcPath = publicSrcDir.getParent();
            long pkgLen = new File(info.sourceDir).length();

            if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
                assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
                assertEquals(srcPath, drmInstallPath);
                assertEquals(publicSrcPath, appInstallPath);
            } else {
                assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
                int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
                if (rLoc == INSTALL_LOC_INT) {
                    assertEquals(srcPath, appInstallPath);
                    assertEquals(publicSrcPath, appInstallPath);
                    assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
                } else if (rLoc == INSTALL_LOC_SD){
                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
                    assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
                    assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
                } else {
                    // TODO handle error. Install should have failed.
                }
            }
        } catch (NameNotFoundException e) {
            failStr("failed with exception : " + e);
        }
    }
    
    private void assertNotInstalled(String pkgName) {
        try {
            ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
            fail(pkgName + " shouldnt be installed");
        } catch (NameNotFoundException e) {
        }
    }

    class InstallParams {
        String outFileName;
        Uri packageURI;
        PackageParser.Package pkg;
        InstallParams(PackageParser.Package pkg, String outFileName, Uri packageURI) {
            this.outFileName = outFileName;
            this.packageURI = packageURI;
            this.pkg = pkg;
        }
    }

    private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
        return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
                false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
    }

    static final String PERM_PACKAGE = "package";
    static final String PERM_DEFINED = "defined";
    static final String PERM_UNDEFINED = "undefined";
    static final String PERM_USED = "used";
    static final String PERM_NOTUSED = "notused";
    
    private void assertPermissions(String[] cmds) {
        final PackageManager pm = getPm();
        String pkg = null;
        PackageInfo pkgInfo = null;
        String mode = PERM_DEFINED;
        int i = 0;
        while (i < cmds.length) {
            String cmd = cmds[i++];
            if (cmd == PERM_PACKAGE) {
                pkg = cmds[i++];
                try {
                    pkgInfo = pm.getPackageInfo(pkg,
                            PackageManager.GET_PERMISSIONS
                            | PackageManager.GET_UNINSTALLED_PACKAGES);
                } catch (NameNotFoundException e) {
                    pkgInfo = null;
                }
            } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED
                    || cmd == PERM_USED || cmd == PERM_NOTUSED) {
                mode = cmds[i++];
            } else {
                if (mode == PERM_DEFINED) {
                    try {
                        PermissionInfo pi = pm.getPermissionInfo(cmd, 0);
                        assertNotNull(pi);
                        assertEquals(pi.packageName, pkg);
                        assertEquals(pi.name, cmd);
                        assertNotNull(pkgInfo);
                        boolean found = false;
                        for (int j=0; j<pkgInfo.permissions.length && !found; j++) {
                            if (pkgInfo.permissions[j].name.equals(cmd)) {
                                found = true;
                            }
                        }
                        if (!found) {
                            fail("Permission not found: " + cmd);
                        }
                    } catch (NameNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                } else if (mode == PERM_UNDEFINED) {
                    try {
                        pm.getPermissionInfo(cmd, 0);
                        throw new RuntimeException("Permission exists: " + cmd);
                    } catch (NameNotFoundException e) {
                    }
                    if (pkgInfo != null) {
                        boolean found = false;
                        for (int j=0; j<pkgInfo.permissions.length && !found; j++) {
                            if (pkgInfo.permissions[j].name.equals(cmd)) {
                                found = true;
                            }
                        }
                        if (found) {
                            fail("Permission still exists: " + cmd);
                        }
                    }
                } else if (mode == PERM_USED || mode == PERM_NOTUSED) {
                    boolean found = false;
                    for (int j=0; j<pkgInfo.requestedPermissions.length && !found; j++) {
                        if (pkgInfo.requestedPermissions[j].equals(cmd)) {
                            found = true;
                        }
                    }
                    if (!found) {
                        fail("Permission not requested: " + cmd);
                    }
                    if (mode == PERM_USED) {
                        if (pm.checkPermission(cmd, pkg)
                                != PackageManager.PERMISSION_GRANTED) {
                            fail("Permission not granted: " + cmd);
                        }
                    } else {
                        if (pm.checkPermission(cmd, pkg)
                                != PackageManager.PERMISSION_DENIED) {
                            fail("Permission granted: " + cmd);
                        }
                    }
                }
            }
        }
    }
    
    public void clearSecureContainersForPkg(String pkgName) {
        IMountService ms = getMs();
        try {
            String list[] = ms.getSecureContainerList();
            if (list != null) {
                for (String cid : list) {
                    boolean delete = false;
                    // STOPSHIP issues with rename should be fixed.
                    if (cid.contains(pkgName) ||
                            cid.contains("smdltmp")) {
                        Log.i(TAG, "Destroying container " + cid);
                        ms.destroySecureContainer(cid, true);
                    }
                }
            }
        } catch (RemoteException e) {}
    }

    /*
     * Utility function that reads a apk bundled as a raw resource
     * copies it into own data directory and invokes
     * PackageManager api to install it.
     */
    private InstallParams installFromRawResource(String outFileName,
            int rawResId, int flags, boolean cleanUp, boolean fail, int result,
            int expInstallLocation) {
        PackageManager pm = mContext.getPackageManager();
        File filesDir = mContext.getFilesDir();
        File outFile = new File(filesDir, outFileName);
        Uri packageURI = getInstallablePackage(rawResId, outFile);
        PackageParser.Package pkg = parsePackage(packageURI);
        assertNotNull(pkg);
        if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
            // Make sure the package doesn't exist
            try {
                ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
                        PackageManager.GET_UNINSTALLED_PACKAGES);
                GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
                invokeDeletePackage(packageURI, 0,
                        pkg.packageName, receiver);
            } catch (NameNotFoundException e1) {
            } catch (Exception e) {
                failStr(e);
            }
        }
        InstallParams ip = null;
        try {
            if (fail) {
                assertTrue(invokeInstallPackageFail(packageURI, flags,
                        pkg.packageName, result));
                assertNotInstalled(pkg.packageName);
            } else {
                InstallReceiver receiver = new InstallReceiver(pkg.packageName);
                assertTrue(invokeInstallPackage(packageURI, flags,
                        pkg.packageName, receiver));
                // Verify installed information
                assertInstall(pkg, flags, expInstallLocation);
                ip = new InstallParams(pkg, outFileName, packageURI);
            }
            return ip;
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            if (cleanUp) {
                cleanUpInstall(ip);
            }
        }
        return ip;
    }

    @MediumTest
    public void testInstallNormalInternal() {
        sampleInstallFromRawResource(0, true);
    }

    @MediumTest
    public void testInstallFwdLockedInternal() {
        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
    }

    @MediumTest
    public void testInstallSdcard() {
        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
    }

    /* ------------------------- Test replacing packages --------------*/
    class ReplaceReceiver extends GenericReceiver {
        String pkgName;
        final static int INVALID = -1;
        final static int REMOVED = 1;
        final static int ADDED = 2;
        final static int REPLACED = 3;
        int removed = INVALID;
        // for updated system apps only
        boolean update = false;

        ReplaceReceiver(String pkgName) {
            this.pkgName = pkgName;
            filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
            if (update) {
                filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
            }
            filter.addDataScheme("package");
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            String action = intent.getAction();
            Uri data = intent.getData();
            String installedPkg = data.getEncodedSchemeSpecificPart();
            if (pkgName == null || !pkgName.equals(installedPkg)) {
                return false;
            }
            if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
                removed = REMOVED;
            } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                if (removed != REMOVED) {
                    return false;
                }
                boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                if (!replacing) {
                    return false;
                }
                removed = ADDED;
                if (!update) {
                    return true;
                }
            } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
                if (removed != ADDED) {
                    return false;
                }
                removed = REPLACED;
                return true;
            }
            return false;
        }
    }

    /*
     * Utility function that reads a apk bundled as a raw resource
     * copies it into own data directory and invokes
     * PackageManager api to install first and then replace it
     * again.
     */
    public void replaceFromRawResource(int flags) {
        InstallParams ip = sampleInstallFromRawResource(flags, false);
        boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
        Log.i(TAG, "replace=" + replace);
        GenericReceiver receiver;
        if (replace) {
            receiver = new ReplaceReceiver(ip.pkg.packageName);
            Log.i(TAG, "Creating replaceReceiver");
        } else {
            receiver = new InstallReceiver(ip.pkg.packageName);
        }
        try {
            try {
                assertEquals(invokeInstallPackage(ip.packageURI, flags,
                        ip.pkg.packageName, receiver), replace);
                if (replace) {
                    assertInstall(ip.pkg, flags, ip.pkg.installLocation);
                }
            } catch (Exception e) {
                failStr("Failed with exception : " + e);
            }
        } finally {
            cleanUpInstall(ip);
        }
    }

    @MediumTest
    public void testReplaceFailNormalInternal() {
        replaceFromRawResource(0);
    }

    @MediumTest
    public void testReplaceFailFwdLockedInternal() {
        replaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
    }

    @MediumTest
    public void testReplaceFailSdcard() {
        replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
    }

    @MediumTest
    public void testReplaceNormalInternal() {
        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
    }

    @MediumTest
    public void testReplaceFwdLockedInternal() {
        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
                PackageManager.INSTALL_FORWARD_LOCK);
    }

    @MediumTest
    public void testReplaceSdcard() {
        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
                PackageManager.INSTALL_EXTERNAL);
    }

    /* -------------- Delete tests ---*/
    class DeleteObserver extends IPackageDeleteObserver.Stub {

        public boolean succeeded;
        private boolean doneFlag = false;

        public boolean isDone() {
            return doneFlag;
        }

        public void packageDeleted(boolean succeeded) throws RemoteException {
            synchronized(this) {
                this.succeeded = succeeded;
                doneFlag = true;
                notifyAll();
            }
        }
    }

    class DeleteReceiver extends GenericReceiver {
        String pkgName;

        DeleteReceiver(String pkgName) {
            this.pkgName = pkgName;
            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
            filter.addDataScheme("package");
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            String action = intent.getAction();
            if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
                return false;
            }
            Uri data = intent.getData();
            String installedPkg = data.getEncodedSchemeSpecificPart();
            if (pkgName.equals(installedPkg)) {
                return true;
            }
            return false;
        }
    }

    public boolean invokeDeletePackage(Uri packageURI, int flags,
            final String pkgName, GenericReceiver receiver) throws Exception {
        DeleteObserver observer = new DeleteObserver();
        final boolean received = false;
        mContext.registerReceiver(receiver, receiver.filter);
        try {
            // Wait on observer
            synchronized(observer) {
                synchronized (receiver) {
                    getPm().deletePackage(pkgName, observer, flags);
                    long waitTime = 0;
                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        observer.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!observer.isDone()) {
                        throw new Exception("Timed out waiting for packageInstalled callback");
                    }
                    // Verify we received the broadcast
                    waitTime = 0;
                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        receiver.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!receiver.isDone()) {
                        throw new Exception("Timed out waiting for PACKAGE_ADDED notification");
                    }
                    return receiver.received;
                }
            }
        } finally {
            mContext.unregisterReceiver(receiver);
        }
    }

    public void deleteFromRawResource(int iFlags, int dFlags) {
        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
        boolean retainData = ((dFlags & PackageManager.DONT_DELETE_DATA) != 0);
        GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
        DeleteObserver observer = new DeleteObserver();
        try {
            assertTrue(invokeDeletePackage(ip.packageURI, dFlags,
                    ip.pkg.packageName, receiver));
            ApplicationInfo info = null;
            Log.i(TAG, "okay4");
            try {
            info = getPm().getApplicationInfo(ip.pkg.packageName,
                    PackageManager.GET_UNINSTALLED_PACKAGES);
            } catch (NameNotFoundException e) {
                info = null;
            }
            if (retainData) {
                assertNotNull(info);
                assertEquals(info.packageName, ip.pkg.packageName);
                File file = new File(info.dataDir);
                assertTrue(file.exists());
            } else {
                assertNull(info);
            }
        } catch (Exception e) {
            failStr(e);
        } finally {
            cleanUpInstall(ip);
        }
    }

    @MediumTest
    public void testDeleteNormalInternal() {
        deleteFromRawResource(0, 0);
    }

    @MediumTest
    public void testDeleteFwdLockedInternal() {
        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
    }

    @MediumTest
    public void testDeleteSdcard() {
        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
    }

    @MediumTest
    public void testDeleteNormalInternalRetainData() {
        deleteFromRawResource(0, PackageManager.DONT_DELETE_DATA);
    }

    @MediumTest
    public void testDeleteFwdLockedInternalRetainData() {
        deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DONT_DELETE_DATA);
    }

    @MediumTest
    public void testDeleteSdcardRetainData() {
        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
    }

    /* sdcard mount/unmount tests ******/

    class SdMountReceiver extends GenericReceiver {
        String pkgNames[];
        boolean status = true;

        SdMountReceiver(String[] pkgNames) {
            this.pkgNames = pkgNames;
            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            Log.i(TAG, "okay 1");
            String action = intent.getAction();
            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
                return false;
            }
            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            for (String pkg : pkgNames) {
                boolean found = false;
                for (String rpkg : rpkgList) {
                    if (rpkg.equals(pkg)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    status = false;
                    return true;
                }
            }
            return true;
        }
    }

    class SdUnMountReceiver extends GenericReceiver {
        String pkgNames[];
        boolean status = true;

        SdUnMountReceiver(String[] pkgNames) {
            this.pkgNames = pkgNames;
            IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            String action = intent.getAction();
            if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
                return false;
            }
            String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            for (String pkg : pkgNames) {
                boolean found = false;
                for (String rpkg : rpkgList) {
                    if (rpkg.equals(pkg)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    status = false;
                    return true;
                }
            }
            return true;
        }
    }

    IMountService getMs() {
        IBinder service = ServiceManager.getService("mount");
        if (service != null) {
            return IMountService.Stub.asInterface(service);
        } else {
            Log.e(TAG, "Can't get mount service");
        }
        return null;
    }

    boolean getMediaState() {
        try {
        String mPath = Environment.getExternalStorageDirectory().toString();
        String state = getMs().getVolumeState(mPath);
        return Environment.MEDIA_MOUNTED.equals(state);
        } catch (RemoteException e) {
            return false;
        }
    }

    boolean mountMedia() {
        if (getMediaState()) {
            return true;
        }
        try {
        String mPath = Environment.getExternalStorageDirectory().toString();
        int ret = getMs().mountVolume(mPath);
        return ret == StorageResultCode.OperationSucceeded;
        } catch (RemoteException e) {
            return false;
        }
    }

    class StorageListener extends StorageEventListener {
        String oldState;
        String newState;
        String path;
        private boolean doneFlag = false;
        @Override
        public void onStorageStateChanged(String path, String oldState, String newState) {
            if (localLOGV) Log.i(TAG, "Storage state changed from " + oldState + " to " + newState);
            synchronized (this) {
                this.oldState = oldState;
                this.newState = newState;
                this.path = path;
                doneFlag = true;
                notifyAll();
            }
        }

        public boolean isDone() {
            return doneFlag;
        }
    }

    private boolean unmountMedia() {
        if (!getMediaState()) {
            return true;
        }
        String path = Environment.getExternalStorageDirectory().toString();
        StorageListener observer = new StorageListener();
        StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
        sm.registerListener(observer);
        try {
            // Wait on observer
            synchronized(observer) {
                getMs().unmountVolume(path, true);
                long waitTime = 0;
                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                    observer.wait(WAIT_TIME_INCR);
                    waitTime += WAIT_TIME_INCR;
                }
                if(!observer.isDone()) {
                    throw new Exception("Timed out waiting for packageInstalled callback");
                }
                return true;
            }
        } catch (Exception e) {
            return false;
        } finally {
            sm.unregisterListener(observer);
        }
    }

    private boolean mountFromRawResource() {
        // Install pkg on sdcard
        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
        if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
        boolean origState = getMediaState();
        boolean registeredReceiver = false;
        SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
        try {
            if (localLOGV) Log.i(TAG, "Unmounting media");
            // Unmount media
            assertTrue(unmountMedia());
            if (localLOGV) Log.i(TAG, "Unmounted media");
            // Register receiver here
            PackageManager pm = getPm();
            mContext.registerReceiver(receiver, receiver.filter);
            registeredReceiver = true;

            // Wait on receiver
            synchronized (receiver) {
                if (localLOGV) Log.i(TAG, "Mounting media");
                // Mount media again
                assertTrue(mountMedia());
                if (localLOGV) Log.i(TAG, "Mounted media");
                if (localLOGV) Log.i(TAG, "Waiting for notification");
                long waitTime = 0;
                // Verify we received the broadcast
                waitTime = 0;
                while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                    receiver.wait(WAIT_TIME_INCR);
                    waitTime += WAIT_TIME_INCR;
                }
                if(!receiver.isDone()) {
                    failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification");
                }
                return receiver.received;
            }
        } catch (InterruptedException e) {
            failStr(e);
            return false;
        } finally {
            if (registeredReceiver) mContext.unregisterReceiver(receiver);
            // Restore original media state
            if (origState) {
                mountMedia();
            } else {
                unmountMedia();
            }
            if (localLOGV) Log.i(TAG, "Cleaning up install");
            cleanUpInstall(ip);
        }
    }

    /*
     * Install package on sdcard. Unmount and then mount the media.
     * (Use PackageManagerService private api for now)
     * Make sure the installed package is available.
     * STOPSHIP will uncomment when MountService api's to mount/unmount
     * are made asynchronous.
     */
    public void xxxtestMountSdNormalInternal() {
        assertTrue(mountFromRawResource());
    }

    void cleanUpInstall(InstallParams ip) {
        if (ip == null) {
            return;
        }
        Runtime.getRuntime().gc();
        Log.i(TAG, "Deleting package : " + ip.pkg.packageName);
        getPm().deletePackage(ip.pkg.packageName, null, 0);
        File outFile = new File(ip.outFileName);
        if (outFile != null && outFile.exists()) {
            outFile.delete();
        }
    }

    public void testManifestInstallLocationInternal() {
        installFromRawResource("install.apk", R.raw.install_loc_internal,
                0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
    }

    public void testManifestInstallLocationSdcard() {
        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
    }

    public void testManifestInstallLocationAuto() {
        installFromRawResource("install.apk", R.raw.install_loc_auto,
                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
    }

    public void testManifestInstallLocationUnspecified() {
        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
    }

    public void testManifestInstallLocationFwdLockedFlagSdcard() {
        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
                PackageManager.INSTALL_FORWARD_LOCK |
                PackageManager.INSTALL_EXTERNAL, true, true,
                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                PackageInfo.INSTALL_LOCATION_AUTO);
    }

    public void testManifestInstallLocationFwdLockedSdcard() {
        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                PackageManager.INSTALL_FORWARD_LOCK, true, false,
                -1,
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
    }

    /*
     * Install a package on internal flash via PackageManager install flag. Replace
     * the package via flag to install on sdcard. Make sure the new flag overrides
     * the old install location.
     */
    public void testReplaceFlagInternalSdcard() {
        int iFlags = 0;
        int rFlags = PackageManager.INSTALL_EXTERNAL;
        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
        try {
            assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
                    ip.pkg.packageName, receiver), true);
            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            cleanUpInstall(ip);
        }
    }

    /*
     * Install a package on sdcard via PackageManager install flag. Replace
     * the package with no flags or manifest option and make sure the old
     * install location is retained.
     */
    public void testReplaceFlagSdcardInternal() {
        int iFlags = PackageManager.INSTALL_EXTERNAL;
        int rFlags = 0;
        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
        try {
            assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
                    ip.pkg.packageName, receiver), true);
            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            cleanUpInstall(ip);
        }
    }

    public void testManifestInstallLocationReplaceInternalSdcard() {
        int iFlags = 0;
        int iApk = R.raw.install_loc_unspecified;
        int rFlags = 0;
        int rApk = R.raw.install_loc_sdcard;
        InstallParams ip = installFromRawResource("install.apk", iApk,
                iFlags, false,
                false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
        try {
            InstallParams rp = installFromRawResource("install.apk", rApk,
                    replaceFlags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
            assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            cleanUpInstall(ip);
        }
    }

    public void testManifestInstallLocationReplaceSdcardInternal() {
        int iFlags = 0;
        int iApk = R.raw.install_loc_sdcard;
        int rFlags = 0;
        int rApk = R.raw.install_loc_unspecified;
        InstallParams ip = installFromRawResource("install.apk", iApk,
                iFlags, false,
                false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
        try {
            InstallParams rp = installFromRawResource("install.apk", rApk,
                    replaceFlags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
            assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            cleanUpInstall(ip);
        }
    }

    class MoveReceiver extends GenericReceiver {
        String pkgName;
        final static int INVALID = -1;
        final static int REMOVED = 1;
        final static int ADDED = 2;
        int removed = INVALID;

        MoveReceiver(String pkgName) {
            this.pkgName = pkgName;
            filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
            filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
            super.setFilter(filter);
        }

        public boolean notifyNow(Intent intent) {
            String action = intent.getAction();
            Log.i(TAG, "MoveReceiver::" + action);
            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                if (list != null) {
                    for (String pkg : list) {
                        if (pkg.equals(pkgName)) {
                            removed = REMOVED;
                            break;
                        }
                    }
                }
                removed = REMOVED;
            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
                if (removed != REMOVED) {
                    return false;
                }
                String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                if (list != null) {
                    for (String pkg : list) {
                        if (pkg.equals(pkgName)) {
                            removed = ADDED;
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }

    private class PackageMoveObserver extends IPackageMoveObserver.Stub {
        public int returnCode;
        private boolean doneFlag = false;

        public void packageMoved(String packageName, int returnCode) {
            synchronized(this) {
                this.returnCode = returnCode;
                doneFlag = true;
                notifyAll();
            }
        }

        public boolean isDone() {
            return doneFlag;
        }
    }

    public boolean invokeMovePackage(String pkgName, int flags,
            GenericReceiver receiver) throws Exception {
        PackageMoveObserver observer = new PackageMoveObserver();
        final boolean received = false;
        mContext.registerReceiver(receiver, receiver.filter);
        try {
            // Wait on observer
            synchronized(observer) {
                synchronized (receiver) {
                    getPm().movePackage(pkgName, observer, flags);
                    long waitTime = 0;
                    while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        observer.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!observer.isDone()) {
                        throw new Exception("Timed out waiting for pkgmove callback");
                    }
                    if (observer.returnCode != PackageManager.MOVE_SUCCEEDED) {
                        return false;
                    }
                    // Verify we received the broadcast
                    waitTime = 0;
                    while((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                        receiver.wait(WAIT_TIME_INCR);
                        waitTime += WAIT_TIME_INCR;
                    }
                    if(!receiver.isDone()) {
                        throw new Exception("Timed out waiting for MOVE notifications");
                    }
                    return receiver.received;
                }
            }
        } finally {
            mContext.unregisterReceiver(receiver);
        }
    }

    private int getInstallLoc() {
        boolean userSetting = false;
        int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
        try {
            userSetting = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
            origDefaultLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
        } catch (SettingNotFoundException e1) {
        }
        return origDefaultLoc;
    }

    private void setInstallLoc(int loc) {
        Settings.System.putInt(mContext.getContentResolver(),
                Settings.System.DEFAULT_INSTALL_LOCATION, loc);
    }
    /*
     * Utility function that reads a apk bundled as a raw resource
     * copies it into own data directory and invokes
     * PackageManager api to install first and then replace it
     * again.
     */
    public void moveFromRawResource(int installFlags, int moveFlags,
            int expRetCode) {
        int origDefaultLoc = getInstallLoc();
        setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
        // Install first
        InstallParams ip = sampleInstallFromRawResource(installFlags, false);
        ApplicationInfo oldAppInfo = null;
        try {
            oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
        } catch (NameNotFoundException e) {
            failStr("Pkg hasnt been installed correctly");
        }

        // Create receiver based on expRetCode
        MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
        try {
            boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
                    receiver);
            if (expRetCode == PackageManager.MOVE_SUCCEEDED) {
                assertTrue(retCode);
                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
                assertNotNull(info);
                if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
                } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
                    assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
                }
            } else {
                assertFalse(retCode);
                ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
                assertNotNull(info);
                assertEquals(oldAppInfo.flags, info.flags);
            }
        } catch (Exception e) {
            failStr("Failed with exception : " + e);
        } finally {
            cleanUpInstall(ip);
            // Restore default install location
            setInstallLoc(origDefaultLoc);
        }
    }

    public void testMoveAppInternalToExternal() {
        moveFromRawResource(0, PackageManager.MOVE_EXTERNAL_MEDIA,
                PackageManager.MOVE_SUCCEEDED);
    }

    public void testMoveAppInternalToInternal() {
        moveFromRawResource(0, PackageManager.MOVE_INTERNAL,
                PackageManager.MOVE_FAILED_INVALID_LOCATION);
    }

    public void testMoveAppExternalToExternal() {
        moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_EXTERNAL_MEDIA,
                PackageManager.MOVE_FAILED_INVALID_LOCATION);
    }
    public void testMoveAppExternalToInternal() {
        moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL,
                PackageManager.MOVE_SUCCEEDED);
    }

    /*
     * Test that an install error code is returned when media is unmounted
     * and package installed on sdcard via package manager flag.
     */
    public void testInstallSdcardUnmount() {
        boolean origState = getMediaState();
        try {
            // Unmount sdcard
            assertTrue(unmountMedia());
            // Try to install and make sure an error code is returned.
            assertNull(installFromRawResource("install.apk", R.raw.install,
                    PackageManager.INSTALL_EXTERNAL, false,
                    true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
                    PackageInfo.INSTALL_LOCATION_AUTO));
        } finally {
            // Restore original media state
            if (origState) {
                mountMedia();
            } else {
                unmountMedia();
            }
        }
    }

    /*
    * Unmount sdcard. Try installing an app with manifest option to install
    * on sdcard. Make sure it gets installed on internal flash.
    */
   public void testInstallManifestSdcardUnmount() {
       boolean origState = getMediaState();
       try {
           // Unmount sdcard
           assertTrue(unmountMedia());
           // Try to install and make sure an error code is returned.
           assertNotNull(installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                   0, false,
                   false, -1,
                   PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY));
       } finally {
           // Restore original media state
           if (origState) {
               mountMedia();
           } else {
               unmountMedia();
           }
       }
   }

   /*---------- Recommended install location tests ----*/
   /* Precedence: FlagManifestExistingUser
    * PrecedenceSuffixes:
    * Flag : FlagI, FlagE, FlagF
    * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
    * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
    * Existing: Existing suffix absent if not existing.
    * User: UserI, UserE, UserA, User suffix absent if not existing. 
    * 
    */
   /*
    * Install an app on internal flash
    */
   public void testFlagI() {
       sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
   }
   /*
    * Install an app on sdcard.
    */
   public void testFlagE() {
       sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
   }

   /*
    * Install an app on sdcard.
    */
   public void testFlagF() {
       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
   }
   /*
    * Install an app with both internal and external flags set. should fail
    */
   public void testFlagIE() {
       installFromRawResource("install.apk", R.raw.install,
               PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
               false,
               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
               PackageInfo.INSTALL_LOCATION_AUTO);
   }

   /*
    * Install an app with both internal and external flags set. should fail
    */
   public void testFlagIF() {
       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
               PackageManager.INSTALL_INTERNAL, true);
   }
   /*
    * Install an app with both internal and external flags set. should fail
    */
   public void testFlagEF() {
       installFromRawResource("install.apk", R.raw.install,
               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
               false,
               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
               PackageInfo.INSTALL_LOCATION_AUTO);
   }
   /*
    * Install an app with both internal and external flags set. should fail
    */
   public void testFlagIEF() {
       installFromRawResource("install.apk", R.raw.install,
               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
               PackageManager.INSTALL_EXTERNAL,
               false,
               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
               PackageInfo.INSTALL_LOCATION_AUTO);
   }
   /*
    * Install an app with both internal and manifest option set.
    * should install on internal.
    */
   public void testFlagIManifestI() {
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               PackageManager.INSTALL_INTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   /*
    * Install an app with both internal and manifest preference for
    * preferExternal. Should install on internal.
    */
   public void testFlagIManifestE() {
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               PackageManager.INSTALL_INTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   /*
    * Install an app with both internal and manifest preference for
    * auto. should install internal.
    */
   public void testFlagIManifestA() {
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               PackageManager.INSTALL_INTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   /*
    * Install an app with both external and manifest option set.
    * should install externally.
    */
   public void testFlagEManifestI() {
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /*
    * Install an app with both external and manifest preference for
    * preferExternal. Should install externally.
    */
   public void testFlagEManifestE() {
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /*
    * Install an app with both external and manifest preference for
    * auto. should install on external media.
    */
   public void testFlagEManifestA() {
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /*
    * Install an app with fwd locked flag set and install location set to
    * internal. should install internally.
    */
   public void testFlagFManifestI() {
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /*
    * Install an app with fwd locked flag set and install location set to
    * preferExternal. should install internally.
    */
   public void testFlagFManifestE() {
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /*
    * Install an app with fwd locked flag set and install location set to
    * auto. should install internally.
    */
   public void testFlagFManifestA() {
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               PackageManager.INSTALL_EXTERNAL,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   /* The following test functions verify install location for existing apps.
    * ie existing app can be installed internally or externally. If install
    * flag is explicitly set it should override current location. If manifest location
    * is set, that should over ride current location too. if not the existing install
    * location should be honoured.
    * testFlagI/E/F/ExistingI/E - 
    */
   public void testFlagIExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   public void testFlagIExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   public void testFlagEExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   public void testFlagEExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   public void testFlagFExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   public void testFlagFExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install,
               rFlags,
               true,
               false, -1,
               -1);
   }
   /*
    * The following set of tests verify the installation of apps with
    * install location attribute set to internalOnly, preferExternal and auto.
    * The manifest option should dictate the install location.
    * public void testManifestI/E/A
    * TODO out of memory fall back behaviour.
    */
   public void testManifestI() {
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               0,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   public void testManifestE() {
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               0,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   public void testManifestA() {
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               0,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   /*
    * The following set of tests verify the installation of apps
    * with install location attribute set to internalOnly, preferExternal and auto
    * for already existing apps. The manifest option should take precedence.
    * TODO add out of memory fall back behaviour.
    * testManifestI/E/AExistingI/E 
    */
   public void testManifestIExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   public void testManifestIExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_internal,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
   }
   public void testManifestEExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   public void testManifestEExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
   }
   public void testManifestAExistingI() {
       int iFlags = PackageManager.INSTALL_INTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_AUTO);
   }
   public void testManifestAExistingE() {
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Replace now
       installFromRawResource("install.apk", R.raw.install_loc_auto,
               rFlags,
               true,
               false, -1,
               PackageInfo.INSTALL_LOCATION_AUTO);
   }
   /*
    * The following set of tests check install location for existing
    * application based on user setting.
    */
   private void setExistingXUserX(int userSetting, int iFlags) {
       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
       // First install.
       installFromRawResource("install.apk", R.raw.install,
               iFlags,
               false,
               false, -1,
               -1);
       // Watch out for this.
       int iloc = PackageInfo.INSTALL_LOCATION_AUTO;
       if ((iFlags & PackageManager.INSTALL_INTERNAL) != 0) {
           iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
       } else if ((iFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
           iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
       }
       int origSetting = getInstallLoc();
       try {
           // Set user setting
           setInstallLoc(userSetting);
           // Replace now
           installFromRawResource("install.apk", R.raw.install,
                   rFlags,
                   true,
                   false, -1,
                   iloc);
       } finally {
           setInstallLoc(origSetting);
       }
   }
   public void testExistingIUserI() {
       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
       int iFlags = PackageManager.INSTALL_INTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   public void testExistingIUserE() {
       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
       int iFlags = PackageManager.INSTALL_INTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   public void testExistingIUserA() {
       int userSetting = PackageHelper.APP_INSTALL_AUTO;
       int iFlags = PackageManager.INSTALL_INTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   public void testExistingEUserI() {
       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   public void testExistingEUserE() {
       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   public void testExistingEUserA() {
       int userSetting = PackageHelper.APP_INSTALL_AUTO;
       int iFlags = PackageManager.INSTALL_EXTERNAL;
       setExistingXUserX(userSetting, iFlags);
   }
   /*
    * The following set of tests verify that the user setting defines
    * the install location.
    * 
    */
   private void setUserX(int userSetting) {
       int origSetting = getInstallLoc();
       int iloc = PackageInfo.INSTALL_LOCATION_AUTO;
       if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
           iloc = PackageInfo.INSTALL_LOCATION_AUTO;
       } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
           iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
       } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
           iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
       }
       try {
           // Set user setting
           setInstallLoc(userSetting);
           // Replace now
           installFromRawResource("install.apk", R.raw.install,
                   0,
                   true,
                   false, -1,
                   iloc);
       } finally {
           setInstallLoc(origSetting);
       }
   }
   public void testUserI() {
       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
       setUserX(userSetting);
   }
   public void testUserE() {
       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
       setUserX(userSetting);
   }
   public void testUserA() {
       int userSetting = PackageHelper.APP_INSTALL_AUTO;
       setUserX(userSetting);
   }
   
    static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
        PERM_DEFINED,
        "com.android.unit_tests.NORMAL",
        "com.android.unit_tests.DANGEROUS",
        "com.android.unit_tests.SIGNATURE",
    };
    
    static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
        PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
        PERM_UNDEFINED,
        "com.android.unit_tests.NORMAL",
        "com.android.unit_tests.DANGEROUS",
        "com.android.unit_tests.SIGNATURE",
    };
    
    static final String BASE_PERMISSIONS_USED[] = new String[] {
        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
        PERM_USED,
        "com.android.unit_tests.NORMAL",
        "com.android.unit_tests.DANGEROUS",
        "com.android.unit_tests.SIGNATURE",
    };
    
    static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
        PERM_NOTUSED,
        "com.android.unit_tests.NORMAL",
        "com.android.unit_tests.DANGEROUS",
        "com.android.unit_tests.SIGNATURE",
    };
    
    static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
        PERM_PACKAGE, "com.android.unit_tests.install_use_perm_good",
        PERM_USED,
        "com.android.unit_tests.SIGNATURE",
        PERM_NOTUSED,
        "com.android.unit_tests.NORMAL",
        "com.android.unit_tests.DANGEROUS",
    };
    
    /*
     * Ensure that permissions are properly declared.
     */
    public void testInstallDeclaresPermissions() {
        InstallParams ip = null;
        InstallParams ip2 = null;
        try {
            // **: Upon installing a package, are its declared permissions published?
           
            int iFlags = PackageManager.INSTALL_INTERNAL;
            int iApk = R.raw.install_decl_perm;
            ip = installFromRawResource("install.apk", iApk,
                    iFlags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_DEFINED);
           
            // **: Upon installing package, are its permissions granted?
           
            int i2Flags = PackageManager.INSTALL_INTERNAL;
            int i2Apk = R.raw.install_use_perm_good;
            ip2 = installFromRawResource("install2.apk", i2Apk,
                    i2Flags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_USED);
            
            // **: Upon removing but not deleting, are permissions retained?
           
            GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
           
            try {
                invokeDeletePackage(ip.packageURI, PackageManager.DONT_DELETE_DATA,
                        ip.pkg.packageName, receiver);
            } catch (Exception e) {
                failStr(e);
            }
            assertPermissions(BASE_PERMISSIONS_DEFINED);
            assertPermissions(BASE_PERMISSIONS_USED);
           
            // **: Upon re-installing, are permissions retained?
           
            ip = installFromRawResource("install.apk", iApk,
                    iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_DEFINED);
            assertPermissions(BASE_PERMISSIONS_USED);
           
            // **: Upon deleting package, are all permissions removed?
           
            try {
                invokeDeletePackage(ip.packageURI, 0,
                        ip.pkg.packageName, receiver);
                ip = null;
            } catch (Exception e) {
                failStr(e);
            }
            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
            assertPermissions(BASE_PERMISSIONS_NOTUSED);
           
            // **: Delete package using permissions; nothing to check here.
           
            GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
            try {
                invokeDeletePackage(ip2.packageURI, 0,
                        ip2.pkg.packageName, receiver);
                ip2 = null;
            } catch (Exception e) {
                failStr(e);
            }
            
            // **: Re-install package using permissions; no permissions can be granted.
           
            ip2 = installFromRawResource("install2.apk", i2Apk,
                    i2Flags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_NOTUSED);
           
            // **: Upon installing declaring package, are sig permissions granted
            // to other apps (but not other perms)?
           
            ip = installFromRawResource("install.apk", iApk,
                    iFlags, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_DEFINED);
            assertPermissions(BASE_PERMISSIONS_SIGUSED);
           
            // **: Re-install package using permissions; are all permissions granted?
            
            ip2 = installFromRawResource("install2.apk", i2Apk,
                    i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
                    false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
            assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
            assertPermissions(BASE_PERMISSIONS_NOTUSED);
           
            // **: Upon deleting package, are all permissions removed?
            
            try {
                invokeDeletePackage(ip.packageURI, 0,
                        ip.pkg.packageName, receiver);
                ip = null;
            } catch (Exception e) {
                failStr(e);
            }
            assertPermissions(BASE_PERMISSIONS_UNDEFINED);
            assertPermissions(BASE_PERMISSIONS_NOTUSED);
            
            // **: Delete package using permissions; nothing to check here.
            
            try {
                invokeDeletePackage(ip2.packageURI, 0,
                        ip2.pkg.packageName, receiver);
                ip2 = null;
            } catch (Exception e) {
                failStr(e);
            }
            
        } finally {
            if (ip2 != null) {
                cleanUpInstall(ip2);
            }
            if (ip != null) {
                cleanUpInstall(ip);
            }
        }
    }

    /*---------- Recommended install location tests ----*/
    /*
     * TODO's
     * check version numbers for upgrades
     * check permissions of installed packages
     * how to do tests on updated system apps?
     * verify updates to system apps cannot be installed on the sdcard.
     */
}
