alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Android example source code file (PackageManagerHostTestUtils.java)

This example Android source code file (PackageManagerHostTestUtils.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Android by Example" TM.

Java - Android tags/keywords

adbcommandrejectedexception, bufferedreader, collectingoutputreceiver, collectingtestrunlistener, device_app_path, idevice, installexception, installreceiver, interruptedexception, io, ioexception, packagemanagerhosttestutils, regex, shellcommandunresponsiveexception, string, timeoutexception, util

The PackageManagerHostTestUtils.java Android example source code

/*
 * Copyright (C) 2010 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 android.content.pm;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.InstallException;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncException;
import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.SyncService.ISyncProgressMonitor;
import com.android.ddmlib.testrunner.ITestRunListener;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestIdentifier;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.Runtime;
import java.lang.Process;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import junit.framework.Assert;

/**
 * Set of tests that verify host side install cases
 */
public class PackageManagerHostTestUtils extends Assert {

    private static final String LOG_TAG = "PackageManagerHostTests";
    private IDevice mDevice = null;

    // TODO: get this value from Android Environment instead of hardcoding
    private static final String APP_PRIVATE_PATH = "/data/app-private/";
    private static final String DEVICE_APP_PATH = "/data/app/";
    private static final String SDCARD_APP_PATH = "/mnt/secure/asec/";

    private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
    private static final int WAIT_FOR_DEVICE_POLL_TIME = 10 * 1000;
    private static final int MAX_WAIT_FOR_APP_LAUNCH_TIME = 60 * 1000;
    private static final int WAIT_FOR_APP_LAUNCH_POLL_TIME = 5 * 1000;

    // Install preference on the device-side
    public static enum InstallLocPreference {
        AUTO,
        INTERNAL,
        EXTERNAL
    }

    // Actual install location
    public static enum InstallLocation {
        DEVICE,
        SDCARD
    }

    /**
     * Constructor takes the device to use
     * @param the device to use when performing operations
     */
    public PackageManagerHostTestUtils(IDevice device)
    {
          mDevice = device;
    }

    /**
     * Disable default constructor
     */
    private PackageManagerHostTestUtils() {}

    /**
     * Returns the path on the device of forward-locked apps.
     *
     * @return path of forward-locked apps on the device
     */
    public static String getAppPrivatePath() {
        return APP_PRIVATE_PATH;
    }

    /**
     * Returns the path on the device of normal apps.
     *
     * @return path of forward-locked apps on the device
     */
    public static String getDeviceAppPath() {
        return DEVICE_APP_PATH;
    }

    /**
     * Returns the path of apps installed on the SD card.
     *
     * @return path of forward-locked apps on the device
     */
    public static String getSDCardAppPath() {
        return SDCARD_APP_PATH;
    }

    /**
     * Helper method to run tests and return the listener that collected the results.
     * @param pkgName Android application package for tests
     * @return the {@link CollectingTestRunListener}
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    private CollectingTestRunListener doRunTests(String pkgName) throws IOException,
    TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
                pkgName, mDevice);
        CollectingTestRunListener listener = new CollectingTestRunListener();
        testRunner.run(listener);
        return listener;
    }

    /**
     * Runs the specified packages tests, and returns whether all tests passed or not.
     *
     * @param pkgName Android application package for tests
     * @return true if every test passed, false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException,
            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        CollectingTestRunListener listener = doRunTests(pkgName);
        return listener.didAllTestsPass();
    }

    /**
     * Helper method to push a file to device
     * @param apkAppPrivatePath
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws IOException if connection to device was lost.
     * @throws SyncException if the sync failed for another reason.
     */
    public void pushFile(final String localFilePath, final String destFilePath)
            throws IOException, SyncException, TimeoutException, AdbCommandRejectedException {
        mDevice.getSyncService().pushFile(localFilePath,
                destFilePath, new NullSyncProgressMonitor());
    }

    /**
     * Helper method to install a file
     * @param localFilePath the absolute file system path to file on local host to install
     * @param reinstall set to <code>true if re-install of app should be performed
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the install failed
     */
    public void installFile(final String localFilePath, final boolean replace) throws IOException,
            InstallException {
        String result = mDevice.installPackage(localFilePath, replace);
        assertEquals(null, result);
    }

    /**
     * Helper method to install a file that should not be install-able
     * @param localFilePath the absolute file system path to file on local host to install
     * @param reinstall set to <code>true if re-install of app should be performed
     * @return the string output of the failed install attempt
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the install failed
     */
    public String installFileFail(final String localFilePath, final boolean replace)
            throws IOException, InstallException {
        String result = mDevice.installPackage(localFilePath, replace);
        assertNotNull(result);
        return result;
    }

    /**
     * Helper method to install a file to device as forward locked
     * @param localFilePath the absolute file system path to file on local host to install
     * @param reinstall set to <code>true if re-install of app should be performed
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     * @throws SyncException if the sync failed for another reason.
     * @throws InstallException if the install failed.
     */
    public String installFileForwardLocked(final String localFilePath, final boolean replace)
            throws IOException, SyncException, TimeoutException, AdbCommandRejectedException,
            ShellCommandUnresponsiveException, InstallException {
        String remoteFilePath = mDevice.syncPackageToDevice(localFilePath);
        InstallReceiver receiver = new InstallReceiver();
        String cmd = String.format(replace ? "pm install -r -l \"%1$s\"" :
                "pm install -l \"%1$s\"", remoteFilePath);
        mDevice.executeShellCommand(cmd, receiver);
        mDevice.removeRemotePackage(remoteFilePath);
        return receiver.getErrorMessage();
    }

    /**
     * Helper method to determine if file on device exists.
     *
     * @param destPath the absolute path of file on device to check
     * @return <code>true if file exists, false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesRemoteFileExist(String destPath) throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        String lsGrep = executeShellCommand(String.format("ls %s", destPath));
        return !lsGrep.contains("No such file or directory");
    }

    /**
     * Helper method to determine if file exists on the device containing a given string.
     *
     * @param destPath the absolute path of the file
     * @return <code>true if file exists containing given string,
     *         <code>false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
            throws IOException, TimeoutException, AdbCommandRejectedException,
            ShellCommandUnresponsiveException {
        String lsResult = executeShellCommand(String.format("ls %s", destPath));
        return lsResult.contains(searchString);
    }

    /**
     * Helper method to determine if package on device exists.
     *
     * @param packageName the Android manifest package to check.
     * @return <code>true if package exists, false otherwise
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesPackageExist(String packageName) throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        String pkgGrep = executeShellCommand(String.format("pm path %s", packageName));
        return pkgGrep.contains("package:");
    }

    /**
     * Determines if app was installed on device.
     *
     * @param packageName package name to check for
     * @return <code>true if file exists, false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesAppExistOnDevice(String packageName) throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
    }

    /**
     * Determines if app was installed on SD card.
     *
     * @param packageName package name to check for
     * @return <code>true if file exists, false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesAppExistOnSDCard(String packageName) throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
    }

    /**
     * Helper method to determine if app was installed on SD card.
     *
     * @param packageName package name to check for
     * @return <code>true if file exists, false otherwise.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public boolean doesAppExistAsForwardLocked(String packageName) throws IOException,
            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        return doesRemoteFileExistContainingString(APP_PRIVATE_PATH, packageName);
    }

    /**
     * Waits for device's package manager to respond.
     *
     * @throws InterruptedException
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public void waitForPackageManager() throws InterruptedException, IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        Log.i(LOG_TAG, "waiting for device");
        int currentWaitTime = 0;
        // poll the package manager until it returns something for android
        while (!doesPackageExist("android")) {
            Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
            currentWaitTime += WAIT_FOR_DEVICE_POLL_TIME;
            if (currentWaitTime > MAX_WAIT_FOR_DEVICE_TIME) {
                Log.e(LOG_TAG, "time out waiting for device");
                throw new InterruptedException();
            }
        }
    }

    /**
     * Helper to determine if the device is currently online and visible via ADB.
     *
     * @return true iff the device is currently available to ADB and online, false otherwise.
     */
    private boolean deviceIsOnline() {
        AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
        IDevice[] devices = bridge.getDevices();

        for (IDevice device : devices) {
            // only online if the device appears in the devices list, and its state is online
            if ((mDevice != null) &&
                    mDevice.getSerialNumber().equals(device.getSerialNumber()) &&
                    device.isOnline()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Waits for device to be online (visible to ADB) before returning, or times out if we've
     * waited too long. Note that this only means the device is visible via ADB, not that
     * PackageManager is fully up and running yet.
     *
     * @throws InterruptedException
     * @throws IOException
     */
    public void waitForDeviceToComeOnline() throws InterruptedException, IOException {
        Log.i(LOG_TAG, "waiting for device to be online");
        int currentWaitTime = 0;

        // poll ADB until we see the device is online
        while (!deviceIsOnline()) {
            Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
            currentWaitTime += WAIT_FOR_DEVICE_POLL_TIME;
            if (currentWaitTime > MAX_WAIT_FOR_DEVICE_TIME) {
                Log.e(LOG_TAG, "time out waiting for device");
                throw new InterruptedException();
            }
        }
        // Note: if we try to access the device too quickly after it is "officially" online,
        // there are sometimes strange issues where it's actually not quite ready yet,
        // so we pause for a bit once more before actually returning.
        Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
    }

    /**
     * Queries package manager and waits until a package is launched (or times out)
     *
     * @param packageName The name of the package to wait to load
     * @throws InterruptedException
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public void waitForApp(String packageName) throws InterruptedException, IOException,
            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        Log.i(LOG_TAG, "waiting for app to launch");
        int currentWaitTime = 0;
        // poll the package manager until it returns something for the package we're looking for
        while (!doesPackageExist(packageName)) {
            Thread.sleep(WAIT_FOR_APP_LAUNCH_POLL_TIME);
            currentWaitTime += WAIT_FOR_APP_LAUNCH_POLL_TIME;
            if (currentWaitTime > MAX_WAIT_FOR_APP_LAUNCH_TIME) {
                Log.e(LOG_TAG, "time out waiting for app to launch: " + packageName);
                throw new InterruptedException();
            }
        }
    }

    /**
     * Helper method which executes a adb shell command and returns output as a {@link String}
     * @return the output of the command
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public String executeShellCommand(String command) throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        Log.i(LOG_TAG, String.format("adb shell %s", command));
        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
        mDevice.executeShellCommand(command, receiver);
        String output = receiver.getOutput();
        Log.i(LOG_TAG, String.format("Result: %s", output));
        return output;
    }

    /**
     * Helper method ensures we are in root mode on the host side. It returns only after
     * PackageManager is actually up and running.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public void runAdbRoot() throws IOException, InterruptedException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        Log.i(LOG_TAG, "adb root");
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("adb root"); // adb should be in the path
        BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));

        String nextLine = null;
        while (null != (nextLine = output.readLine())) {
            Log.i(LOG_TAG, nextLine);
        }
        process.waitFor();
        waitForDeviceToComeOnline();
        waitForPackageManager(); // now wait for package manager to actually load
    }

    /**
     * Helper method which reboots the device and returns once the device is online again
     * and package manager is up and running (note this function is synchronous to callers).
     * @throws InterruptedException
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public void rebootDevice() throws IOException, InterruptedException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        String command = "reboot"; // no need for -s since mDevice is already tied to a device
        Log.i(LOG_TAG, command);
        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
        mDevice.executeShellCommand(command, receiver);
        String output = receiver.getOutput();
        Log.i(LOG_TAG, String.format("Result: %s", output));
        waitForDeviceToComeOnline(); // wait for device to come online
        runAdbRoot();
    }

    /**
     * A {@link IShellOutputReceiver} which collects the whole shell output into one {@link String}
     */
    private class CollectingOutputReceiver extends MultiLineReceiver {

        private StringBuffer mOutputBuffer = new StringBuffer();

        public String getOutput() {
            return mOutputBuffer.toString();
        }

        @Override
        public void processNewLines(String[] lines) {
            for (String line: lines) {
                mOutputBuffer.append(line);
                mOutputBuffer.append("\n");
            }
        }

        public boolean isCancelled() {
            return false;
        }
    }

    private class NullSyncProgressMonitor implements ISyncProgressMonitor {
        public void advance(int work) {
            // ignore
        }

        public boolean isCanceled() {
            // ignore
            return false;
        }

        public void start(int totalWork) {
            // ignore

        }

        public void startSubTask(String name) {
            // ignore
        }

        public void stop() {
            // ignore
        }
    }

    // For collecting results from running device tests
    private static class CollectingTestRunListener implements ITestRunListener {

        private boolean mAllTestsPassed = true;
        private String mTestRunErrorMessage = null;

        public void testEnded(TestIdentifier test) {
            // ignore
        }

        public void testFailed(TestFailure status, TestIdentifier test,
                String trace) {
            Log.w(LOG_TAG, String.format("%s#%s failed: %s", test.getClassName(),
                    test.getTestName(), trace));
            mAllTestsPassed = false;
        }

        public void testRunEnded(long elapsedTime, Map<String, String> resultBundle) {
            // ignore
        }

        public void testRunFailed(String errorMessage) {
            Log.w(LOG_TAG, String.format("test run failed: %s", errorMessage));
            mAllTestsPassed = false;
            mTestRunErrorMessage = errorMessage;
        }

        public void testRunStarted(int testCount) {
            // ignore
        }

        public void testRunStopped(long elapsedTime) {
            // ignore
        }

        public void testStarted(TestIdentifier test) {
            // ignore
        }

        boolean didAllTestsPass() {
            return mAllTestsPassed;
        }

        /**
         * Get the test run failure error message.
         * @return the test run failure error message or <code>null if test run completed.
         */
        String getTestRunErrorMessage() {
            return mTestRunErrorMessage;
        }
    }

    /**
     * Output receiver for "pm install package.apk" command line.
     *
     */
    private static final class InstallReceiver extends MultiLineReceiver {

        private static final String SUCCESS_OUTPUT = "Success"; //$NON-NLS-1$
        private static final Pattern FAILURE_PATTERN = Pattern.compile("Failure\\s+\\[(.*)\\]"); //$NON-NLS-1$

        private String mErrorMessage = null;

        public InstallReceiver() {
        }

        @Override
        public void processNewLines(String[] lines) {
            for (String line : lines) {
                if (line.length() > 0) {
                    if (line.startsWith(SUCCESS_OUTPUT)) {
                        mErrorMessage = null;
                    } else {
                        Matcher m = FAILURE_PATTERN.matcher(line);
                        if (m.matches()) {
                            mErrorMessage = m.group(1);
                        }
                    }
                }
            }
        }

        public boolean isCancelled() {
            return false;
        }

        public String getErrorMessage() {
            return mErrorMessage;
        }
    }

    /**
     * Helper method for installing an app to wherever is specified in its manifest, and
     * then verifying the app was installed onto SD Card.
     * <p/>
     * Assumes adb is running as root in device under test.
     *
     * @param the path of the apk to install
     * @param the name of the package
     * @param <code>true if the app should be overwritten, false otherwise
     * @throws InterruptedException if the thread was interrupted
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the install failed.
     */
    public void installAppAndVerifyExistsOnSDCard(String apkPath, String pkgName, boolean overwrite)
            throws IOException, InterruptedException, InstallException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        // Start with a clean slate if we're not overwriting
        if (!overwrite) {
            // cleanup test app just in case it already exists
            mDevice.uninstallPackage(pkgName);
            // grep for package to make sure its not installed
            assertFalse(doesPackageExist(pkgName));
        }

        installFile(apkPath, overwrite);
        assertTrue(doesAppExistOnSDCard(pkgName));
        assertFalse(doesAppExistOnDevice(pkgName));
        waitForPackageManager();

        // grep for package to make sure it is installed
        assertTrue(doesPackageExist(pkgName));
    }

    /**
     * Helper method for installing an app to wherever is specified in its manifest, and
     * then verifying the app was installed onto device.
     * <p/>
     * Assumes adb is running as root in device under test.
     *
     * @param the path of the apk to install
     * @param the name of the package
     * @param <code>true if the app should be overwritten, false otherwise
     * @throws InterruptedException if the thread was interrupted
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the install failed.
     */
    public void installAppAndVerifyExistsOnDevice(String apkPath, String pkgName, boolean overwrite)
            throws IOException, InterruptedException, InstallException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException {
        // Start with a clean slate if we're not overwriting
        if (!overwrite) {
            // cleanup test app just in case it already exists
            mDevice.uninstallPackage(pkgName);
            // grep for package to make sure its not installed
            assertFalse(doesPackageExist(pkgName));
        }

        installFile(apkPath, overwrite);
        assertFalse(doesAppExistOnSDCard(pkgName));
        assertTrue(doesAppExistOnDevice(pkgName));
        waitForPackageManager();

        // grep for package to make sure it is installed
        assertTrue(doesPackageExist(pkgName));
    }

    /**
     * Helper method for installing an app as forward-locked, and
     * then verifying the app was installed in the proper forward-locked location.
     * <p/>
     * Assumes adb is running as root in device under test.
     *
     * @param the path of the apk to install
     * @param the name of the package
     * @param <code>true if the app should be overwritten, false otherwise
     * @throws InterruptedException if the thread was interrupted
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the install failed.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     */
    public void installFwdLockedAppAndVerifyExists(String apkPath,
            String pkgName, boolean overwrite) throws IOException, InterruptedException,
            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
            ShellCommandUnresponsiveException {
        // Start with a clean slate if we're not overwriting
        if (!overwrite) {
            // cleanup test app just in case it already exists
            mDevice.uninstallPackage(pkgName);
            // grep for package to make sure its not installed
            assertFalse(doesPackageExist(pkgName));
        }

        String result = installFileForwardLocked(apkPath, overwrite);
        assertEquals(null, result);
        assertTrue(doesAppExistAsForwardLocked(pkgName));
        assertFalse(doesAppExistOnSDCard(pkgName));
        waitForPackageManager();

        // grep for package to make sure it is installed
        assertTrue(doesPackageExist(pkgName));
    }

    /**
     * Helper method for uninstalling an app.
     * <p/>
     * Assumes adb is running as root in device under test.
     *
     * @param pkgName package name to uninstall
     * @throws InterruptedException if the thread was interrupted
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the uninstall failed.
     */
    public void uninstallApp(String pkgName) throws IOException, InterruptedException,
            InstallException, TimeoutException, AdbCommandRejectedException,
            ShellCommandUnresponsiveException {
        mDevice.uninstallPackage(pkgName);
        // make sure its not installed anymore
        assertFalse(doesPackageExist(pkgName));
    }

    /**
     * Helper method for clearing any installed non-system apps.
     * Useful ensuring no non-system apps are installed, and for cleaning up stale files that
     * may be lingering on the system for whatever reason.
     * <p/>
     * Assumes adb is running as root in device under test.
     *
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     * @throws InstallException if the uninstall failed.
     */
    public void wipeNonSystemApps() throws IOException, TimeoutException,
            AdbCommandRejectedException, ShellCommandUnresponsiveException, InstallException {
      String allInstalledPackages = executeShellCommand("pm list packages -f");
      BufferedReader outputReader = new BufferedReader(new StringReader(allInstalledPackages));

      // First use Package Manager to uninstall all non-system apps
      String currentLine = null;
      while ((currentLine = outputReader.readLine()) != null) {
          // Skip over any system apps...
          if (currentLine.contains("/system/")) {
              continue;
          }
          String packageName = currentLine.substring(currentLine.indexOf('=') + 1);
          mDevice.uninstallPackage(packageName);
      }
      // Make sure there are no stale app files under these directories
      executeShellCommand(String.format("rm %s*", SDCARD_APP_PATH, "*"));
      executeShellCommand(String.format("rm %s*", DEVICE_APP_PATH, "*"));
      executeShellCommand(String.format("rm %s*", APP_PRIVATE_PATH, "*"));
    }

    /**
     * Sets the device's install location preference.
     *
     * <p/>
     * Assumes adb is running as root in device under test.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException,
            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        String command = "pm setInstallLocation %d";
        int locValue = 0;
        switch (pref) {
            case INTERNAL:
                locValue = 1;
                break;
            case EXTERNAL:
                locValue = 2;
                break;
            default: // AUTO
                locValue = 0;
                break;
        }
        executeShellCommand(String.format(command, locValue));
    }

    /**
     * Gets the device's install location preference.
     *
     * <p/>
     * Assumes adb is running as root in device under test.
     * @throws TimeoutException in case of a timeout on the connection.
     * @throws AdbCommandRejectedException if adb rejects the command
     * @throws ShellCommandUnresponsiveException if the device did not output anything for
     * a period longer than the max time to output.
     * @throws IOException if connection to device was lost.
     */
    public InstallLocPreference getDevicePreferredInstallLocation() throws IOException,
            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
        String result = executeShellCommand("pm getInstallLocation");
        if (result.indexOf('0') != -1) {
            return InstallLocPreference.AUTO;
        }
        else if (result.indexOf('1') != -1) {
            return InstallLocPreference.INTERNAL;
        }
        else {
            return InstallLocPreference.EXTERNAL;
        }
    }
}

Other Android examples (source code examples)

Here is a short list of links related to this Android PackageManagerHostTestUtils.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.