/*
 * 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 com.android.tradefed.device;

import com.android.ddmlib.IDevice;
import com.android.tradefed.log.ITestLogger;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.util.Bugreport;
import com.android.tradefed.util.KeyguardControllerState;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Provides an reliable and slightly higher level API to a ddmlib {@link IDevice}.
 * <p/>
 * Retries device commands for a configurable amount, and provides a device recovery
 * interface for devices which are unresponsive.
 */
public interface ITestDevice extends INativeDevice {

    public enum RecoveryMode {
        /** don't attempt to recover device. */
        NONE,
        /** recover device to online state only */
        ONLINE,
        /**
         * Recover device into fully testable state - framework is up, and external storage is
         * mounted.
         */
        AVAILABLE
    }

    /**
     * A simple struct class to store information about a single mountpoint
     */
    public static class MountPointInfo {
        public String filesystem;
        public String mountpoint;
        public String type;
        public List<String> options;

        /** Simple constructor */
        public MountPointInfo() {}

        /**
         * Convenience constructor to set all members
         */
        public MountPointInfo(String filesystem, String mountpoint, String type,
                List<String> options) {
            this.filesystem = filesystem;
            this.mountpoint = mountpoint;
            this.type = type;
            this.options = options;
        }

        public MountPointInfo(String filesystem, String mountpoint, String type, String optString) {
            this(filesystem, mountpoint, type, splitMountOptions(optString));
        }

        public static List<String> splitMountOptions(String options) {
            List<String> list = Arrays.asList(options.split(","));
            return list;
        }

        @Override
        public String toString() {
            return String.format("%s %s %s %s", this.filesystem, this.mountpoint, this.type,
                    this.options);
        }
    }

    /** A simple struct class to store information about a single APEX */
    public static class ApexInfo {
        public final String name;
        public final long versionCode;
        public final String sourceDir;

        public ApexInfo(String name, long versionCode, String sourceDir) {
            this.name = name;
            this.versionCode = versionCode;
            this.sourceDir = sourceDir;
        }

        public ApexInfo(String name, long versionCode) {
            this(name, versionCode, "");
        }

        @Override
        public boolean equals(Object other) {
            if (other != null && other instanceof ApexInfo) {
                ApexInfo ai = (ApexInfo) other;
                return name.equals(ai.name) && versionCode == ai.versionCode;
            }
            return false;
        }

        @Override
        public int hashCode() {
            // no need to consider versionCode here.
            return name.hashCode();
        }

        @Override
        public String toString() {
            return "packageName: "
                    + name
                    + ", versionCode: "
                    + versionCode
                    + ", sourceDir: "
                    + sourceDir;
        }
    }

