Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d368d4ee authored by Badhri Jagan Sridharan's avatar Badhri Jagan Sridharan Committed by Android (Google) Code Review
Browse files

Merge "Add systemApis to allow data transfer over USB-C while being docked"

parents 615951d1 7212c8fd
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -5221,6 +5221,7 @@ package android.hardware.usb {
  public final class UsbPort {
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableLimitPowerTransfer(boolean);
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbDataWhileDocked();
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
    method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_INTERNAL = 1; // 0x1
@@ -5233,6 +5234,12 @@ package android.hardware.usb {
    field public static final int ENABLE_USB_DATA_ERROR_OTHER = 4; // 0x4
    field public static final int ENABLE_USB_DATA_ERROR_PORT_MISMATCH = 3; // 0x3
    field public static final int ENABLE_USB_DATA_SUCCESS = 0; // 0x0
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_DATA_ENABLED = 4; // 0x4
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_INTERNAL = 1; // 0x1
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_NOT_SUPPORTED = 2; // 0x2
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5; // 0x5
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH = 3; // 0x3
    field public static final int ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS = 0; // 0x0
  }
  public final class UsbPortStatus implements android.os.Parcelable {
@@ -5240,7 +5247,9 @@ package android.hardware.usb {
    method public int getCurrentDataRole();
    method public int getCurrentMode();
    method public int getCurrentPowerRole();
    method public int getPowerBrickStatus();
    method public int getSupportedRoleCombinations();
    method @Nullable public int[] getUsbDataStatus();
    method public boolean isConnected();
    method public boolean isPowerTransferLimited();
    method public boolean isRoleCombinationSupported(int, int);
@@ -5254,9 +5263,19 @@ package android.hardware.usb {
    field public static final int MODE_DFP = 2; // 0x2
    field public static final int MODE_NONE = 0; // 0x0
    field public static final int MODE_UFP = 1; // 0x1
    field public static final int POWER_BRICK_STATUS_CONNECTED = 1; // 0x1
    field public static final int POWER_BRICK_STATUS_DISCONNECTED = 2; // 0x2
    field public static final int POWER_BRICK_STATUS_UNKNOWN = 0; // 0x0
    field public static final int POWER_ROLE_NONE = 0; // 0x0
    field public static final int POWER_ROLE_SINK = 2; // 0x2
    field public static final int POWER_ROLE_SOURCE = 1; // 0x1
    field public static final int USB_DATA_STATUS_DISABLED_CONTAMINANT = 3; // 0x3
    field public static final int USB_DATA_STATUS_DISABLED_DEBUG = 6; // 0x6
    field public static final int USB_DATA_STATUS_DISABLED_DOCK = 4; // 0x4
    field public static final int USB_DATA_STATUS_DISABLED_FORCE = 5; // 0x5
    field public static final int USB_DATA_STATUS_DISABLED_OVERHEAT = 2; // 0x2
    field public static final int USB_DATA_STATUS_ENABLED = 1; // 0x1
    field public static final int USB_DATA_STATUS_UNKNOWN = 0; // 0x0
  }
}
+3 −0
Original line number Diff line number Diff line
@@ -139,6 +139,9 @@ interface IUsbManager
    /* Set USB data on or off */
    boolean enableUsbData(in String portId, boolean enable, int operationId, in IUsbOperationInternal callback);

    /* Enable USB data when disabled due to docking event  */
    void enableUsbDataWhileDocked(in String portId, int operationId, in IUsbOperationInternal callback);

    /* Gets the USB Hal Version. */
    int getUsbHalVersion();

+29 −0
Original line number Diff line number Diff line
@@ -1358,6 +1358,35 @@ public class UsbManager {
        }
    }

    /**
     * Should only be called by {@link UsbPort#enableUsbDataWhileDocked}.
     * <p>
     * Enables or disables USB data when disabled due to docking event.
     *
     * @param port USB port for which USB data needs to be enabled.
     * @param operationId operationId for the request.
     * @param callback callback object to be invoked when the operation is complete.
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    void enableUsbDataWhileDocked(@NonNull UsbPort port, int operationId,
            IUsbOperationInternal callback) {
        Objects.requireNonNull(port, "enableUsbDataWhileDocked: port must not be null. opId:"
                + operationId);
        try {
            mService.enableUsbDataWhileDocked(port.getId(), operationId, callback);
        } catch (RemoteException e) {
            Log.e(TAG, "enableUsbDataWhileDocked: failed. opId:" + operationId, e);
            try {
                callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
            } catch (RemoteException r) {
                Log.e(TAG, "enableUsbDataWhileDocked: failed to call onOperationComplete. opId:"
                        + operationId, r);
            }
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Sets the component that will handle USB device connection.
     * <p>
+148 −0
Original line number Diff line number Diff line
@@ -33,9 +33,19 @@ import static android.hardware.usb.UsbPortStatus.MODE_DFP;
import static android.hardware.usb.UsbPortStatus.MODE_DUAL;
import static android.hardware.usb.UsbPortStatus.MODE_NONE;
import static android.hardware.usb.UsbPortStatus.MODE_UFP;
import static android.hardware.usb.UsbPortStatus.POWER_BRICK_STATUS_DISCONNECTED;
import static android.hardware.usb.UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN;
import static android.hardware.usb.UsbPortStatus.POWER_BRICK_STATUS_CONNECTED;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_NONE;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_UNKNOWN;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_ENABLED;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_DISABLED_OVERHEAT;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_DISABLED_CONTAMINANT;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_DISABLED_DOCK;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_DISABLED_FORCE;
import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_DISABLED_DEBUG;

import android.Manifest;
import android.annotation.CheckResult;
@@ -154,6 +164,48 @@ public final class UsbPort {
    @Retention(RetentionPolicy.SOURCE)
    @interface EnableLimitPowerTransferStatus{}

    /**
     * The {@link #enableUsbDataWhileDocked} request was successfully completed.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS = 0;

    /**
     * The {@link #enableUsbDataWhileDocked} request failed due to internal error.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_INTERNAL = 1;

    /**
     * The {@link #enableUsbDataWhileDocked} request failed as it's not supported.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_NOT_SUPPORTED = 2;

    /**
     * The {@link #enableUsbDataWhileDocked} request failed as port id mismatched.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH = 3;

    /**
     * The {@link #enableUsbDataWhileDocked} request failed as data is still enabled.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_DATA_ENABLED = 4;

    /**
     * The {@link #enableUsbDataWhileDocked} request failed due to other reasons.
     */
    public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5;

    /** @hide */
    @IntDef(prefix = { "ENABLE_USB_DATA_WHILE_DOCKED_" }, value = {
            ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS,
            ENABLE_USB_DATA_WHILE_DOCKED_ERROR_INTERNAL,
            ENABLE_USB_DATA_WHILE_DOCKED_ERROR_NOT_SUPPORTED,
            ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH,
            ENABLE_USB_DATA_WHILE_DOCKED_ERROR_DATA_ENABLED,
            ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface EnableUsbDataWhileDockedStatus{}

    /** @hide */
    public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes,
            int supportedContaminantProtectionModes,
@@ -307,6 +359,51 @@ public final class UsbPort {
        }
    }

    /**
     * Enables Usb data when disabled due to {@link UsbPort#USB_DATA_STATUS_DISABLED_DOCK}
     *
     * @return {@link #ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS} when request completes successfully or
     *         {@link #ENABLE_USB_DATA_WHILE_DOCKED_ERROR_INTERNAL} when request fails due to
     *         internal error or
     *         {@link ENABLE_USB_DATA_WHILE_DOCKED_ERROR_NOT_SUPPORTED} when not supported or
     *         {@link ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH} when request fails due to
     *         port id mismatch or
     *         {@link ENABLE_USB_DATA_WHILE_DOCKED_ERROR_DATA_ENABLED} when request fails as data
     *         is still enabled or
     *         {@link ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER} when fails due to other reasons.
     */
    @CheckResult
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    public @EnableUsbDataWhileDockedStatus int enableUsbDataWhileDocked() {
        // UID is added To minimize operationID overlap between two different packages.
        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
        Log.i(TAG, "enableUsbData opId:" + operationId
                + " callingUid:" + Binder.getCallingUid());
        UsbPortStatus portStatus = getStatus();
        if (portStatus != null &&
                !usbDataStatusToString(portStatus.getUsbDataStatus()).contains("disabled-dock")) {
            return ENABLE_USB_DATA_WHILE_DOCKED_ERROR_DATA_ENABLED;
        }

        UsbOperationInternal opCallback =
                new UsbOperationInternal(operationId, mId);
        mUsbManager.enableUsbDataWhileDocked(this, operationId, opCallback);
                opCallback.waitForOperationComplete();
        int result = opCallback.getStatus();
        switch (result) {
            case USB_OPERATION_SUCCESS:
                return ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS;
            case USB_OPERATION_ERROR_INTERNAL:
                return ENABLE_USB_DATA_WHILE_DOCKED_ERROR_INTERNAL;
            case USB_OPERATION_ERROR_NOT_SUPPORTED:
                return ENABLE_USB_DATA_WHILE_DOCKED_ERROR_NOT_SUPPORTED;
            case USB_OPERATION_ERROR_PORT_MISMATCH:
                return ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH;
            default:
                return ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER;
        }
    }

    /**
     * Limits power transfer In and out of the port.
     * <p>
@@ -445,6 +542,57 @@ public final class UsbPort {
        }
    }

    /** @hide */
    public static String usbDataStatusToString(int usbDataStatus) {
        switch (usbDataStatus) {
            case USB_DATA_STATUS_UNKNOWN:
                return "unknown";
            case USB_DATA_STATUS_ENABLED:
                return "enabled";
            case USB_DATA_STATUS_DISABLED_OVERHEAT:
                return "disabled-overheat";
            case USB_DATA_STATUS_DISABLED_CONTAMINANT:
                return "disabled-contaminant";
            case USB_DATA_STATUS_DISABLED_DOCK:
                return "disabled-dock";
            case USB_DATA_STATUS_DISABLED_FORCE:
                return "disabled-force";
            case USB_DATA_STATUS_DISABLED_DEBUG:
                return "disabled-debug";
            default:
                return Integer.toString(usbDataStatus);
        }
    }

    /** @hide */
    public static String usbDataStatusToString(int[] usbDataStatus) {
        StringBuilder modeString = new StringBuilder();
        if (usbDataStatus == null) {
            return "unknown";
        }
        for (int i = 0; i < usbDataStatus.length; i++) {
            modeString.append(usbDataStatusToString(usbDataStatus[i]));
            if (i < usbDataStatus.length - 1) {
                modeString.append(", ");
            }
        }
        return modeString.toString();
    }

    /** @hide */
    public static String powerBrickStatusToString(int powerBrickStatus) {
        switch (powerBrickStatus) {
            case POWER_BRICK_STATUS_UNKNOWN:
                return "unknown";
            case POWER_BRICK_STATUS_CONNECTED:
                return "connected";
            case POWER_BRICK_STATUS_DISCONNECTED:
                return "disconnected";
            default:
                return Integer.toString(powerBrickStatus);
        }
    }

    /** @hide */
    public static String roleCombinationsToString(int combo) {
        StringBuilder result = new StringBuilder();
+112 −13
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.hardware.usb;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,8 +43,9 @@ public final class UsbPortStatus implements Parcelable {
    private final int mSupportedRoleCombinations;
    private final @ContaminantProtectionStatus int mContaminantProtectionStatus;
    private final @ContaminantDetectionStatus int mContaminantDetectionStatus;
    private final boolean mUsbDataEnabled;
    private final boolean mPowerTransferLimited;
    private final @UsbDataStatus int[] mUsbDataStatus;
    private final @PowerBrickStatus int mPowerBrickStatus;

    /**
     * Power role: This USB port does not have a power role.
@@ -193,6 +195,57 @@ public final class UsbPortStatus implements Parcelable {
     */
    public static final int CONTAMINANT_PROTECTION_DISABLED = 1 << 3;

    /**
     * USB data status is not known.
     */
    public static final int USB_DATA_STATUS_UNKNOWN = 0;

    /**
     * USB data is enabled.
     */
    public static final int USB_DATA_STATUS_ENABLED = 1;

    /**
     * USB data is disabled as the port is too hot.
     */
    public static final int USB_DATA_STATUS_DISABLED_OVERHEAT = 2;

    /**
     * USB data is disabled due to contaminated port.
     */
    public static final int USB_DATA_STATUS_DISABLED_CONTAMINANT = 3;

    /**
     * USB data is disabled due to docking event.
     */
    public static final int USB_DATA_STATUS_DISABLED_DOCK = 4;

    /**
     * USB data is disabled by
     * {@link UsbPort#enableUsbData UsbPort.enableUsbData}.
     */
    public static final int USB_DATA_STATUS_DISABLED_FORCE = 5;

    /**
     * USB data is disabled for debug.
     */
    public static final int USB_DATA_STATUS_DISABLED_DEBUG = 6;

    /**
     * Unknown whether a power brick is connected.
     */
    public static final int POWER_BRICK_STATUS_UNKNOWN = 0;

    /**
     * The connected device is a power brick.
     */
    public static final int POWER_BRICK_STATUS_CONNECTED = 1;

    /**
     * The connected device is not power brick.
     */
    public static final int POWER_BRICK_STATUS_DISCONNECTED = 2;

    @IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = {
            CONTAMINANT_DETECTION_NOT_SUPPORTED,
            CONTAMINANT_DETECTION_DISABLED,
@@ -222,19 +275,42 @@ public final class UsbPortStatus implements Parcelable {
    @Retention(RetentionPolicy.SOURCE)
    @interface UsbPortMode{}

    /** @hide */
    @IntDef(prefix = { "USB_DATA_STATUS_" }, value = {
            USB_DATA_STATUS_UNKNOWN,
            USB_DATA_STATUS_ENABLED,
            USB_DATA_STATUS_DISABLED_OVERHEAT,
            USB_DATA_STATUS_DISABLED_CONTAMINANT,
            USB_DATA_STATUS_DISABLED_DOCK,
            USB_DATA_STATUS_DISABLED_FORCE,
            USB_DATA_STATUS_DISABLED_DEBUG
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface UsbDataStatus{}

    /** @hide */
    @IntDef(prefix = { "POWER_BRICK_STATUS_" }, value = {
            POWER_BRICK_STATUS_UNKNOWN,
            POWER_BRICK_STATUS_DISCONNECTED,
            POWER_BRICK_STATUS_CONNECTED,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface PowerBrickStatus{}

    /** @hide */
    public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
            int supportedRoleCombinations, int contaminantProtectionStatus,
            int contaminantDetectionStatus, boolean usbDataEnabled,
            boolean powerTransferLimited) {
            int contaminantDetectionStatus, @UsbDataStatus int[] usbDataStatus,
            boolean powerTransferLimited, @PowerBrickStatus int powerBrickStatus) {
        mCurrentMode = currentMode;
        mCurrentPowerRole = currentPowerRole;
        mCurrentDataRole = currentDataRole;
        mSupportedRoleCombinations = supportedRoleCombinations;
        mContaminantProtectionStatus = contaminantProtectionStatus;
        mContaminantDetectionStatus = contaminantDetectionStatus;
        mUsbDataEnabled = usbDataEnabled;
        mUsbDataStatus = usbDataStatus;
        mPowerTransferLimited = powerTransferLimited;
        mPowerBrickStatus = powerBrickStatus;
    }

    /** @hide */
@@ -247,7 +323,8 @@ public final class UsbPortStatus implements Parcelable {
        mSupportedRoleCombinations = supportedRoleCombinations;
        mContaminantProtectionStatus = contaminantProtectionStatus;
        mContaminantDetectionStatus = contaminantDetectionStatus;
        mUsbDataEnabled = true;
        mUsbDataStatus = new int[]{USB_DATA_STATUS_UNKNOWN};
        mPowerBrickStatus = POWER_BRICK_STATUS_UNKNOWN;
        mPowerTransferLimited = false;
    }

@@ -334,10 +411,14 @@ public final class UsbPortStatus implements Parcelable {
    /**
     * Returns UsbData status.
     *
     * @hide
     */
    public boolean getUsbDataStatus() {
        return mUsbDataEnabled;
     * @return Current USB data status of the port: {@link #USB_DATA_STATUS_UNKNOWN}
     *         or {@link #USB_DATA_STATUS_ENABLED} or {@link #USB_DATA_STATUS_DIASBLED_OVERHEAT}
     *         or {@link #USB_DATA_STATUS_DISABLED_CONTAMINANT}
     *         or {@link #USB_DATA_STATUS_DISABLED_DOCK} or {@link #USB_DATA_STATUS_DISABLED_FORCE}
     *         or {@link #USB_DATA_STATUS_DISABLED_DEBUG}
     */
    public @UsbDataStatus @Nullable int[] getUsbDataStatus() {
        return mUsbDataStatus;
    }

    /**
@@ -350,6 +431,17 @@ public final class UsbPortStatus implements Parcelable {
        return mPowerTransferLimited;
    }

    /**
     * Let's the caller know if a power brick is connected to the USB port.
     *
     * @return {@link #POWER_BRICK_STATUS_UNKNOWN}
     *         or {@link #POWER_BRICK_STATUS_CONNECTED}
     *         or {@link #POWER_BRICK_STATUS_DISCONNECTED}
     */
    public @PowerBrickStatus int getPowerBrickStatus() {
        return mPowerBrickStatus;
    }

    @NonNull
    @Override
    public String toString() {
@@ -363,10 +455,12 @@ public final class UsbPortStatus implements Parcelable {
                        + getContaminantDetectionStatus()
                + ", contaminantProtectionStatus="
                        + getContaminantProtectionStatus()
                + ", usbDataEnabled="
                        + getUsbDataStatus()
                + ", usbDataStatus="
                        + UsbPort.usbDataStatusToString(getUsbDataStatus())
                + ", isPowerTransferLimited="
                        + isPowerTransferLimited()
                +", powerBrickStatus="
                        + UsbPort.powerBrickStatusToString(getPowerBrickStatus())
                + "}";
    }

@@ -383,8 +477,10 @@ public final class UsbPortStatus implements Parcelable {
        dest.writeInt(mSupportedRoleCombinations);
        dest.writeInt(mContaminantProtectionStatus);
        dest.writeInt(mContaminantDetectionStatus);
        dest.writeBoolean(mUsbDataEnabled);
        dest.writeInt(mUsbDataStatus.length);
        dest.writeIntArray(mUsbDataStatus);
        dest.writeBoolean(mPowerTransferLimited);
        dest.writeInt(mPowerBrickStatus);
    }

    public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
@@ -397,11 +493,14 @@ public final class UsbPortStatus implements Parcelable {
            int supportedRoleCombinations = in.readInt();
            int contaminantProtectionStatus = in.readInt();
            int contaminantDetectionStatus = in.readInt();
            boolean usbDataEnabled = in.readBoolean();
            int[] usbDataStatus = new int[in.readInt()];
            in.readIntArray(usbDataStatus);
            boolean powerTransferLimited = in.readBoolean();
            int powerBrickStatus = in.readInt();
            return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                    supportedRoleCombinations, contaminantProtectionStatus,
                    contaminantDetectionStatus, usbDataEnabled, powerTransferLimited);
                    contaminantDetectionStatus, usbDataStatus, powerTransferLimited,
                    powerBrickStatus);
        }

        @Override
Loading