From 7212c8fda4942546a33f632ea5247ceb73005a4d Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Mon, 27 Dec 2021 02:50:50 -0800 Subject: [PATCH] Add systemApis to allow data transfer over USB-C while being docked This change adds two systemApis to UsbPortStatus viz., a. getUsbDataStatus: Allows caller to infer whether USB data is enabled. b. getPowerBrickStatus: Allows caller to infer whether a power brick is connected to the USB port. The change also adds enableUsbDataWhileDocked systemApi to UsbPort to enable Usb data momentarily. Bug: 211677613 Bug: 213312081 Test: Manually tested on tablet CTS-Coverage-Bug: 215019881 Signed-off-by: Badhri Jagan Sridharan Change-Id: Ib7521f0f04b7f8e3e58dc253b28072d3631f21a7 --- core/api/system-current.txt | 19 +++ .../android/hardware/usb/IUsbManager.aidl | 3 + .../java/android/hardware/usb/UsbManager.java | 29 ++++ core/java/android/hardware/usb/UsbPort.java | 148 ++++++++++++++++++ .../android/hardware/usb/UsbPortStatus.java | 125 +++++++++++++-- .../com/android/internal/usb/DumpUtils.java | 6 +- core/proto/android/service/usb.proto | 3 +- .../android/server/usb/UsbPortManager.java | 99 ++++++++++-- .../com/android/server/usb/UsbService.java | 26 +++ .../server/usb/hal/port/RawPortInfo.java | 26 +-- .../server/usb/hal/port/UsbPortAidl.java | 80 +++++++++- .../server/usb/hal/port/UsbPortHal.java | 18 ++- .../server/usb/hal/port/UsbPortHidl.java | 35 +++-- 13 files changed, 560 insertions(+), 57 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 7a76f7a3b5348..0c84c9756bde2 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -4688,6 +4688,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 @@ -4700,6 +4701,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 { @@ -4707,7 +4714,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); @@ -4721,9 +4730,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 } } diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 1d0837e3f1188..459dab1bffe16 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -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(); diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index eb3e84d27c7c8..f0e040ed4686a 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -1358,6 +1358,35 @@ public class UsbManager { } } + /** + * Should only be called by {@link UsbPort#enableUsbDataWhileDocked}. + *

+ * 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. *

diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java index e908c245fc8eb..bef4dea019a23 100644 --- a/core/java/android/hardware/usb/UsbPort.java +++ b/core/java/android/hardware/usb/UsbPort.java @@ -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. *

@@ -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(); diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java index 934c5067c11fa..d1f424667d730 100644 --- a/core/java/android/hardware/usb/UsbPortStatus.java +++ b/core/java/android/hardware/usb/UsbPortStatus.java @@ -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 + * @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 boolean getUsbDataStatus() { - return mUsbDataEnabled; + 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 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 diff --git a/core/java/com/android/internal/usb/DumpUtils.java b/core/java/com/android/internal/usb/DumpUtils.java index b06a7f4e56e41..b32a6b078884f 100644 --- a/core/java/com/android/internal/usb/DumpUtils.java +++ b/core/java/com/android/internal/usb/DumpUtils.java @@ -244,10 +244,12 @@ public class DumpUtils { writeContaminantPresenceStatus(dump, "contaminant_presence_status", UsbPortStatusProto.CONTAMINANT_PRESENCE_STATUS, status.getContaminantDetectionStatus()); - dump.write("usb_data_enabled", UsbPortStatusProto.USB_DATA_ENABLED, - status.getUsbDataStatus()); + dump.write("usb_data_status", UsbPortStatusProto.USB_DATA_STATUS, + UsbPort.usbDataStatusToString(status.getUsbDataStatus())); dump.write("is_power_transfer_limited", UsbPortStatusProto.IS_POWER_TRANSFER_LIMITED, status.isPowerTransferLimited()); + dump.write("usb_power_brick_status", UsbPortStatusProto.USB_POWER_BRICK_STATUS, + UsbPort.powerBrickStatusToString(status.getPowerBrickStatus())); dump.end(token); } } diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto index b3f54f9afce23..c5eaf42784ab4 100644 --- a/core/proto/android/service/usb.proto +++ b/core/proto/android/service/usb.proto @@ -264,8 +264,9 @@ message UsbPortStatusProto { optional DataRole data_role = 4; repeated UsbPortStatusRoleCombinationProto role_combinations = 5; optional android.service.ContaminantPresenceStatus contaminant_presence_status = 6; - optional bool usb_data_enabled = 7; + optional string usb_data_status = 7; optional bool is_power_transfer_limited = 8; + optional string usb_power_brick_status = 9; } message UsbPortStatusRoleCombinationProto { diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 98173adfd0eb4..65b79bfbb36f2 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -383,6 +383,46 @@ public class UsbPortManager { } } + /** + * Enables USB data when disabled due to {@link UsbPortStatus#USB_DATA_STATUS_DISABLED_DOCK} + */ + public void enableUsbDataWhileDocked(@NonNull String portId, long transactionId, + IUsbOperationInternal callback, IndentingPrintWriter pw) { + Objects.requireNonNull(portId); + final PortInfo portInfo = mPorts.get(portId); + if (portInfo == null) { + logAndPrint(Log.ERROR, pw, "enableUsbDataWhileDocked: No such port: " + portId + + " opId:" + transactionId); + try { + if (callback != null) { + callback.onOperationComplete(USB_OPERATION_ERROR_PORT_MISMATCH); + } + } catch (RemoteException e) { + logAndPrintException(pw, + "enableUsbDataWhileDocked: Failed to call OperationComplete. opId:" + + transactionId, e); + } + return; + } + + try { + try { + mUsbPortHal.enableUsbDataWhileDocked(portId, transactionId, callback); + } catch (Exception e) { + logAndPrintException(pw, + "enableUsbDataWhileDocked: Failed to limit power transfer. opId:" + + transactionId , e); + if (callback != null) { + callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL); + } + } + } catch (RemoteException e) { + logAndPrintException(pw, + "enableUsbDataWhileDocked:Failed to call onOperationComplete. opId:" + + transactionId, e); + } + } + /** * Enable/disable the USB data signaling * @@ -759,8 +799,9 @@ public class UsbPortManager { portInfo.contaminantProtectionStatus, portInfo.supportsEnableContaminantPresenceDetection, portInfo.contaminantDetectionStatus, - portInfo.usbDataEnabled, - portInfo.powerTransferLimited, pw); + portInfo.usbDataStatus, + portInfo.powerTransferLimited, + portInfo.powerBrickStatus, pw); } } else { for (RawPortInfo currentPortInfo : newPortInfo) { @@ -773,8 +814,9 @@ public class UsbPortManager { currentPortInfo.contaminantProtectionStatus, currentPortInfo.supportsEnableContaminantPresenceDetection, currentPortInfo.contaminantDetectionStatus, - currentPortInfo.usbDataEnabled, - currentPortInfo.powerTransferLimited, pw); + currentPortInfo.usbDataStatus, + currentPortInfo.powerTransferLimited, + currentPortInfo.powerBrickStatus, pw); } } @@ -810,8 +852,9 @@ public class UsbPortManager { int contaminantProtectionStatus, boolean supportsEnableContaminantPresenceDetection, int contaminantDetectionStatus, - boolean usbDataEnabled, + int[] usbDataStatus, boolean powerTransferLimited, + int powerBrickStatus, IndentingPrintWriter pw) { // Only allow mode switch capability for dual role ports. // Validate that the current mode matches the supported modes we expect. @@ -870,8 +913,8 @@ public class UsbPortManager { currentPowerRole, canChangePowerRole, currentDataRole, canChangeDataRole, supportedRoleCombinations, contaminantProtectionStatus, - contaminantDetectionStatus, usbDataEnabled, - powerTransferLimited); + contaminantDetectionStatus, usbDataStatus, + powerTransferLimited, powerBrickStatus); mPorts.put(portId, portInfo); } else { // Validate that ports aren't changing definition out from under us. @@ -908,8 +951,8 @@ public class UsbPortManager { currentPowerRole, canChangePowerRole, currentDataRole, canChangeDataRole, supportedRoleCombinations, contaminantProtectionStatus, - contaminantDetectionStatus, usbDataEnabled, - powerTransferLimited)) { + contaminantDetectionStatus, usbDataStatus, + powerTransferLimited, powerBrickStatus)) { portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED; } else { portInfo.mDisposition = PortInfo.DISPOSITION_READY; @@ -1135,7 +1178,9 @@ public class UsbPortManager { != supportedRoleCombinations) { mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations, UsbPortStatus.CONTAMINANT_PROTECTION_NONE, - UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED, true, false); + UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED, + new int[]{UsbPortStatus.USB_DATA_STATUS_UNKNOWN}, false, + UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN); dispositionChanged = true; } @@ -1150,12 +1195,31 @@ public class UsbPortManager { return dispositionChanged; } + private boolean dataStatusEquals(int[] dataStatusL, int[] dataStatusR) { + if (dataStatusL == null && dataStatusR == null) { + return true; + } + if ((dataStatusL == null && dataStatusR != null) + || (dataStatusL != null && dataStatusR == null)) { + return false; + } + if (dataStatusL.length != dataStatusR.length) { + return false; + } + for (int i = 0; i < dataStatusL.length; i++) { + if (dataStatusL[i] != dataStatusR[i]) { + return false; + } + } + return true; + } + public boolean setStatus(int currentMode, boolean canChangeMode, int currentPowerRole, boolean canChangePowerRole, int currentDataRole, boolean canChangeDataRole, int supportedRoleCombinations, int contaminantProtectionStatus, - int contaminantDetectionStatus, boolean usbDataEnabled, - boolean powerTransferLimited) { + int contaminantDetectionStatus, int[] usbDataStatus, + boolean powerTransferLimited, int powerBrickStatus) { boolean dispositionChanged = false; mCanChangeMode = canChangeMode; @@ -1171,14 +1235,15 @@ public class UsbPortManager { != contaminantProtectionStatus || mUsbPortStatus.getContaminantDetectionStatus() != contaminantDetectionStatus - || mUsbPortStatus.getUsbDataStatus() - != usbDataEnabled + || !dataStatusEquals(mUsbPortStatus.getUsbDataStatus(), usbDataStatus) || mUsbPortStatus.isPowerTransferLimited() - != powerTransferLimited) { + != powerTransferLimited + || mUsbPortStatus.getPowerBrickStatus() + != powerBrickStatus) { mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations, contaminantProtectionStatus, - contaminantDetectionStatus, usbDataEnabled, - powerTransferLimited); + contaminantDetectionStatus, usbDataStatus, + powerTransferLimited, powerBrickStatus); dispositionChanged = true; } diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 51643e7d7d3c7..88ffc7d613e29 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -813,6 +813,32 @@ public class UsbService extends IUsbManager.Stub { return wait; } + @Override + public void enableUsbDataWhileDocked(String portId, int operationId, + IUsbOperationInternal callback) { + Objects.requireNonNull(portId, "enableUsbDataWhileDocked: portId must not be null. opId:" + + operationId); + Objects.requireNonNull(callback, + "enableUsbDataWhileDocked: callback must not be null. opId:" + + operationId); + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + final long ident = Binder.clearCallingIdentity(); + boolean wait; + try { + if (mPortManager != null) { + mPortManager.enableUsbDataWhileDocked(portId, operationId, callback, null); + } else { + try { + callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL); + } catch (RemoteException e) { + Slog.e(TAG, "enableUsbData: Failed to call onOperationComplete", e); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + @Override public void setUsbDeviceConnectionHandler(ComponentName usbDeviceConnectionHandler) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); diff --git a/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java index 8dfc85995272c..dd256205c220e 100644 --- a/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java +++ b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java @@ -37,8 +37,9 @@ public final class RawPortInfo implements Parcelable { public int contaminantProtectionStatus; public boolean supportsEnableContaminantPresenceDetection; public int contaminantDetectionStatus; - public boolean usbDataEnabled; + public int[] usbDataStatus; public boolean powerTransferLimited; + public int powerBrickStatus; public RawPortInfo(String portId, int supportedModes) { this.portId = portId; @@ -48,8 +49,9 @@ public final class RawPortInfo implements Parcelable { this.contaminantProtectionStatus = UsbPortStatus.CONTAMINANT_PROTECTION_NONE; this.supportsEnableContaminantPresenceDetection = false; this.contaminantDetectionStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED; - this.usbDataEnabled = true; + this.usbDataStatus[0] = UsbPortStatus.USB_DATA_STATUS_UNKNOWN; this.powerTransferLimited = false; + this.powerBrickStatus = UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN; } public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes, @@ -60,8 +62,9 @@ public final class RawPortInfo implements Parcelable { int contaminantProtectionStatus, boolean supportsEnableContaminantPresenceDetection, int contaminantDetectionStatus, - boolean usbDataEnabled, - boolean powerTransferLimited) { + int[] usbDataStatus, + boolean powerTransferLimited, + int powerBrickStatus) { this.portId = portId; this.supportedModes = supportedModes; this.supportedContaminantProtectionModes = supportedContaminantProtectionModes; @@ -77,8 +80,9 @@ public final class RawPortInfo implements Parcelable { this.supportsEnableContaminantPresenceDetection = supportsEnableContaminantPresenceDetection; this.contaminantDetectionStatus = contaminantDetectionStatus; - this.usbDataEnabled = usbDataEnabled; + this.usbDataStatus = usbDataStatus; this.powerTransferLimited = powerTransferLimited; + this.powerBrickStatus = powerBrickStatus; } @Override @@ -101,8 +105,10 @@ public final class RawPortInfo implements Parcelable { dest.writeInt(contaminantProtectionStatus); dest.writeBoolean(supportsEnableContaminantPresenceDetection); dest.writeInt(contaminantDetectionStatus); - dest.writeBoolean(usbDataEnabled); + dest.writeInt(usbDataStatus.length); + dest.writeIntArray(usbDataStatus); dest.writeBoolean(powerTransferLimited); + dest.writeInt(powerBrickStatus); } public static final Parcelable.Creator CREATOR = @@ -122,8 +128,10 @@ public final class RawPortInfo implements Parcelable { int contaminantProtectionStatus = in.readInt(); boolean supportsEnableContaminantPresenceDetection = in.readBoolean(); 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 RawPortInfo(id, supportedModes, supportedContaminantProtectionModes, currentMode, canChangeMode, currentPowerRole, canChangePowerRole, @@ -131,8 +139,8 @@ public final class RawPortInfo implements Parcelable { supportsEnableContaminantPresenceProtection, contaminantProtectionStatus, supportsEnableContaminantPresenceDetection, - contaminantDetectionStatus, usbDataEnabled, - powerTransferLimited); + contaminantDetectionStatus, usbDataStatus, + powerTransferLimited, powerBrickStatus); } @Override diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java index 24602426930d6..5582600737335 100644 --- a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java +++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java @@ -322,6 +322,48 @@ public final class UsbPortAidl implements UsbPortHal { } } + @Override + public void enableUsbDataWhileDocked(String portName, long operationID, + IUsbOperationInternal callback) { + Objects.requireNonNull(portName); + long key = operationID; + synchronized (mLock) { + try { + if (mProxy == null) { + logAndPrint(Log.ERROR, mPw, + "enableUsbDataWhileDocked: Proxy is null. Retry !opID:" + + operationID); + callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL); + return; + } + while (sCallbacks.get(key) != null) { + key = ThreadLocalRandom.current().nextInt(); + } + if (key != operationID) { + logAndPrint(Log.INFO, mPw, + "enableUsbDataWhileDocked: operationID exists ! opID:" + + operationID + " key:" + key); + } + try { + sCallbacks.put(key, callback); + mProxy.enableUsbDataWhileDocked(portName, key); + } catch (RemoteException e) { + logAndPrintException(mPw, + "enableUsbDataWhileDocked: error while invoking hal" + + "portID=" + portName + " opID:" + operationID, e); + if (callback != null) { + callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL); + } + sCallbacks.remove(key); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "enableUsbDataWhileDocked: Failed to call onOperationComplete portID=" + + portName + " opID:" + operationID, e); + } + } + } + private static class HALCallback extends IUsbCallback.Stub { public IndentingPrintWriter mPw; public UsbPortManager mPortManager; @@ -403,6 +445,14 @@ public final class UsbPortAidl implements UsbPortHal { return supportedContaminantProtectionModes; } + private int[] toIntArray(byte[] input) { + int[] output = new int[input.length]; + for (int i = 0; i < input.length; i++) { + output[i] = input[i]; + } + return output; + } + @Override public void notifyPortStatusChange( android.hardware.usb.PortStatus[] currentPortStatus, int retval) { @@ -434,8 +484,9 @@ public final class UsbPortAidl implements UsbPortHal { toContaminantProtectionStatus(current.contaminantProtectionStatus), current.supportsEnableContaminantPresenceDetection, current.contaminantDetectionStatus, - current.usbDataEnabled, - current.powerTransferLimited); + toIntArray(current.usbDataStatus), + current.powerTransferLimited, + current.powerBrickStatus); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback AIDL V1: " + current.portName); @@ -529,5 +580,30 @@ public final class UsbPortAidl implements UsbPortHal { e); } } + + @Override + public void notifyEnableUsbDataWhileDockedStatus(String portName, int retval, + long operationID) { + if (retval == Status.SUCCESS) { + UsbPortManager.logAndPrint(Log.INFO, mPw, portName + ": opID:" + + operationID + " successful"); + } else { + UsbPortManager.logAndPrint(Log.ERROR, mPw, portName + + "notifyEnableUsbDataWhileDockedStatus: opID:" + + operationID + " failed. err:" + retval); + } + try { + IUsbOperationInternal callback = sCallbacks.get(operationID); + if (callback != null) { + sCallbacks.get(operationID).onOperationComplete(retval == Status.SUCCESS + ? USB_OPERATION_SUCCESS + : USB_OPERATION_ERROR_INTERNAL); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "notifyEnableUsbDataWhileDockedStatus: Failed to call onOperationComplete", + e); + } + } } } diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java index 90c89090ef164..abfdd6f517cd8 100644 --- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java +++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java @@ -158,15 +158,27 @@ public interface UsbPortHal { * completion. * @param callback callback object to be invoked when the operation is complete. * @return True when the operation is asynchronous. The caller of - * {@link UsbOperationCallbackInternal} must therefore call - * {@link UsbOperationCallbackInternal#waitForOperationComplete} for processing + * {@link UsbOperationInternal} must therefore call + * {@link UsbOperationInternal#waitForOperationComplete} for processing * the result. * False when the operation is synchronous. Caller can proceed reading the result - * through {@link UsbOperationCallbackInternal#getStatus} + * through {@link UsbOperationInternal#getStatus} */ public boolean enableUsbData(String portName, boolean enable, long transactionId, IUsbOperationInternal callback); + /** + * Invoked to enable UsbData when disabled due to docking event. + * + * @param portName Port Identifier. + * @param transactionId Used for tracking the current request and is passed down to the HAL + * implementation as needed. + * @param callback callback object to be invoked to invoke the status of the operation upon + * completion. + */ + public void enableUsbDataWhileDocked(String portName, long transactionId, + IUsbOperationInternal callback); + /** * Invoked to enableLimitPowerTransfer on the specified port. * diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java index 8a0370ad49090..c1d76355e75b1 100644 --- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java +++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java @@ -30,8 +30,12 @@ import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST; import static android.hardware.usb.UsbPortStatus.MODE_DFP; import static android.hardware.usb.UsbPortStatus.MODE_DUAL; import static android.hardware.usb.UsbPortStatus.MODE_UFP; +import static android.hardware.usb.UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN; 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_DISABLED_FORCE; +import static android.hardware.usb.UsbPortStatus.USB_DATA_STATUS_UNKNOWN; + import static com.android.server.usb.UsbPortManager.logAndPrint; import static com.android.server.usb.UsbPortManager.logAndPrintException; @@ -40,6 +44,7 @@ import android.annotation.Nullable; import android.hardware.usb.IUsbOperationInternal; import android.hardware.usb.UsbManager.UsbHalVersion; import android.hardware.usb.UsbPort; +import android.hardware.usb.UsbPortStatus; import android.hardware.usb.V1_0.IUsb; import android.hardware.usb.V1_0.PortRoleType; import android.hardware.usb.V1_0.Status; @@ -80,7 +85,7 @@ public final class UsbPortHidl implements UsbPortHal { private HALCallback mHALCallback; private boolean mSystemReady; // Workaround since HIDL HAL versions report UsbDataEnabled status in UsbPortStatus; - private static boolean sUsbDataEnabled = true; + private static int sUsbDataStatus = USB_DATA_STATUS_UNKNOWN; public @UsbHalVersion int getUsbHalVersion() throws RemoteException { int version; @@ -281,6 +286,17 @@ public final class UsbPortHidl implements UsbPortHal { } } + @Override + public void enableUsbDataWhileDocked(String portName, long transactionId, + IUsbOperationInternal callback) { + /* Not supported in HIDL hals*/ + try { + callback.onOperationComplete(USB_OPERATION_ERROR_NOT_SUPPORTED); + } catch (RemoteException e) { + logAndPrintException(mPw, "Failed to call onOperationComplete", e); + } + } + @Override public void switchDataRole(String portId, @HalUsbDataRole int newDataRole, long transactionId) { synchronized (mLock) { @@ -332,7 +348,7 @@ public final class UsbPortHidl implements UsbPortHal { android.hardware.usb.V1_3.IUsb proxy = android.hardware.usb.V1_3.IUsb.castFrom(mProxy); success = proxy.enableUsbDataSignal(enable); - } catch (RemoteException e) { + } catch (RemoteException e) { logAndPrintException(mPw, "Failed enableUsbData: opId:" + transactionId + " portId=" + portName , e); try { @@ -346,9 +362,8 @@ public final class UsbPortHidl implements UsbPortHal { } } if (success) { - sUsbDataEnabled = enable; + sUsbDataStatus = enable ? USB_DATA_STATUS_UNKNOWN : USB_DATA_STATUS_DISABLED_FORCE; } - try { callback.onOperationComplete(success ? USB_OPERATION_SUCCESS @@ -393,8 +408,8 @@ public final class UsbPortHidl implements UsbPortHal { current.canChangePowerRole, current.currentDataRole, current.canChangeDataRole, false, CONTAMINANT_PROTECTION_NONE, - false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataEnabled, - false); + false, CONTAMINANT_DETECTION_NOT_SUPPORTED, new int[sUsbDataStatus], + false, POWER_BRICK_STATUS_UNKNOWN); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_0: " + current.portName); @@ -427,8 +442,8 @@ public final class UsbPortHidl implements UsbPortHal { current.status.canChangePowerRole, current.status.currentDataRole, current.status.canChangeDataRole, false, CONTAMINANT_PROTECTION_NONE, - false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataEnabled, - false); + false, CONTAMINANT_DETECTION_NOT_SUPPORTED, new int[sUsbDataStatus], + false, POWER_BRICK_STATUS_UNKNOWN); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_1: " + current.status.portName); @@ -465,8 +480,8 @@ public final class UsbPortHidl implements UsbPortHal { current.contaminantProtectionStatus, current.supportsEnableContaminantPresenceDetection, current.contaminantDetectionStatus, - sUsbDataEnabled, - false); + new int[sUsbDataStatus], + false, POWER_BRICK_STATUS_UNKNOWN); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_2: " + current.status_1_1.status.portName);