    /**
     * Install an Android package on device.
     *
     * @param packageFile the apk file to install
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public String installPackage(File packageFile, boolean reinstall, String... extraArgs)
            throws DeviceNotAvailableException;

    /**
     * Install an Android package on device.
     *
     * <p>Note: Only use cases that requires explicit control of granting runtime permission at
     * install time should call this function.
     *
     * @param packageFile the apk file to install
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param grantPermissions if all runtime permissions should be granted at install time
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public String installPackage(
            File packageFile, boolean reinstall, boolean grantPermissions, String... extraArgs)
            throws DeviceNotAvailableException;

    /**
     * Install an Android package on device for a given user.
     *
     * @param packageFile the apk file to install
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param userId the integer user id to install for.
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public String installPackageForUser(
            File packageFile, boolean reinstall, int userId, String... extraArgs)
            throws DeviceNotAvailableException;

    /**
     * Install an Android package on device for a given user.
     *
     * <p>Note: Only use cases that requires explicit control of granting runtime permission at
     * install time should call this function.
     *
     * @param packageFile the apk file to install
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param grantPermissions if all runtime permissions should be granted at install time
     * @param userId the integer user id to install for.
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public String installPackageForUser(
            File packageFile,
            boolean reinstall,
            boolean grantPermissions,
            int userId,
            String... extraArgs)
            throws DeviceNotAvailableException;

    /**
     * Uninstall an Android package from device.
     *
     * @param packageName the Android package to uninstall
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public String uninstallPackage(String packageName) throws DeviceNotAvailableException;

    /**
     * Uninstall an Android package from device for a given user.
     *
     * @param packageName the Android package to uninstall
     * @param userId the integer user id to uninstall for.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public String uninstallPackageForUser(String packageName, int userId)
            throws DeviceNotAvailableException;

    /**
     * Install an Android application made of several APK files (one main and extra split packages).
     * See "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
     * several files.
     *
     * @param packageFiles the local apk files
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installPackages(
            List<File> packageFiles, boolean reinstall, String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }

    /**
     * Install an Android application made of several APK files (one main and extra split packages)
     * that are sitting on the android device. See
     * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
     * several files.
     *
     * <p>Note: Only use cases that requires explicit control of granting runtime permission at
     * install time should call this function.
     *
     * @param packageFiles the remote apk file paths to install
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param grantPermissions if all runtime permissions should be granted at install time
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installPackages(
            List<File> packageFiles,
            boolean reinstall,
            boolean grantPermissions,
            String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }

    /**
     * Install an Android application made of several APK files (one main and extra split packages)
     * for a given user. See "https://developer.android.com/studio/build/configure-apk-splits" on
     * how to split apk to several files.
     *
     * @param packageFiles the local apk files
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param userId the integer user id to install for.
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installPackagesForUser(
            List<File> packageFiles, boolean reinstall, int userId, String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }

    /**
     * Install an Android application made of several APK files (one main and extra split packages)
     * for a given user. See "https://developer.android.com/studio/build/configure-apk-splits" on
     * how to split apk to several files.
     *
     * <p>Note: Only use cases that requires explicit control of granting runtime permission at
     * install time should call this function.
     *
     * @param packageFiles the local apk files
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param grantPermissions if all runtime permissions should be granted at install time
     * @param userId the integer user id to install for.
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installPackagesForUser(
            List<File> packageFiles,
            boolean reinstall,
            boolean grantPermissions,
            int userId,
            String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }

    /**
     * Install an Android application made of several APK files (one main and extra split packages)
     * that are sitting on the android device. See
     * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
     * several files.
     *
     * <p>Note: Only use cases that requires explicit control of granting runtime permission at
     * install time should call this function.
     *
     * @param remoteApkPaths the remote apk file paths
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param grantPermissions if all runtime permissions should be granted at install time
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installRemotePackages(
            List<String> remoteApkPaths,
            boolean reinstall,
            boolean grantPermissions,
            String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }

    /**
     * Install an Android application made of several APK files (one main and extra split packages)
     * that are sitting on the android device. See
     * "https://developer.android.com/studio/build/configure-apk-splits" on how to split apk to
     * several files.
     *
     * @param remoteApkPaths the remote apk file paths
     * @param reinstall <code>true</code> if a reinstall should be performed
     * @param extraArgs optional extra arguments to pass. See 'adb shell pm -h' for available
     *     options.
     * @return a {@link String} with an error code, or <code>null</code> if success.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     * @throws UnsupportedOperationException if runtime permission is not supported by the platform
     *     on device.
     */
    public default String installRemotePackages(
            List<String> remoteApkPaths, boolean reinstall, String... extraArgs)
            throws DeviceNotAvailableException {
        throw new UnsupportedOperationException("No support for Package Manager's features");
    }


    /**
     * Grabs a screenshot from the device.
     *
     * @return a {@link InputStreamSource} of the screenshot in png format, or <code>null</code> if
     *         the screenshot was not successful.
     * @throws DeviceNotAvailableException
     */
    public InputStreamSource getScreenshot() throws DeviceNotAvailableException;

    /**
     * Grabs a screenshot from the device.
     * Recommended to use getScreenshot(format) instead with JPEG encoding for smaller size
     * @param format supported PNG, JPEG
     * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if
     *         the screenshot was not successful.
     * @throws DeviceNotAvailableException
     */
    public InputStreamSource getScreenshot(String format) throws DeviceNotAvailableException;

    /**
     * Grabs a screenshot from the device. Recommended to use {@link #getScreenshot(String)} instead
     * with JPEG encoding for smaller size.
     *
     * @param format supported PNG, JPEG
     * @param rescale if screenshot should be rescaled to reduce the size of resulting image
     * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if the
     *     screenshot was not successful.
     * @throws DeviceNotAvailableException
     */
    public InputStreamSource getScreenshot(String format, boolean rescale)
            throws DeviceNotAvailableException;

