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

Commit f8cef77b authored by RD Babiera's avatar RD Babiera
Browse files

Usb non-compliant port partner frameworks api

Adds supportsComplianceWarnings and getComplianceWarinings to support
querying non compliant USB port partner setups. COMPLIANCE_CHANGED
broadcast is broadcasted whenever a new port with non zero compliance
warnings list is added or when compliance warnings list changes for
an existing port.

Test: atest VtsAidlUsbTargetTest
      atest CtsUsbManagerTestCases
Bug: 236322506
Bug: 253298114
Change-Id: I29fab5f0191bbeb61ed54efd14838078647dd9a6
parent c2d3644f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -5442,6 +5442,7 @@ package android.hardware.usb {
    method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long);
    field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_ACCESSORY_HANDSHAKE = "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE";
    field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_CHANGED = "android.hardware.usb.action.USB_PORT_CHANGED";
    field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_COMPLIANCE_CHANGED = "android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED";
    field public static final String ACTION_USB_STATE = "android.hardware.usb.action.USB_STATE";
    field public static final String EXTRA_ACCESSORY_HANDSHAKE_END = "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END";
    field public static final String EXTRA_ACCESSORY_START = "android.hardware.usb.extra.ACCESSORY_START";
@@ -5469,6 +5470,7 @@ package android.hardware.usb {
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbPort(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
    method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean supportsComplianceWarnings();
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_INTERNAL = 1; // 0x1
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_NOT_SUPPORTED = 2; // 0x2
    field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_OTHER = 4; // 0x4
@@ -5494,6 +5496,7 @@ package android.hardware.usb {
  public final class UsbPortStatus implements android.os.Parcelable {
    method public int describeContents();
    method @CheckResult @NonNull public int[] getComplianceWarnings();
    method public int getCurrentDataRole();
    method public int getCurrentMode();
    method public int getCurrentPowerRole();
@@ -5504,6 +5507,10 @@ package android.hardware.usb {
    method public boolean isPowerTransferLimited();
    method public boolean isRoleCombinationSupported(int, int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int COMPLIANCE_WARNING_BC_1_2 = 3; // 0x3
    field public static final int COMPLIANCE_WARNING_DEBUG_ACCESSORY = 2; // 0x2
    field public static final int COMPLIANCE_WARNING_MISSING_RP = 4; // 0x4
    field public static final int COMPLIANCE_WARNING_OTHER = 1; // 0x1
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.usb.UsbPortStatus> CREATOR;
    field public static final int DATA_ROLE_DEVICE = 2; // 0x2
    field public static final int DATA_ROLE_HOST = 1; // 0x1
+13 −4
Original line number Diff line number Diff line
@@ -34,11 +34,13 @@ public final class ParcelableUsbPort implements Parcelable {
    private final int mSupportedContaminantProtectionModes;
    private final boolean mSupportsEnableContaminantPresenceProtection;
    private final boolean mSupportsEnableContaminantPresenceDetection;
    private final boolean mSupportsComplianceWarnings;

    private ParcelableUsbPort(@NonNull String id, int supportedModes,
            int supportedContaminantProtectionModes,
            boolean supportsEnableContaminantPresenceProtection,
            boolean supportsEnableContaminantPresenceDetection) {
            boolean supportsEnableContaminantPresenceDetection,
            boolean supportsComplianceWarnings) {
        mId = id;
        mSupportedModes = supportedModes;
        mSupportedContaminantProtectionModes = supportedContaminantProtectionModes;
@@ -46,6 +48,8 @@ public final class ParcelableUsbPort implements Parcelable {
                supportsEnableContaminantPresenceProtection;
        mSupportsEnableContaminantPresenceDetection =
                supportsEnableContaminantPresenceDetection;
        mSupportsComplianceWarnings =
                supportsComplianceWarnings;
    }

    /**
@@ -59,7 +63,8 @@ public final class ParcelableUsbPort implements Parcelable {
        return new ParcelableUsbPort(port.getId(), port.getSupportedModes(),
                port.getSupportedContaminantProtectionModes(),
                port.supportsEnableContaminantPresenceProtection(),
                port.supportsEnableContaminantPresenceDetection());
                port.supportsEnableContaminantPresenceDetection(),
                port.supportsComplianceWarnings());
    }

    /**
@@ -72,7 +77,8 @@ public final class ParcelableUsbPort implements Parcelable {
    public @NonNull UsbPort getUsbPort(@NonNull UsbManager usbManager) {
        return new UsbPort(usbManager, mId, mSupportedModes, mSupportedContaminantProtectionModes,
                mSupportsEnableContaminantPresenceProtection,
                mSupportsEnableContaminantPresenceDetection);
                mSupportsEnableContaminantPresenceDetection,
                mSupportsComplianceWarnings);
    }

    @Override
@@ -87,6 +93,7 @@ public final class ParcelableUsbPort implements Parcelable {
        dest.writeInt(mSupportedContaminantProtectionModes);
        dest.writeBoolean(mSupportsEnableContaminantPresenceProtection);
        dest.writeBoolean(mSupportsEnableContaminantPresenceDetection);
        dest.writeBoolean(mSupportsComplianceWarnings);
    }

    public static final @android.annotation.NonNull Creator<ParcelableUsbPort> CREATOR =
@@ -98,11 +105,13 @@ public final class ParcelableUsbPort implements Parcelable {
                    int supportedContaminantProtectionModes = in.readInt();
                    boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
                    boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
                    boolean supportsComplianceWarnings = in.readBoolean();

                    return new ParcelableUsbPort(id, supportedModes,
                            supportedContaminantProtectionModes,
                            supportsEnableContaminantPresenceProtection,
                            supportsEnableContaminantPresenceDetection);
                            supportsEnableContaminantPresenceDetection,
                            supportsComplianceWarnings);
                }

                @Override
+13 −0
Original line number Diff line number Diff line
@@ -113,6 +113,19 @@ public class UsbManager {
    public static final String ACTION_USB_PORT_CHANGED =
            "android.hardware.usb.action.USB_PORT_CHANGED";

     /**
     * Broadcast Action: A broadcast for USB compliance warning changes.
     *
     * This intent is sent when a port partner's
     * (USB power source/cable/accessory) compliance warnings change state.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    public static final String ACTION_USB_PORT_COMPLIANCE_CHANGED =
            "android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED";

   /**
     * Activity intent sent when user attaches a USB device.
     *
+70 −4
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_CONTAMINAN
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_DOCK;
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_DEBUG;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_BC_1_2;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_MISSING_RP;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_OTHER;

import android.Manifest;
import android.annotation.CallbackExecutor;
@@ -83,6 +87,7 @@ public final class UsbPort {
    private final int mSupportedContaminantProtectionModes;
    private final boolean mSupportsEnableContaminantPresenceProtection;
    private final boolean mSupportsEnableContaminantPresenceDetection;
    private final boolean mSupportsComplianceWarnings;

    private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES;
    /**
@@ -250,6 +255,18 @@ public final class UsbPort {
            int supportedContaminantProtectionModes,
            boolean supportsEnableContaminantPresenceProtection,
            boolean supportsEnableContaminantPresenceDetection) {
        this(usbManager, id, supportedModes, supportedContaminantProtectionModes,
                supportsEnableContaminantPresenceProtection,
                supportsEnableContaminantPresenceDetection,
                false);
    }

    /** @hide */
    public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes,
            int supportedContaminantProtectionModes,
            boolean supportsEnableContaminantPresenceProtection,
            boolean supportsEnableContaminantPresenceDetection,
            boolean supportsComplianceWarnings) {
        Objects.requireNonNull(id);
        Preconditions.checkFlagsArgument(supportedModes,
                MODE_DFP | MODE_UFP | MODE_AUDIO_ACCESSORY | MODE_DEBUG_ACCESSORY);
@@ -262,6 +279,7 @@ public final class UsbPort {
                supportsEnableContaminantPresenceProtection;
        mSupportsEnableContaminantPresenceDetection =
                supportsEnableContaminantPresenceDetection;
        mSupportsComplianceWarnings = supportsComplianceWarnings;
    }

    /**
@@ -330,6 +348,21 @@ public final class UsbPort {
        return mUsbManager.getPortStatus(this);
    }

    /**
     * Queries USB Port to see if the port is capable of identifying
     * non compliant USB power source/cable/accessory.
     *
     * @return true when the UsbPort is capable of identifying
     *             non compliant USB power
     *             source/cable/accessory.
     * @return false otherwise.
     */
    @CheckResult
    @RequiresPermission(Manifest.permission.MANAGE_USB)
    public boolean supportsComplianceWarnings() {
        return mSupportsComplianceWarnings;
    }

    /**
     * Sets the desired role combination of the port.
     * <p>
@@ -685,6 +718,37 @@ public final class UsbPort {
        return result.toString();
    }

    /** @hide */
    public static String complianceWarningsToString(@NonNull int[] complianceWarnings) {
        StringBuilder complianceWarningString = new StringBuilder();
        complianceWarningString.append("[");

        if (complianceWarnings != null) {
            for (int warning : complianceWarnings) {
                switch (warning) {
                    case UsbPortStatus.COMPLIANCE_WARNING_OTHER:
                        complianceWarningString.append("other, ");
                        break;
                    case UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY:
                        complianceWarningString.append("debug accessory, ");
                        break;
                    case UsbPortStatus.COMPLIANCE_WARNING_BC_1_2:
                        complianceWarningString.append("bc12, ");
                        break;
                    case UsbPortStatus.COMPLIANCE_WARNING_MISSING_RP:
                        complianceWarningString.append("missing rp, ");
                        break;
                    default:
                        complianceWarningString.append(String.format("Unknown(%d), ", warning));
                        break;
                }
            }
        }

        complianceWarningString.append("]");
        return complianceWarningString.toString().replaceAll(", ]$", "]");
    }

    /** @hide */
    public static void checkMode(int powerRole) {
        Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE,
@@ -720,10 +784,12 @@ public final class UsbPort {
    @Override
    public String toString() {
        return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes)
                + "supportedContaminantProtectionModes=" + mSupportedContaminantProtectionModes
                + "supportsEnableContaminantPresenceProtection="
                + ", supportedContaminantProtectionModes=" + mSupportedContaminantProtectionModes
                + ", supportsEnableContaminantPresenceProtection="
                + mSupportsEnableContaminantPresenceProtection
                + "supportsEnableContaminantPresenceDetection="
                + mSupportsEnableContaminantPresenceDetection;
                + ", supportsEnableContaminantPresenceDetection="
                + mSupportsEnableContaminantPresenceDetection
                + ", supportsComplianceWarnings="
                + mSupportsComplianceWarnings;
    }
}
+106 −14
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package android.hardware.usb;

import android.Manifest;
import android.annotation.CheckResult;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -46,6 +48,7 @@ public final class UsbPortStatus implements Parcelable {
    private final boolean mPowerTransferLimited;
    private final @UsbDataStatus int mUsbDataStatus;
    private final @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
    private final @NonNull @ComplianceWarning int[] mComplianceWarnings;

    /**
     * Power role: This USB port does not have a power role.
@@ -246,6 +249,41 @@ public final class UsbPortStatus implements Parcelable {
     */
    public static final int POWER_BRICK_STATUS_DISCONNECTED = 2;

    /**
     * Used to indicate attached sources/cables/accessories/ports
     * that do not match the other warnings below and do not meet the
     * requirements of specifications including but not limited to
     * USB Type-C Cable and Connector, Universal Serial Bus
     * Power Delivery, and Universal Serial Bus 1.x/2.0/3.x/4.0.
     * In addition, constants introduced after the target sdk will be
     * remapped into COMPLIANCE_WARNING_OTHER.
     */
    public static final int COMPLIANCE_WARNING_OTHER = 1;

    /**
     * Used to indicate Type-C port partner
     * (cable/accessory/source) that identifies itself as debug
     * accessory source as defined in USB Type-C Cable and
     * Connector Specification. However, the specification states
     * that this is meant for debug only and shall not be used for
     * with commercial products.
     */
    public static final int COMPLIANCE_WARNING_DEBUG_ACCESSORY = 2;

    /**
     * Used to indicate USB ports that does not
     * identify itself as one of the charging port types (SDP/CDP
     * DCP etc) as defined by Battery Charging v1.2 Specification.
     */
    public static final int COMPLIANCE_WARNING_BC_1_2 = 3;

    /**
     * Used to indicate Type-C sources/cables that are missing pull
     * up resistors on the CC pins as required by USB Type-C Cable
     * and Connector Specification.
     */
    public static final int COMPLIANCE_WARNING_MISSING_RP = 4;

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

    @IntDef(prefix = { "COMPLIANCE_WARNING_" }, value = {
            COMPLIANCE_WARNING_OTHER,
            COMPLIANCE_WARNING_DEBUG_ACCESSORY,
            COMPLIANCE_WARNING_BC_1_2,
            COMPLIANCE_WARNING_MISSING_RP,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface ComplianceWarning{}

    /** @hide */
    @IntDef(prefix = { "DATA_STATUS_" }, flag = true, value = {
            DATA_STATUS_UNKNOWN,
@@ -302,7 +349,8 @@ public final class UsbPortStatus implements Parcelable {
            int supportedRoleCombinations, int contaminantProtectionStatus,
            int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus,
            boolean powerTransferLimited,
            @PowerBrickConnectionStatus int powerBrickConnectionStatus) {
            @PowerBrickConnectionStatus int powerBrickConnectionStatus,
            @NonNull @ComplianceWarning int[] complianceWarnings) {
        mCurrentMode = currentMode;
        mCurrentPowerRole = currentPowerRole;
        mCurrentDataRole = currentDataRole;
@@ -312,21 +360,29 @@ public final class UsbPortStatus implements Parcelable {
        mUsbDataStatus = usbDataStatus;
        mPowerTransferLimited = powerTransferLimited;
        mPowerBrickConnectionStatus = powerBrickConnectionStatus;
        mComplianceWarnings = complianceWarnings;
    }

    /** @hide */
    public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
            int supportedRoleCombinations, int contaminantProtectionStatus,
            int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus,
            boolean powerTransferLimited,
            @PowerBrickConnectionStatus int powerBrickConnectionStatus) {
        this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
                contaminantProtectionStatus, contaminantDetectionStatus,
                usbDataStatus, powerTransferLimited, powerBrickConnectionStatus,
                new int[] {});
    }

    /** @hide */
    public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
            int supportedRoleCombinations, int contaminantProtectionStatus,
            int contaminantDetectionStatus) {
        mCurrentMode = currentMode;
        mCurrentPowerRole = currentPowerRole;
        mCurrentDataRole = currentDataRole;
        mSupportedRoleCombinations = supportedRoleCombinations;
        mContaminantProtectionStatus = contaminantProtectionStatus;
        mContaminantDetectionStatus = contaminantDetectionStatus;
        mUsbDataStatus = DATA_STATUS_UNKNOWN;
        mPowerBrickConnectionStatus = POWER_BRICK_STATUS_UNKNOWN;
        mPowerTransferLimited = false;
        this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
                contaminantProtectionStatus, contaminantDetectionStatus,
                DATA_STATUS_UNKNOWN, false, POWER_BRICK_STATUS_UNKNOWN,
                new int[] {});
    }

    /**
@@ -443,6 +499,21 @@ public final class UsbPortStatus implements Parcelable {
        return mPowerBrickConnectionStatus;
    }

    /**
     * Returns non compliant reasons, if any, for the connected
     * charger/cable/accessory/USB port.
     *
     * @return array including {@link #NON_COMPLIANT_REASON_DEBUG_ACCESSORY},
     *         {@link #NON_COMPLIANT_REASON_BC12},
     *         {@link #NON_COMPLIANT_REASON_MISSING_RP},
     *         or {@link #NON_COMPLIANT_REASON_TYPEC}
     */
    @CheckResult
    @NonNull
    public @ComplianceWarning int[] getComplianceWarnings() {
        return mComplianceWarnings;
    }

    @NonNull
    @Override
    public String toString() {
@@ -463,6 +534,8 @@ public final class UsbPortStatus implements Parcelable {
                + ", powerBrickConnectionStatus="
                        + UsbPort
                            .powerBrickConnectionStatusToString(getPowerBrickConnectionStatus())
                + ", complianceWarnings="
                        + UsbPort.complianceWarningsToString(getComplianceWarnings())
                + "}";
    }

@@ -482,6 +555,7 @@ public final class UsbPortStatus implements Parcelable {
        dest.writeInt(mUsbDataStatus);
        dest.writeBoolean(mPowerTransferLimited);
        dest.writeInt(mPowerBrickConnectionStatus);
        dest.writeIntArray(mComplianceWarnings);
    }

    public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
@@ -497,10 +571,12 @@ public final class UsbPortStatus implements Parcelable {
            int usbDataStatus = in.readInt();
            boolean powerTransferLimited = in.readBoolean();
            int powerBrickConnectionStatus = in.readInt();
            @ComplianceWarning int[] complianceWarnings = in.createIntArray();
            return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                    supportedRoleCombinations, contaminantProtectionStatus,
                    contaminantDetectionStatus, usbDataStatus, powerTransferLimited,
                    powerBrickConnectionStatus);
                    powerBrickConnectionStatus,
                    complianceWarnings);
        }

        @Override
@@ -524,6 +600,7 @@ public final class UsbPortStatus implements Parcelable {
        private boolean mPowerTransferLimited;
        private @UsbDataStatus int mUsbDataStatus;
        private @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
        private @ComplianceWarning int[] mComplianceWarnings;

        public Builder() {
            mCurrentMode = MODE_NONE;
@@ -533,6 +610,7 @@ public final class UsbPortStatus implements Parcelable {
            mContaminantDetectionStatus = CONTAMINANT_DETECTION_NOT_SUPPORTED;
            mUsbDataStatus = DATA_STATUS_UNKNOWN;
            mPowerBrickConnectionStatus = POWER_BRICK_STATUS_UNKNOWN;
            mComplianceWarnings = new int[] {};
        }

        /**
@@ -618,6 +696,20 @@ public final class UsbPortStatus implements Parcelable {
            return this;
        }

        /**
         * Sets the non-compliant charger reasons of {@link UsbPortStatus}
         *
         * @return Instance of {@link Builder}
         */
        @NonNull
        public Builder setComplianceWarnings(
                @NonNull int[] complianceWarnings) {
            mComplianceWarnings = complianceWarnings == null ? new int[] {} :
                    complianceWarnings;
            return this;
        }


        /**
         * Creates the {@link UsbPortStatus} object.
         */
@@ -626,7 +718,7 @@ public final class UsbPortStatus implements Parcelable {
            UsbPortStatus status = new UsbPortStatus(mCurrentMode, mCurrentPowerRole,
                    mCurrentDataRole, mSupportedRoleCombinations, mContaminantProtectionStatus,
                    mContaminantDetectionStatus, mUsbDataStatus, mPowerTransferLimited,
                    mPowerBrickConnectionStatus);
                    mPowerBrickConnectionStatus, mComplianceWarnings);
            return status;
        }
    };
Loading