    /**
     * Grabs a screenshot from the device given display id. Format is PNG.
     *
     * <p>TODO: extend the implementations above to support 'format' and 'rescale'
     *
     * @param displayId the display id of the screen to get screenshot from.
     * @return a {@link InputStreamSource} of the screenshot in format, or <code>null</code> if the
     *     screenshot was not successful.
     * @throws DeviceNotAvailableException
     */
    public InputStreamSource getScreenshot(long displayId) throws DeviceNotAvailableException;

    /**
     * Clears the last connected wifi network. This should be called when starting a new invocation
     * to avoid connecting to the wifi network used in the previous test after device reboots.
     */
    public void clearLastConnectedWifiNetwork();

    /**
     * Connects to a wifi network.
     * <p/>
     * Turns on wifi and blocks until a successful connection is made to the specified wifi network.
     * Once a connection is made, the instance will try to restore the connection after every reboot
     * until {@link ITestDevice#disconnectFromWifi()} or
     * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
     *
     * @param wifiSsid the wifi ssid to connect to
     * @param wifiPsk PSK passphrase or null if unencrypted
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *         otherwise
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean connectToWifiNetwork(String wifiSsid, String wifiPsk)
            throws DeviceNotAvailableException;

    /**
     * Connects to a wifi network.
     * <p/>
     * Turns on wifi and blocks until a successful connection is made to the specified wifi network.
     * Once a connection is made, the instance will try to restore the connection after every reboot
     * until {@link ITestDevice#disconnectFromWifi()} or
     * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
     *
     * @param wifiSsid the wifi ssid to connect to
     * @param wifiPsk PSK passphrase or null if unencrypted
     * @param scanSsid whether to scan for hidden SSID for this network.
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *         otherwise
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean connectToWifiNetwork(String wifiSsid, String wifiPsk, boolean scanSsid)
            throws DeviceNotAvailableException;

    /**
     * Connects to a wifi network.
     *
     * <p>Turns on wifi and blocks until a successful connection is made with one of the wifi
     * networks given in the wifiSsidToPsk map. Once a connection is made, the instance will try to
     * restore the connection after every reboot until {@link ITestDevice#disconnectFromWifi()} or
     * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
     *
     * @param wifiSsidToPsk A map of wifi SSIDs to passwords.
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *     otherwise
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public boolean connectToWifiNetwork(Map<String, String> wifiSsidToPsk)
            throws DeviceNotAvailableException;

    /**
     * Connects to a wifi network.
     *
     * <p>Turns on wifi and blocks until a successful connection is made with one of the wifi
     * networks given in the wifiSsidToPsk map. Once a connection is made, the instance will try to
     * restore the connection after every reboot until {@link ITestDevice#disconnectFromWifi()} or
     * {@link ITestDevice#clearLastConnectedWifiNetwork()} is called.
     *
     * @param wifiSsidToPsk A map of wifi SSIDs to passwords.
     * @param scanSsid whether to scan for hidden SSIDs for this network.
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *     otherwise
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public boolean connectToWifiNetwork(Map<String, String> wifiSsidToPsk, boolean scanSsid)
            throws DeviceNotAvailableException;

    /**
     * A variant of {@link #connectToWifiNetwork(String, String)} that only connects if device
     * currently does not have network connectivity.
     *
     * @param wifiSsid
     * @param wifiPsk
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *         otherwise
     * @throws DeviceNotAvailableException
     */
    public boolean connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk)
            throws DeviceNotAvailableException;

    /**
     * A variant of {@link #connectToWifiNetwork(String, String)} that only connects if device
     * currently does not have network connectivity.
     *
     * @param wifiSsid
     * @param wifiPsk
     * @param scanSsid whether to scan for hidden SSID for this network
     * @return <code>true</code> if connected to wifi network successfully. <code>false</code>
     *         otherwise
     * @throws DeviceNotAvailableException
     */
    public boolean connectToWifiNetworkIfNeeded(String wifiSsid, String wifiPsk, boolean scanSsid)
            throws DeviceNotAvailableException;

    /**
     * Disconnects from a wifi network.
     * <p/>
     * Removes all networks from known networks list and disables wifi.
     *
     * @return <code>true</code> if disconnected from wifi network successfully. <code>false</code>
     *         if disconnect failed.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean disconnectFromWifi() throws DeviceNotAvailableException;

    /**
     * Test if wifi is enabled.
     * <p/>
     * Checks if wifi is enabled on device. Useful for asserting wifi status before tests that
     * shouldn't run with wifi, e.g. mobile data tests.
     *
     * @return <code>true</code> if wifi is enabled. <code>false</code> if disabled
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean isWifiEnabled() throws DeviceNotAvailableException;

    /**
     * Gets the device's IP address.
     *
     * @return the device's IP address, or <code>null</code> if device has no IP address
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public String getIpAddress() throws DeviceNotAvailableException;

    /**
     * Enables network monitoring on device.
     *
     * @return <code>true</code> if monitoring is enabled successfully. <code>false</code>
     *         if it failed.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean enableNetworkMonitor() throws DeviceNotAvailableException;

    /**
     * Disables network monitoring on device.
     *
     * @return <code>true</code> if monitoring is disabled successfully. <code>false</code>
     *         if it failed.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean disableNetworkMonitor() throws DeviceNotAvailableException;

    /**
     * Check that device has network connectivity.
     *
     * @return <code>true</code> if device has a working network connection,
     *          <code>false</code> overwise.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *          recovered.
     */
    public boolean checkConnectivity() throws DeviceNotAvailableException;

    /**
     * Attempt to dismiss any error dialogs currently displayed on device UI.
     *
     * @return <code>true</code> if no dialogs were present or dialogs were successfully cleared.
     *         <code>false</code> otherwise.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *             recovered.
     */
    public boolean clearErrorDialogs() throws DeviceNotAvailableException;

    /**
     * Return an object to get the current state of the keyguard or null if not supported.
     *
     * @return a {@link KeyguardControllerState} containing a snapshot of the state of the keyguard
     *     and returns Null if the Keyguard query is not supported.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public KeyguardControllerState getKeyguardState() throws DeviceNotAvailableException;

    /**
     * Fetch the test options for the device.
     *
     * @return {@link TestDeviceOptions} related to the device under test.
     */
    public TestDeviceOptions getOptions();

    /**
     * Fetch the application package names present on the device.
     *
     * @return {@link Set} of {@link String} package names currently installed on the device.
     * @throws DeviceNotAvailableException
     */
    public Set<String> getInstalledPackageNames() throws DeviceNotAvailableException;

    /**
     * Query the device for a given package name to check if it's currently installed or not.
     *
     * @return True if the package is reported as installed. False otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean isPackageInstalled(String packageName) throws DeviceNotAvailableException;

    /**
     * Query the device for a given package name and given user id to check if it's currently
     * installed or not for that user.
     *
     * @param packageName the package we are checking if it's installed.
     * @param userId The user id we are checking the package is installed for. If null, primary user
     *     zero will be used.
     * @return True if the package is reported as installed. False otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean isPackageInstalled(String packageName, String userId)
            throws DeviceNotAvailableException;

    /**
     * Fetch the information about APEXes activated on the device.
     *
     * @return {@link Set} of {@link ApexInfo} currently activated on the device
     * @throws DeviceNotAvailableException
     */
    public Set<ApexInfo> getActiveApexes() throws DeviceNotAvailableException;

    /**
     * Get the information about the mainline modules installed on the device.
     *
     * @return {@link Set} of {@link String} mainline modules currently installed on the device.
     * @throws DeviceNotAvailableException
     */
    public Set<String> getMainlineModuleInfo() throws DeviceNotAvailableException;

    /**
     * Fetch the application package names that can be uninstalled. This is presently defined as
     * non-system packages, and updated system packages.
     *
     * @return {@link Set} of uninstallable {@link String} package names currently installed on the
     *         device.
     * @throws DeviceNotAvailableException
     */
    public Set<String> getUninstallablePackageNames() throws DeviceNotAvailableException;

    /**
     * Fetch information about a package installed on device.
     *
     * @return the {@link PackageInfo} or <code>null</code> if information could not be retrieved
     * @throws DeviceNotAvailableException
     */
    public PackageInfo getAppPackageInfo(String packageName) throws DeviceNotAvailableException;

    /**
     * Fetch information of packages installed on the device.
     *
     * @return {@link List} of {@link PackageInfo}s installed on the device.
     * @throws DeviceNotAvailableException
     */
    public List<PackageInfo> getAppPackageInfos() throws DeviceNotAvailableException;

    /**
     * Determines if multi user is supported.
     *
     * @return true if multi user is supported, false otherwise
     * @throws DeviceNotAvailableException
     */
    public boolean isMultiUserSupported() throws DeviceNotAvailableException;

    /** Returns whether the device uses headless system user mode. */
    public boolean isHeadlessSystemUserMode() throws DeviceNotAvailableException;

    /** Returns whether it's allowed to switch to the headless SYSTEM user. */
    public boolean canSwitchToHeadlessSystemUser() throws DeviceNotAvailableException;

    /**
     * Returns whether the main user is a permanent admin and can't be deleted or downgraded to
     * non-admin status.
     */
    public boolean isMainUserPermanentAdmin() throws DeviceNotAvailableException;

    /**
     * Create a user with a given name and default flags 0.
     *
     * @param name of the user to create on the device
     * @return the integer for the user id created
     * @throws DeviceNotAvailableException
     */
    public int createUser(String name) throws DeviceNotAvailableException, IllegalStateException;

    /**
     * Create a user with a given name and the provided flags
     *
     * @param name of the user to create on the device
     * @param guest enable the user flag --guest during creation
     * @param ephemeral enable the user flag --ephemeral during creation
     * @return id of the created user
     * @throws DeviceNotAvailableException
     */
    public int createUser(String name, boolean guest, boolean ephemeral)
            throws DeviceNotAvailableException, IllegalStateException;

    /**
     * Create a user with a given name and the provided flags
     *
     * @param name of the user to create on the device
     * @param guest enable the user flag --guest during creation
     * @param ephemeral enable the user flag --ephemeral during creation
     * @param forTesting enable the test flag --for-testing during creation
     * @return id of the created user
     * @throws DeviceNotAvailableException
     */
    public int createUser(String name, boolean guest, boolean ephemeral, boolean forTesting)
            throws DeviceNotAvailableException, IllegalStateException;

    /**
     * Create a user with a given name and default flags 0.
     *
     * @param name of the user to create on the device
     * @return the integer for the user id created or -1 for error.
     * @throws DeviceNotAvailableException
     */
    public int createUserNoThrow(String name) throws DeviceNotAvailableException;

    /**
     * Remove a given user from the device.
     *
     * @param userId of the user to remove
     * @return true if we were successful in removing the user, false otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean removeUser(int userId) throws DeviceNotAvailableException;

    /**
     * Gets the list of users on the device. Will throw {@link DeviceRuntimeException} if output
     * from device is not as expected.
     *
     * @return the list of user ids.
     * @throws DeviceNotAvailableException
     * @throws DeviceRuntimeException
     */
    ArrayList<Integer> listUsers() throws DeviceNotAvailableException;

    /**
     * Gets the Map of useId to {@link UserInfo} on the device. Will throw {@link
     * DeviceRuntimeException} if output from device is not as expected.
     *
     * @return the list of UserInfo objects.
     * @throws DeviceNotAvailableException
     * @throws DeviceRuntimeException
     */
    public Map<Integer, UserInfo> getUserInfos() throws DeviceNotAvailableException;

    /**
     * Get the maximum number of supported users. Defaults to 0.
     *
     * @return an integer indicating the number of supported users
     * @throws DeviceNotAvailableException
     */
    public int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException;

    /**
     * Get the maximum number of supported simultaneously running users. Defaults to 0.
     *
     * @return an integer indicating the number of simultaneously running users
     * @throws DeviceNotAvailableException
     */
    public int getMaxNumberOfRunningUsersSupported() throws DeviceNotAvailableException;

    /**
     * Starts a given user in the background if it is currently stopped. If the user is already
     * running in the background, this method is a NOOP.
     * @param userId of the user to start in the background
     * @return true if the user was successfully started in the background.
     * @throws DeviceNotAvailableException
     */
    public boolean startUser(int userId) throws DeviceNotAvailableException;

    /**
     * Starts a given user in the background if it is currently stopped. If the user is already
     * running in the background, this method is a NOOP. Possible to provide extra flag to wait for
     * the operation to have effect.
     *
     * @param userId of the user to start in the background
     * @param waitFlag will make the command wait until user is started and unlocked.
     * @return true if the user was successfully started in the background.
     * @throws DeviceNotAvailableException
     */
    public boolean startUser(int userId, boolean waitFlag) throws DeviceNotAvailableException;

    /**
     * Starts a given user in the background, visible in the given display (i.e., allowing the user
     * to launch activities in that display).
     *
     * <p><b>NOTE: </b>this command doesn't check if the user exists, display is available, {@link
     * #isVisibleBackgroundUsersSupported() device supports such feature}, etc.
     *
     * @param userId of the user to start in the background
     * @param displayId display to start user visible on
     * @param waitFlag will make the command wait until user is started and unlocked.
     * @return {@code true} if the user was successfully started visible in the background.
     */
    public boolean startVisibleBackgroundUser(int userId, int displayId, boolean waitFlag)
            throws DeviceNotAvailableException;

    /**
     * Stops a given user. If the user is already stopped, this method is a NOOP.
     * Cannot stop current and system user.
     *
     * @param userId of the user to stop.
     * @return true if the user was successfully stopped.
     * @throws DeviceNotAvailableException
     */
    public boolean stopUser(int userId) throws DeviceNotAvailableException;

    /**
     * Stop a given user. Possible to provide extra flags to wait for the operation to have effect,
     * and force terminate the user. Cannot stop current and system user.
     *
     * @param userId of the user to stop.
     * @param waitFlag will make the command wait until user is stopped.
     * @param forceFlag will force stop the user.
     * @return true if the user was successfully stopped.
     * @throws DeviceNotAvailableException
     */
    public boolean stopUser(int userId, boolean waitFlag, boolean forceFlag)
            throws DeviceNotAvailableException;

    /**
     * Returns whether the device allow users to be started visible in the background.
     *
     * <p>If it does, you could call {@link #startVisibleBackgroundUser(int, int, boolean)}, passing
     * a display returned by {@link #listDisplayIdsForStartingVisibleBackgroundUsers()}.
     */
    public boolean isVisibleBackgroundUsersSupported() throws DeviceNotAvailableException;

    /**
     * Returns whether the device allow users to be started visible in the background in the {@link
     * java.android.view.Display#DEFAULT_DISPLAY}.
     *
     * <p>If it does, you could call {@link #startVisibleBackgroundUser(int, int, boolean)}, passing
     * a display returned by {@link #listDisplayIdsForStartingVisibleBackgroundUsers()} (which
     * should include {@link java.android.view.Display#DEFAULT_DISPLAY}).
     */
    public boolean isVisibleBackgroundUsersOnDefaultDisplaySupported()
            throws DeviceNotAvailableException;

    /**
     * Returns the primary user id.
     *
     * @return the userId of the primary user if there is one, and null if there is no primary user.
     * @throws DeviceNotAvailableException
     * @throws DeviceRuntimeException if the output from the device is not as expected.
     */
    public Integer getPrimaryUserId() throws DeviceNotAvailableException;

    /**
     * Returns the main user id.
     *
     * @return the userId of the main user if there is one, and null if there is no main user.
     * @throws DeviceNotAvailableException
     * @throws DeviceRuntimeException if the output from the device is not as expected.
     */
    public Integer getMainUserId() throws DeviceNotAvailableException;

    /**
     * Return the id of the current running user. In case of error, return -10000.
     *
     * @throws DeviceNotAvailableException
     */
    public int getCurrentUser() throws DeviceNotAvailableException;

    /**
     * Checks if the given user is visible.
     *
     * <p>A "visible" user is a user that is interacting with the "human" user and hence is able to
     * launch launch activities (typically in the default display).
     */
    public boolean isUserVisible(int userId) throws DeviceNotAvailableException;

    /**
     * Checks if the given user is visible in the given display.
     *
     * <p>A "visible" user is a user that is interacting with the "human" user and hence is able to
     * launch launch activities in that display.
     */
    public boolean isUserVisibleOnDisplay(int userId, int displayId)
            throws DeviceNotAvailableException;

    /**
     * Find and return the flags of a given user.
     * Flags are defined in "android.content.pm.UserInfo" class in Android Open Source Project.
     *
     * @return the flags associated with the userId provided if found, -10000 in any other cases.
     * @throws DeviceNotAvailableException
     */
    public int getUserFlags(int userId) throws DeviceNotAvailableException;

    /**
     * Return whether the specified user is a secondary user according to it's flags.
     *
     * @return true if the user is secondary, false otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean isUserSecondary(int userId) throws DeviceNotAvailableException;

    /**
     * Return the serial number associated to the userId if found, -10000 in any other cases.
     *
     * @throws DeviceNotAvailableException
     */
    public int getUserSerialNumber(int userId) throws DeviceNotAvailableException;

    /**
     * Switch to another userId with a default timeout. {@link #switchUser(int, long)}.
     *
     * @return True if the new userId matches the userId provider. False otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean switchUser(int userId) throws DeviceNotAvailableException;

    /**
     * Switch to another userId with the provided timeout as deadline.
     * Attempt to disable keyguard after user change is successful.
     *
     * @param timeout to wait before returning false for switch-user failed.
     * @return True if the new userId matches the userId provider. False otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean switchUser(int userId, long timeout) throws DeviceNotAvailableException;

    /**
     * Check if a given user is running.
     *
     * @return True if the user is running, false in every other cases.
     * @throws DeviceNotAvailableException
     */
    public boolean isUserRunning(int userId) throws DeviceNotAvailableException;

    /**
     * Check if a feature is available on a device.
     *
     * @param feature which format should be "feature:<name>" or "<name>" directly.
     * @return True if feature is found, false otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean hasFeature(String feature) throws DeviceNotAvailableException;

    /**
     * See {@link #getSetting(int, String, String)} and performed on system user.
     *
     * @throws DeviceNotAvailableException
     */
    public String getSetting(String namespace, String key) throws DeviceNotAvailableException;

    /**
     * Return the value of the requested setting.
     * namespace must be one of: {"system", "secure", "global"}
     *
     * @return the value associated with the namespace:key of a user. Null if not found.
     * @throws DeviceNotAvailableException
     */
    public String getSetting(int userId, String namespace, String key)
            throws DeviceNotAvailableException;

    /**
     * Return key value pairs of requested namespace.
     *
     * @param namespace must be one of {"system", "secure", "global"}
     * @return the map of key value pairs. Null if namespace is not supported.
     * @throws DeviceNotAvailableException
     */
    public Map<String, String> getAllSettings(String namespace) throws DeviceNotAvailableException;

    /**
     * See {@link #setSetting(int, String, String, String)} and performed on system user.
     *
     * @throws DeviceNotAvailableException
     */
    public void setSetting(String namespace, String key, String value)
            throws DeviceNotAvailableException;

    /**
     * Add a setting value to the namespace of a given user. Some settings will only be available
     * after a reboot.
     * namespace must be one of: {"system", "secure", "global"}
     *
     * @throws DeviceNotAvailableException
     */
    public void setSetting(int userId, String namespace, String key, String value)
            throws DeviceNotAvailableException;

    /**
     * Find and return the android-id associated to a userId, null if not found.
     *
     * @throws DeviceNotAvailableException
     */
    public String getAndroidId(int userId) throws DeviceNotAvailableException;

    /**
     * Create a Map of android ids found matching user ids. There is no insurance that each user
     * id will found an android id associated in this function so some user ids may match null.
     *
     * @return Map of android ids found matching user ids.
     * @throws DeviceNotAvailableException
     */
    public Map<Integer, String> getAndroidIds() throws DeviceNotAvailableException;

    /**
     * Set a device admin component as device owner in given user.
     *
     * @param componentName of device admin to be device owner.
     * @param userId of the user that the device owner lives in.
     * @return True if it is successful, false otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean setDeviceOwner(String componentName, int userId)
            throws DeviceNotAvailableException;

    /**
     * Remove given device admin in given user and return {@code true} if it is successful, {@code
     * false} otherwise.
     *
     * @param componentName of device admin to be removed.
     * @param userId of user that the device admin lives in.
     * @return True if it is successful, false otherwise.
     * @throws DeviceNotAvailableException
     */
    public boolean removeAdmin(String componentName, int userId) throws DeviceNotAvailableException;

    /**
     * Remove all existing device profile owners with the best effort.
     *
     * @throws DeviceNotAvailableException
     */
    public void removeOwners() throws DeviceNotAvailableException;

    /**
     * Attempts to disable the keyguard.
     * <p>
     * First wait for the input dispatch to become ready, this happens around the same time when the
     * device reports BOOT_COMPLETE, apparently asynchronously, because current framework
     * implementation has occasional race condition. Then command is sent to dismiss keyguard (works
     * on non-secure ones only)
     */
    public void disableKeyguard() throws DeviceNotAvailableException;

    /**
     * Attempt to dump the heap from the system_server. It is the caller responsibility to clean up
     * the dumped file.
     *
     * @param process the name of the device process to dumpheap on.
     * @param devicePath the path on the device where to put the dump. This must be a location where
     *     permissions allow it.
     * @return the {@link File} containing the report. Null if something failed.
     * @throws DeviceNotAvailableException
     */
    public File dumpHeap(String process, String devicePath) throws DeviceNotAvailableException;

    /**
     * Collect the list of available displays id on the device as reported by "dumpsys
     * SurfaceFlinger".
     *
     * @return The list of displays. Default always returns the default display 0.
     * @throws DeviceNotAvailableException
     */
    public Set<Long> listDisplayIds() throws DeviceNotAvailableException;

    /**
     * Gets the list of displays that can be used to {@link #startVisibleBackgroundUser(int, int,
     * boolean) start a user visible in the background}.
     */
    public Set<Integer> listDisplayIdsForStartingVisibleBackgroundUsers()
            throws DeviceNotAvailableException;

    /**
     * Returns the list of foldable states on the device. Can be obtained with "cmd device_state
     * print-states".
     *
     * @throws DeviceNotAvailableException
     */
    public Set<DeviceFoldableState> getFoldableStates() throws DeviceNotAvailableException;

    /**
     * Returns the current foldable state of the device or null if some issues occurred.
     *
     * @throws DeviceNotAvailableException
     */
    public DeviceFoldableState getCurrentFoldableState() throws DeviceNotAvailableException;

    /**
     * Helper method to determine if file on device exists for a given user.
     *
     * @param deviceFilePath the absolute path of file on device to check
     * @param userId The user id against which to check file existence
     * @return <code>true</code> if file exists, <code>false</code> otherwise.
     * @throws DeviceNotAvailableException if connection with device is lost and cannot be
     *     recovered.
     */
    public boolean doesFileExist(String deviceFilePath, int userId)
            throws DeviceNotAvailableException;

    /**
     * Registers a {@link IDeviceActionReceiver} for this device.
     *
     * <p>All registered {@link IDeviceActionReceiver}s will be notified before a device action
     * starts and after the device action ends.
     *
     * @param deviceActionReceiver A {@link IDeviceActionReceiver} which will be registered.
     */
    public void registerDeviceActionReceiver(IDeviceActionReceiver deviceActionReceiver);

    /**
     * Removes the registered {@link IDeviceActionReceiver}.
     *
     * @param deviceActionReceiver A {@link IDeviceActionReceiver} which will be removed.
     */
    public void deregisterDeviceActionReceiver(IDeviceActionReceiver deviceActionReceiver);

    /**
     * Retrieves a bugreport from the device.
     *
     * <p>The implementation of this is guaranteed to continue to work on a device without an sdcard
     * (or where the sdcard is not yet mounted).
     *
     * @return An {@link InputStreamSource} which will produce the bugreport contents on demand. In
     *     case of failure, the {@code InputStreamSource} will produce an empty {@link InputStream}.
     */
    public InputStreamSource getBugreport();

    /**
     * Retrieves a bugreportz from the device. Zip format bugreport contains the main bugreport and
     * other log files that are useful for debugging.
     *
     * <p>Only supported for 'adb version' > 1.0.36
     *
     * @return a {@link InputStreamSource} of the zip file containing the bugreportz, return null in
     *     case of failure.
     */
    public InputStreamSource getBugreportz();

    /**
     * Helper method to take a bugreport and log it to the reporters.
     *
     * @param dataName name under which the bugreport will be reported.
     * @param listener an {@link ITestLogger} to log the bugreport.
     * @return True if the logging was successful, false otherwise.
     */
    public boolean logBugreport(String dataName, ITestLogger listener);

    /**
     * Take a bugreport and returns it inside a {@link Bugreport} object to handle it. Return null
     * in case of issue. File referenced in the Bugreport object need to be cleaned via {@link
     * Bugreport#close()}.
     */
    public Bugreport takeBugreport();

    /** Notify the device to wait for snapuserd completion. */
    public default void notifySnapuserd(SnapuserdWaitPhase waitPhase) {
        // Empty on purpose
    }

    /** If expected, wait for snapuserd to complete. */
    public default void waitForSnapuserd(SnapuserdWaitPhase currentPhase)
            throws DeviceNotAvailableException {
        // Empty on purpose
    }
}
