diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e5f08825ec809..4c689490a138e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -5771,6 +5771,19 @@ package android.hardware.soundtrigger { package android.hardware.usb { + public final class DisplayPortAltModeInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getCableStatus(); + method public int getNumberOfLanes(); + method public int getPartnerSinkStatus(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int DISPLAYPORT_ALT_MODE_STATUS_CAPABLE = 2; // 0x2 + field public static final int DISPLAYPORT_ALT_MODE_STATUS_ENABLED = 3; // 0x3 + field public static final int DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE = 1; // 0x1 + field public static final int DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN = 0; // 0x0 + } + public class UsbDeviceConnection { method public boolean resetDevice(); } @@ -5779,8 +5792,10 @@ package android.hardware.usb { method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public long getCurrentFunctions(); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USB) public java.util.List getPorts(); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String); + method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean registerDisplayPortAltModeInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbGadget(); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long); + method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void unregisterDisplayPortAltModeInfoListener(@NonNull android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener); 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"; @@ -5804,11 +5819,16 @@ package android.hardware.usb { field public static final String USB_FUNCTION_RNDIS = "rndis"; } + public static interface UsbManager.DisplayPortAltModeInfoListener { + method public void onDisplayPortAltModeInfoChanged(@NonNull String, @NonNull android.hardware.usb.DisplayPortAltModeInfo); + } + 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 public boolean isAltModeSupported(int); method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbPort(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int); method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean supportsComplianceWarnings(); @@ -5828,6 +5848,7 @@ package android.hardware.usb { 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 + field public static final int FLAG_ALT_MODE_TYPE_DISPLAYPORT = 1; // 0x1 field public static final int RESET_USB_PORT_ERROR_INTERNAL = 1; // 0x1 field public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2; // 0x2 field public static final int RESET_USB_PORT_ERROR_OTHER = 4; // 0x4 @@ -5841,6 +5862,8 @@ package android.hardware.usb { method public int getCurrentDataRole(); method public int getCurrentMode(); method public int getCurrentPowerRole(); + method @Nullable public android.hardware.usb.DisplayPortAltModeInfo getDisplayPortAltModeInfo(); + method public int getPlugState(); method public int getPowerBrickConnectionStatus(); method public int getSupportedRoleCombinations(); method public int getUsbDataStatus(); @@ -5870,6 +5893,11 @@ 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 PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED = 4; // 0x4 + field public static final int PLUG_STATE_PLUGGED_ORIENTATION_NORMAL = 3; // 0x3 + field public static final int PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN = 2; // 0x2 + field public static final int PLUG_STATE_UNKNOWN = 0; // 0x0 + field public static final int PLUG_STATE_UNPLUGGED = 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 diff --git a/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl b/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl new file mode 100644 index 0000000000000..14986d0de6bc2 --- /dev/null +++ b/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb; + +parcelable DisplayPortAltModeInfo; \ No newline at end of file diff --git a/core/java/android/hardware/usb/DisplayPortAltModeInfo.java b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java new file mode 100644 index 0000000000000..febc643339930 --- /dev/null +++ b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb; + +import android.Manifest; +import android.annotation.CheckResult; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Holds information related to DisplayPort Alt Mode statuses + * + * @hide + */ +@SystemApi +public final class DisplayPortAltModeInfo implements Parcelable { + private final @DisplayPortAltModeStatus int mPartnerSinkStatus; + private final @DisplayPortAltModeStatus int mCableStatus; + private final int mNumLanes; + + /** + * Port Partners: + * The port partner status is currently unknown for one of the following reasons: + *
    + *
  • No port partner is connected to the device + *
  • The USB Power Delivery Discover Identity command has not been issued to the port + * partner via SOP messaging. + *
+ *

+ * Cables: + * The cable’s capabilities are not yet known to the device, or no cable is plugged in. + */ + public static final int DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN = 0; + + /** + * Port Partners: + * The current port partner does not list DisplayPort as one of its Alt Modes, or does not list + * the capability to act as a DisplayPort Source or Sink device, or a compatible configuration + * could not be established. + *

+ * Cables: + * The cable/adapter’s capabilities do not list DisplayPort as one of its Alt Modes, or a + * compatible configuration could not be established. + */ + public static final int DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE = 1; + + /** + * Port Partners: + * The current port partner lists compatible DisplayPort capabilities with the device, however + * may not yet have entered DisplayPort Alt Mode or has configured its port for data + * transmission. + *

+ * Cables: + * The Type-C cable/adapter’s capabilities have been discovered and list DisplayPort Alt Mode + * as one of its capabilities, however may not yet have entered DisplayPort Alt Mode or has been + * configured for data transmission. + */ + public static final int DISPLAYPORT_ALT_MODE_STATUS_CAPABLE = 2; + + /** + * Port Partners: + * The port partner and device are both configured for DisplayPort Alt Mode. + *

+ * Cables: + * The Type-C cable/adapter is configured for DisplayPort Alt Mode. + */ + public static final int DISPLAYPORT_ALT_MODE_STATUS_ENABLED = 3; + + /** @hide */ + @IntDef(prefix = { "DISPLAYPORT_ALT_MODE_STATUS_" }, value = { + DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN, + DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE, + DISPLAYPORT_ALT_MODE_STATUS_CAPABLE, + DISPLAYPORT_ALT_MODE_STATUS_ENABLED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DisplayPortAltModeStatus {} + + /** @hide */ + public DisplayPortAltModeInfo() { + mPartnerSinkStatus = DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN; + mCableStatus = DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN; + mNumLanes = 0; + } + + /** @hide */ + public DisplayPortAltModeInfo(int partnerSinkStatus, int cableStatus, + int numLanes) { + mPartnerSinkStatus = partnerSinkStatus; + mCableStatus = cableStatus; + mNumLanes = numLanes; + } + + /** + * Returns the DisplayPort Alt Mode Status for a port partner acting as a sink. + * + * @return {@link #DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_CAPABLE} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_ENABLED} + */ + public @DisplayPortAltModeStatus int getPartnerSinkStatus() { + return mPartnerSinkStatus; + } + + /** + * Returns the DisplayPort Alt Mode Status for the attached cable + * + * @return {@link #DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_CAPABLE} + * or {@link #DISPLAYPORT_ALT_MODE_STATUS_ENABLED} + */ + public @DisplayPortAltModeStatus int getCableStatus() { + return mCableStatus; + } + + /** + * Returns the number of lanes used to transmit display data. + * + */ + public int getNumberOfLanes() { + return mNumLanes; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mPartnerSinkStatus); + dest.writeInt(mCableStatus); + dest.writeInt(mNumLanes); + } + + @NonNull + @Override + public String toString() { + return "DisplayPortAltModeInfo{partnerSink=" + + mPartnerSinkStatus + + " cable=" + + mCableStatus + + " numLanes=" + + mNumLanes + + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DisplayPortAltModeInfo)) { + return false; + } + DisplayPortAltModeInfo other = (DisplayPortAltModeInfo) o; + return this.mPartnerSinkStatus == other.mPartnerSinkStatus + && this.mCableStatus == other.mCableStatus + && this.mNumLanes == other.mNumLanes; + } + + @Override + public int hashCode() { + return Objects.hash(mPartnerSinkStatus, mCableStatus, mNumLanes); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public DisplayPortAltModeInfo createFromParcel(Parcel in) { + int partnerSinkStatus = in.readInt(); + int cableStatus = in.readInt(); + int numLanes = in.readInt(); + return new DisplayPortAltModeInfo(partnerSinkStatus, cableStatus, numLanes); + } + + @Override + public DisplayPortAltModeInfo[] newArray(int size) { + return new DisplayPortAltModeInfo[size]; + } + }; +} diff --git a/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl b/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl new file mode 100644 index 0000000000000..e93e0fbb67de2 --- /dev/null +++ b/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb; + +import android.hardware.usb.DisplayPortAltModeInfo; + +/** + * @hide + */ +oneway interface IDisplayPortAltModeInfoListener { + void onDisplayPortAltModeInfoChanged(in String portId, + in DisplayPortAltModeInfo DisplayPortAltModeInfo); +} \ No newline at end of file diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 248b5d0398f6f..21b00e31054dd 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -18,6 +18,7 @@ package android.hardware.usb; import android.app.PendingIntent; import android.content.ComponentName; +import android.hardware.usb.IDisplayPortAltModeInfoListener; import android.hardware.usb.IUsbOperationInternal; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbDevice; @@ -184,4 +185,15 @@ interface IUsbManager /* Sets USB device connection handler. */ void setUsbDeviceConnectionHandler(in ComponentName usbDeviceConnectionHandler); + + /* Registers callback for Usb events */ + @JavaPassthrough(annotation= + "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)") + boolean registerForDisplayPortEvents(IDisplayPortAltModeInfoListener listener); + + /* Unregisters Usb event callback */ + @JavaPassthrough(annotation= + "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)") + void unregisterForDisplayPortEvents(IDisplayPortAltModeInfoListener listener); + } diff --git a/core/java/android/hardware/usb/ParcelableUsbPort.java b/core/java/android/hardware/usb/ParcelableUsbPort.java index 7fc282c141ba5..eb6501ad228be 100644 --- a/core/java/android/hardware/usb/ParcelableUsbPort.java +++ b/core/java/android/hardware/usb/ParcelableUsbPort.java @@ -35,12 +35,14 @@ public final class ParcelableUsbPort implements Parcelable { private final boolean mSupportsEnableContaminantPresenceProtection; private final boolean mSupportsEnableContaminantPresenceDetection; private final boolean mSupportsComplianceWarnings; + private final int mSupportedAltModesMask; private ParcelableUsbPort(@NonNull String id, int supportedModes, int supportedContaminantProtectionModes, boolean supportsEnableContaminantPresenceProtection, boolean supportsEnableContaminantPresenceDetection, - boolean supportsComplianceWarnings) { + boolean supportsComplianceWarnings, + int supportedAltModesMask) { mId = id; mSupportedModes = supportedModes; mSupportedContaminantProtectionModes = supportedContaminantProtectionModes; @@ -50,6 +52,7 @@ public final class ParcelableUsbPort implements Parcelable { supportsEnableContaminantPresenceDetection; mSupportsComplianceWarnings = supportsComplianceWarnings; + mSupportedAltModesMask = supportedAltModesMask; } /** @@ -64,7 +67,8 @@ public final class ParcelableUsbPort implements Parcelable { port.getSupportedContaminantProtectionModes(), port.supportsEnableContaminantPresenceProtection(), port.supportsEnableContaminantPresenceDetection(), - port.supportsComplianceWarnings()); + port.supportsComplianceWarnings(), + port.getSupportedAltModesMask()); } /** @@ -78,7 +82,8 @@ public final class ParcelableUsbPort implements Parcelable { return new UsbPort(usbManager, mId, mSupportedModes, mSupportedContaminantProtectionModes, mSupportsEnableContaminantPresenceProtection, mSupportsEnableContaminantPresenceDetection, - mSupportsComplianceWarnings); + mSupportsComplianceWarnings, + mSupportedAltModesMask); } @Override @@ -94,6 +99,7 @@ public final class ParcelableUsbPort implements Parcelable { dest.writeBoolean(mSupportsEnableContaminantPresenceProtection); dest.writeBoolean(mSupportsEnableContaminantPresenceDetection); dest.writeBoolean(mSupportsComplianceWarnings); + dest.writeInt(mSupportedAltModesMask); } public static final @android.annotation.NonNull Creator CREATOR = @@ -106,12 +112,14 @@ public final class ParcelableUsbPort implements Parcelable { boolean supportsEnableContaminantPresenceProtection = in.readBoolean(); boolean supportsEnableContaminantPresenceDetection = in.readBoolean(); boolean supportsComplianceWarnings = in.readBoolean(); + int supportedAltModesMask = in.readInt(); return new ParcelableUsbPort(id, supportedModes, supportedContaminantProtectionModes, supportsEnableContaminantPresenceProtection, supportsEnableContaminantPresenceDetection, - supportsComplianceWarnings); + supportsComplianceWarnings, + supportedAltModesMask); } @Override diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 7a8117c1b684b..909d147412cf9 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -20,6 +20,7 @@ package android.hardware.usb; import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE; import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; @@ -44,16 +45,24 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; +import android.util.ArrayMap; import android.util.Log; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.StringJoiner; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.Executor; +import java.util.function.BiConsumer; +import java.util.function.Consumer; /** * This class allows you to access the state of USB and communicate with USB devices. @@ -724,8 +733,60 @@ public class UsbManager { }) public @interface UsbHalVersion {} + /** + * Listener to register for when the {@link DisplayPortAltModeInfo} changes on a + * {@link UsbPort}. + * + * @hide + */ + @SystemApi + public interface DisplayPortAltModeInfoListener { + /** + * Callback to be executed when the {@link DisplayPortAltModeInfo} changes on a + * {@link UsbPort}. + * + * @param portId String describing the {@link UsbPort} that was changed. + * @param info New {@link DisplayPortAltModeInfo} for the corresponding portId. + */ + public void onDisplayPortAltModeInfoChanged(@NonNull String portId, + @NonNull DisplayPortAltModeInfo info); + } + + /** + * Holds callback and executor data to be passed across UsbService. + */ + private class DisplayPortAltModeInfoDispatchingListener extends + IDisplayPortAltModeInfoListener.Stub { + + public void onDisplayPortAltModeInfoChanged(String portId, + DisplayPortAltModeInfo displayPortAltModeInfo) { + synchronized (mDisplayPortListenersLock) { + for (Map.Entry entry : + mDisplayPortListeners.entrySet()) { + Executor executor = entry.getValue(); + DisplayPortAltModeInfoListener callback = entry.getKey(); + final long token = Binder.clearCallingIdentity(); + try { + executor.execute(() -> callback.onDisplayPortAltModeInfoChanged(portId, + displayPortAltModeInfo)); + } catch (Exception e) { + Slog.e(TAG, "Exception during onDisplayPortAltModeInfoChanged from " + + "executor: " + executor, e); + } finally { + Binder.restoreCallingIdentity(token); + } + } + } + } + } + private final Context mContext; private final IUsbManager mService; + private final Object mDisplayPortListenersLock = new Object(); + @GuardedBy("mDisplayPortListenersLock") + private ArrayMap mDisplayPortListeners; + @GuardedBy("mDisplayPortListenersLock") + private DisplayPortAltModeInfoDispatchingListener mDisplayPortServiceListener; /** * @hide @@ -1524,6 +1585,109 @@ public class UsbManager { } } + @GuardedBy("mDisplayPortListenersLock") + @RequiresPermission(Manifest.permission.MANAGE_USB) + private boolean registerDisplayPortAltModeEventsIfNeededLocked() { + DisplayPortAltModeInfoDispatchingListener displayPortDispatchingListener = + new DisplayPortAltModeInfoDispatchingListener(); + try { + if (mService.registerForDisplayPortEvents(displayPortDispatchingListener)) { + mDisplayPortServiceListener = displayPortDispatchingListener; + return true; + } + return false; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Registers the given listener to listen for DisplayPort Alt Mode changes. + *

+ * If this method returns true, the caller should ensure to call + * {@link #unregisterDisplayPortAltModeListener} when it no longer requires updates. + * + * @param executor Executor on which to run the listener. + * @param listener DisplayPortAltModeInfoListener invoked on DisplayPortAltModeInfo + * changes. See {@link #DisplayPortAltModeInfoListener} for listener + * details. + * + * @return true on successful register, false on failed register due to listener already being + * registered or an internal error. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_USB) + public boolean registerDisplayPortAltModeInfoListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull DisplayPortAltModeInfoListener listener) { + Objects.requireNonNull(executor, "registerDisplayPortAltModeInfoListener: " + + "executor must not be null."); + Objects.requireNonNull(listener, "registerDisplayPortAltModeInfoListener: " + + "listener must not be null."); + + synchronized (mDisplayPortListenersLock) { + if (mDisplayPortListeners == null) { + mDisplayPortListeners = new ArrayMap(); + } + + if (mDisplayPortServiceListener == null) { + if (!registerDisplayPortAltModeEventsIfNeededLocked()) { + return false; + } + } + if (mDisplayPortListeners.containsKey(listener)) { + return false; + } + + mDisplayPortListeners.put(listener, executor); + return true; + } + } + + @GuardedBy("mDisplayPortListenersLock") + @RequiresPermission(Manifest.permission.MANAGE_USB) + private void unregisterDisplayPortAltModeEventsLocked() { + if (mDisplayPortServiceListener != null) { + try { + mService.unregisterForDisplayPortEvents(mDisplayPortServiceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } finally { + // If there was a RemoteException, the system server may have died, + // and this listener probably became unregistered, so clear it for re-registration. + mDisplayPortServiceListener = null; + } + } + } + + /** + * Unregisters the given listener if it was previously passed to + * registerDisplayPortAltModeInfoListener. + * + * @param listener DisplayPortAltModeInfoListener used to register the listener + * in registerDisplayPortAltModeInfoListener. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_USB) + public void unregisterDisplayPortAltModeInfoListener( + @NonNull DisplayPortAltModeInfoListener listener) { + synchronized (mDisplayPortListenersLock) { + if (mDisplayPortListeners == null) { + return; + } + mDisplayPortListeners.remove(listener); + if (mDisplayPortListeners.isEmpty()) { + unregisterDisplayPortAltModeEventsLocked(); + } + } + return; + } + /** * 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 cdd67b7c35477..73dcb362f3839 100644 --- a/core/java/android/hardware/usb/UsbPort.java +++ b/core/java/android/hardware/usb/UsbPort.java @@ -52,6 +52,10 @@ import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESS 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 static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN; +import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE; +import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_CAPABLE; +import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_ENABLED; import android.Manifest; import android.annotation.CallbackExecutor; @@ -90,6 +94,7 @@ public final class UsbPort { private final boolean mSupportsEnableContaminantPresenceProtection; private final boolean mSupportsEnableContaminantPresenceDetection; private final boolean mSupportsComplianceWarnings; + private final @AltModeType int mSupportedAltModes; private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES; /** @@ -252,6 +257,18 @@ public final class UsbPort { @Retention(RetentionPolicy.SOURCE) @interface EnableUsbDataWhileDockedStatus{} + /** + * Indicates that the Alt Mode being described is DisplayPort. + */ + public static final int FLAG_ALT_MODE_TYPE_DISPLAYPORT = 1 << 0; + + /** @hide */ + @IntDef(prefix = { "FLAG_ALT_MODE_TYPE_" }, flag = true, value = { + FLAG_ALT_MODE_TYPE_DISPLAYPORT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AltModeType {} + /** @hide */ public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes, int supportedContaminantProtectionModes, @@ -260,7 +277,7 @@ public final class UsbPort { this(usbManager, id, supportedModes, supportedContaminantProtectionModes, supportsEnableContaminantPresenceProtection, supportsEnableContaminantPresenceDetection, - false); + false, 0); } /** @hide */ @@ -268,7 +285,8 @@ public final class UsbPort { int supportedContaminantProtectionModes, boolean supportsEnableContaminantPresenceProtection, boolean supportsEnableContaminantPresenceDetection, - boolean supportsComplianceWarnings) { + boolean supportsComplianceWarnings, + int supportedAltModes) { Objects.requireNonNull(id); Preconditions.checkFlagsArgument(supportedModes, MODE_DFP | MODE_UFP | MODE_AUDIO_ACCESSORY | MODE_DEBUG_ACCESSORY); @@ -282,6 +300,7 @@ public final class UsbPort { mSupportsEnableContaminantPresenceDetection = supportsEnableContaminantPresenceDetection; mSupportsComplianceWarnings = supportsComplianceWarnings; + mSupportedAltModes = supportedAltModes; } /** @@ -365,6 +384,27 @@ public final class UsbPort { return mSupportsComplianceWarnings; } + /** + * Returns all Alt Modes supported by the port. + * + * @hide + */ + public @AltModeType int getSupportedAltModesMask() { + return mSupportedAltModes; + } + + /** + * Returns whether all Alt Mode types in a given mask are supported + * by the port. + * + * @return true if all given Alt Modes are supported, false otherwise. + * + */ + public boolean isAltModeSupported(@AltModeType int typeMask) { + return (mSupportedAltModes & typeMask) == typeMask; + } + + /** * Sets the desired role combination of the port. *

@@ -760,6 +800,22 @@ public final class UsbPort { return complianceWarningString.toString().replaceAll(", ]$", "]"); } + /** @hide */ + public static String dpAltModeStatusToString(int dpAltModeStatus) { + switch (dpAltModeStatus) { + case DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN: + return "Unknown"; + case DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE: + return "Not Capable"; + case DISPLAYPORT_ALT_MODE_STATUS_CAPABLE: + return "Capable"; + case DISPLAYPORT_ALT_MODE_STATUS_ENABLED: + return "Enabled"; + default: + return Integer.toString(dpAltModeStatus); + } + } + /** @hide */ public static void checkMode(int powerRole) { Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE, diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java index e61703d1c3ff4..8c133079a70a1 100644 --- a/core/java/android/hardware/usb/UsbPortStatus.java +++ b/core/java/android/hardware/usb/UsbPortStatus.java @@ -20,6 +20,7 @@ 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; @@ -27,6 +28,7 @@ import android.os.Parcelable; import com.android.internal.annotations.Immutable; +import java.lang.StringBuilder; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -49,6 +51,13 @@ public final class UsbPortStatus implements Parcelable { private final @UsbDataStatus int mUsbDataStatus; private final @PowerBrickConnectionStatus int mPowerBrickConnectionStatus; private final @NonNull @ComplianceWarning int[] mComplianceWarnings; + private final @PlugState int mPlugState; + /** + * Holds the DisplayPort Alt Mode info for the Port. This field + * is null if the device does not support DisplayPort Alt Mode. + */ + private final @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo; + /** * Power role: This USB port does not have a power role. @@ -300,6 +309,35 @@ public final class UsbPortStatus implements Parcelable { */ public static final int COMPLIANCE_WARNING_MISSING_RP = 4; + /** + * Indicates that the Type-C plug orientation cannot be + * determined. + */ + public static final int PLUG_STATE_UNKNOWN = 0; + + /** + * Indicates no Type-C plug is inserted into the device. + */ + public static final int PLUG_STATE_UNPLUGGED = 1; + + /** + * Indicates a Type-C plug is inserted into the device, but + * the orientation cannot be determined. + */ + public static final int PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN = 2; + + /** + * Indicates that the connected plug uses its CC1 + * pin to manage the Source-to-Sink connection. + */ + public static final int PLUG_STATE_PLUGGED_ORIENTATION_NORMAL = 3; + + /** + * Indicates that the connected plug uses its CC2 + * pin to manage the Source-to-Sink connection. + */ + public static final int PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED = 4; + @IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = { CONTAMINANT_DETECTION_NOT_SUPPORTED, CONTAMINANT_DETECTION_DISABLED, @@ -338,6 +376,16 @@ public final class UsbPortStatus implements Parcelable { @Retention(RetentionPolicy.SOURCE) @interface ComplianceWarning{} + @IntDef(prefix = { "PLUG_STATE_" }, value = { + PLUG_STATE_UNKNOWN, + PLUG_STATE_UNPLUGGED, + PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN, + PLUG_STATE_PLUGGED_ORIENTATION_NORMAL, + PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED, + }) + @Retention(RetentionPolicy.SOURCE) + @interface PlugState{} + /** @hide */ @IntDef(prefix = { "DATA_STATUS_" }, flag = true, value = { DATA_STATUS_UNKNOWN, @@ -348,7 +396,7 @@ public final class UsbPortStatus implements Parcelable { DATA_STATUS_DISABLED_DOCK_HOST_MODE, DATA_STATUS_DISABLED_DOCK_DEVICE_MODE, DATA_STATUS_DISABLED_FORCE, - DATA_STATUS_DISABLED_DEBUG + DATA_STATUS_DISABLED_DEBUG, }) @Retention(RetentionPolicy.SOURCE) @interface UsbDataStatus{} @@ -368,7 +416,9 @@ public final class UsbPortStatus implements Parcelable { int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus, boolean powerTransferLimited, @PowerBrickConnectionStatus int powerBrickConnectionStatus, - @NonNull @ComplianceWarning int[] complianceWarnings) { + @NonNull @ComplianceWarning int[] complianceWarnings, + int plugState, + @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) { mCurrentMode = currentMode; mCurrentPowerRole = currentPowerRole; mCurrentDataRole = currentDataRole; @@ -393,6 +443,8 @@ public final class UsbPortStatus implements Parcelable { mPowerTransferLimited = powerTransferLimited; mPowerBrickConnectionStatus = powerBrickConnectionStatus; mComplianceWarnings = complianceWarnings; + mPlugState = plugState; + mDisplayPortAltModeInfo = displayPortAltModeInfo; } /** @hide */ @@ -404,7 +456,7 @@ public final class UsbPortStatus implements Parcelable { this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - new int[] {}); + new int[] {}, PLUG_STATE_UNKNOWN, null); } /** @hide */ @@ -414,7 +466,7 @@ public final class UsbPortStatus implements Parcelable { this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, DATA_STATUS_UNKNOWN, false, POWER_BRICK_STATUS_UNKNOWN, - new int[] {}); + new int[] {}, PLUG_STATE_UNKNOWN, null); } /** @@ -547,10 +599,34 @@ public final class UsbPortStatus implements Parcelable { return mComplianceWarnings; } + /** + * Returns the orientation state of the attached cable/adapter. + * + * @return one of {@link #PLUG_STATE_UNKNOWN}, + * {@link #PLUG_STATE_UNPLUGGED}, + * {@link #PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN}, + * {@link #PLUG_STATE_PLUGGED_ORIENTATION_NORMAL}, + * {@link #PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED}, + */ + public @PlugState int getPlugState() { + return mPlugState; + } + + /** + * Returns the DisplayPortInfo of the USB Port, if applicable. + * + * @return an instance of type DisplayPortInfo + * or null if not applicable. + */ + @Nullable + public DisplayPortAltModeInfo getDisplayPortAltModeInfo() { + return (mDisplayPortAltModeInfo == null) ? null : mDisplayPortAltModeInfo; + } + @NonNull @Override public String toString() { - return "UsbPortStatus{connected=" + isConnected() + StringBuilder mString = new StringBuilder("UsbPortStatus{connected=" + isConnected() + ", currentMode=" + UsbPort.modeToString(mCurrentMode) + ", currentPowerRole=" + UsbPort.powerRoleToString(mCurrentPowerRole) + ", currentDataRole=" + UsbPort.dataRoleToString(mCurrentDataRole) @@ -569,7 +645,12 @@ public final class UsbPortStatus implements Parcelable { .powerBrickConnectionStatusToString(getPowerBrickConnectionStatus()) + ", complianceWarnings=" + UsbPort.complianceWarningsToString(getComplianceWarnings()) - + "}"; + + ", plugState=" + + getPlugState() + + ", displayPortAltModeInfo=" + + mDisplayPortAltModeInfo + + "}"); + return mString.toString(); } @Override @@ -589,6 +670,13 @@ public final class UsbPortStatus implements Parcelable { dest.writeBoolean(mPowerTransferLimited); dest.writeInt(mPowerBrickConnectionStatus); dest.writeIntArray(mComplianceWarnings); + dest.writeInt(mPlugState); + if (mDisplayPortAltModeInfo == null) { + dest.writeBoolean(false); + } else { + dest.writeBoolean(true); + mDisplayPortAltModeInfo.writeToParcel(dest, 0); + } } public static final @NonNull Parcelable.Creator CREATOR = @@ -605,11 +693,19 @@ public final class UsbPortStatus implements Parcelable { boolean powerTransferLimited = in.readBoolean(); int powerBrickConnectionStatus = in.readInt(); @ComplianceWarning int[] complianceWarnings = in.createIntArray(); + int plugState = in.readInt(); + boolean supportsDisplayPortAltMode = in.readBoolean(); + DisplayPortAltModeInfo displayPortAltModeInfo; + if (supportsDisplayPortAltMode) { + displayPortAltModeInfo = DisplayPortAltModeInfo.CREATOR.createFromParcel(in); + } else { + displayPortAltModeInfo = null; + } return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - complianceWarnings); + complianceWarnings, plugState, displayPortAltModeInfo); } @Override @@ -634,6 +730,8 @@ public final class UsbPortStatus implements Parcelable { private @UsbDataStatus int mUsbDataStatus; private @PowerBrickConnectionStatus int mPowerBrickConnectionStatus; private @ComplianceWarning int[] mComplianceWarnings; + private @PlugState int mPlugState; + private @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo; public Builder() { mCurrentMode = MODE_NONE; @@ -644,6 +742,8 @@ public final class UsbPortStatus implements Parcelable { mUsbDataStatus = DATA_STATUS_UNKNOWN; mPowerBrickConnectionStatus = POWER_BRICK_STATUS_UNKNOWN; mComplianceWarnings = new int[] {}; + mPlugState = PLUG_STATE_UNKNOWN; + mDisplayPortAltModeInfo = null; } /** @@ -742,6 +842,28 @@ public final class UsbPortStatus implements Parcelable { return this; } + /** + * Sets the plug orientation of {@link UsbPortStatus} + * + * @return Instance of {@link Builder} + */ + @NonNull + public Builder setPlugState(int plugState) { + mPlugState = plugState; + return this; + } + + /** + * Sets the plug orientation of {@link UsbPortStatus} + * + * @return Instance of {@link Builder} + */ + @NonNull + public Builder setDisplayPortAltModeInfo( + @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) { + mDisplayPortAltModeInfo = displayPortAltModeInfo; + return this; + } /** * Creates the {@link UsbPortStatus} object. @@ -751,7 +873,8 @@ public final class UsbPortStatus implements Parcelable { UsbPortStatus status = new UsbPortStatus(mCurrentMode, mCurrentPowerRole, mCurrentDataRole, mSupportedRoleCombinations, mContaminantProtectionStatus, mContaminantDetectionStatus, mUsbDataStatus, mPowerTransferLimited, - mPowerBrickConnectionStatus, mComplianceWarnings); + mPowerBrickConnectionStatus, mComplianceWarnings, + mPlugState, mDisplayPortAltModeInfo); return status; } }; diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index f920f0f1f2816..28d726e480884 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -46,11 +46,13 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.hardware.usb.IDisplayPortAltModeInfoListener; import android.hardware.usb.IUsbOperationInternal; import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.DisplayPortAltModeInfo; import android.hardware.usb.V1_0.IUsb; import android.hardware.usb.V1_0.PortRole; import android.hardware.usb.V1_0.PortRoleType; @@ -63,6 +65,8 @@ import android.hidl.manager.V1_0.IServiceNotification; import android.os.Bundle; import android.os.Handler; import android.os.HwBinder; +import android.os.IBinder; +import android.os.IInterface; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; @@ -90,8 +94,10 @@ import com.android.server.usb.hal.port.UsbPortHalInstance; import java.util.Arrays; import java.util.ArrayList; +import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.concurrent.Executor; /** * Allows trusted components to control the properties of physical USB ports @@ -105,7 +111,7 @@ import java.util.Objects; * (but we don't care today). *

*/ -public class UsbPortManager { +public class UsbPortManager implements IBinder.DeathRecipient { private static final String TAG = "UsbPortManager"; private static final int MSG_UPDATE_PORTS = 1; @@ -158,6 +164,12 @@ public class UsbPortManager { private NotificationManager mNotificationManager; + // Maintains a list of DisplayPortAltModeInfo Event listeners, + // protected by mDisplayPortListenerLock for broadcasts/register/unregister events + private final Object mDisplayPortListenerLock = new Object(); + private final ArrayMap mDisplayPortListeners = + new ArrayMap(); + /** * If there currently is a notification related to contaminated USB port management * shown the id of the notification, or 0 if there is none. @@ -673,6 +685,46 @@ public class UsbPortManager { } } + @Override + public void binderDied() { + // All calls should go to binderDied(IBinder deadBinder) + Slog.wtf(TAG, "binderDied() called unexpectedly"); + } + + public void binderDied(IBinder deadBinder) { + synchronized (mDisplayPortListenerLock) { + mDisplayPortListeners.remove(deadBinder); + Slog.d(TAG, "DisplayPortEventDispatcherListener died at " + deadBinder); + } + } + + public boolean registerForDisplayPortEvents( + @NonNull IDisplayPortAltModeInfoListener listener) { + synchronized (mDisplayPortListenerLock) { + if (!mDisplayPortListeners.containsKey(listener.asBinder())) { + try { + listener.asBinder().linkToDeath(this, 0); + } catch (RemoteException e) { + logAndPrintException(null, "Caught RemoteException in " + + "registerForDisplayPortEvents: ", e); + return false; + } + mDisplayPortListeners.put(listener.asBinder(), listener); + return true; + } + } + return false; + } + + public void unregisterForDisplayPortEvents( + @NonNull IDisplayPortAltModeInfoListener listener) { + synchronized (mDisplayPortListenerLock) { + if (mDisplayPortListeners.remove(listener.asBinder()) != null) { + listener.asBinder().unlinkToDeath(this, 0); + } + } + } + public void updatePorts(ArrayList newPortInfo) { Message message = mHandler.obtainMessage(); Bundle bundle = new Bundle(); @@ -683,8 +735,15 @@ public class UsbPortManager { } public void addSimulatedPort(String portId, int supportedModes, - boolean supportsComplianceWarnings, - IndentingPrintWriter pw) { + boolean supportsComplianceWarnings, boolean supportsDisplayPortAltMode, + IndentingPrintWriter pw) { + int supportedAltModes = supportsDisplayPortAltMode ? + UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT : 0; + DisplayPortAltModeInfo displayPortAltModeInfo = null; + + if (supportsDisplayPortAltMode) { + displayPortAltModeInfo = new DisplayPortAltModeInfo(); + } synchronized (mLock) { if (mSimulatedPorts.containsKey(portId)) { @@ -713,7 +772,10 @@ public class UsbPortManager { false, UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN, supportsComplianceWarnings, - new int[] {})); + new int[] {}, + UsbPortStatus.PLUG_STATE_UNKNOWN, + supportedAltModes, + displayPortAltModeInfo)); updatePortsLocked(pw, null); } } @@ -802,6 +864,25 @@ public class UsbPortManager { } } + + public void simulateDisplayPortAltModeInfo(String portId, int partnerSinkStatus, + int cableStatus, int numLanes, IndentingPrintWriter pw) { + synchronized (mLock) { + final RawPortInfo portInfo = mSimulatedPorts.get(portId); + if (portInfo == null) { + pw.println("Simulated port not found"); + return; + } + + DisplayPortAltModeInfo displayPortAltModeInfo = + new DisplayPortAltModeInfo(partnerSinkStatus, cableStatus, numLanes); + portInfo.displayPortAltModeInfo = displayPortAltModeInfo; + pw.println("Simulating DisplayPort Info: " + displayPortAltModeInfo); + updatePortsLocked(pw, null); + } + + } + public void disconnectSimulatedPort(String portId, IndentingPrintWriter pw) { synchronized (mLock) { final RawPortInfo portInfo = mSimulatedPorts.get(portId); @@ -893,6 +974,9 @@ public class UsbPortManager { portInfo.powerBrickConnectionStatus, portInfo.supportsComplianceWarnings, portInfo.complianceWarnings, + portInfo.plugState, + portInfo.supportedAltModes, + portInfo.displayPortAltModeInfo, pw); } } else { @@ -911,6 +995,9 @@ public class UsbPortManager { currentPortInfo.powerBrickConnectionStatus, currentPortInfo.supportsComplianceWarnings, currentPortInfo.complianceWarnings, + currentPortInfo.plugState, + currentPortInfo.supportedAltModes, + currentPortInfo.displayPortAltModeInfo, pw); } } @@ -937,6 +1024,9 @@ public class UsbPortManager { if (portInfo.mComplianceWarningChange == portInfo.COMPLIANCE_WARNING_CHANGED) { handlePortComplianceWarningLocked(portInfo, pw); } + if (portInfo.mDisplayPortAltModeChange == portInfo.ALTMODE_INFO_CHANGED) { + handleDpAltModeLocked(portInfo, pw); + } } } @@ -955,6 +1045,9 @@ public class UsbPortManager { int powerBrickConnectionStatus, boolean supportsComplianceWarnings, @NonNull int[] complianceWarnings, + int plugState, + int supportedAltModes, + DisplayPortAltModeInfo displayPortAltModeInfo, IndentingPrintWriter pw) { // Only allow mode switch capability for dual role ports. // Validate that the current mode matches the supported modes we expect. @@ -1009,14 +1102,15 @@ public class UsbPortManager { portId, supportedModes, supportedContaminantProtectionModes, supportsEnableContaminantPresenceProtection, supportsEnableContaminantPresenceDetection, - supportsComplianceWarnings); + supportsComplianceWarnings, + supportedAltModes); portInfo.setStatus(currentMode, canChangeMode, currentPowerRole, canChangePowerRole, currentDataRole, canChangeDataRole, supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - complianceWarnings); + complianceWarnings, plugState, displayPortAltModeInfo); mPorts.put(portId, portInfo); } else { // Validate that ports aren't changing definition out from under us. @@ -1054,7 +1148,7 @@ public class UsbPortManager { supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - complianceWarnings)) { + complianceWarnings, plugState, displayPortAltModeInfo)) { portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED; } else { portInfo.mDisposition = PortInfo.DISPOSITION_READY; @@ -1086,6 +1180,11 @@ public class UsbPortManager { sendComplianceWarningBroadcastLocked(portInfo); } + private void handleDpAltModeLocked(PortInfo portInfo, IndentingPrintWriter pw) { + logAndPrint(Log.INFO, pw, "USB port DisplayPort Alt Mode Status Changed: " + portInfo); + sendDpAltModeCallbackLocked(portInfo, pw); + } + private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo); handlePortLocked(portInfo, pw); @@ -1135,7 +1234,6 @@ public class UsbPortManager { return complianceWarningsProto.toArray(); } - private void sendPortChangedBroadcastLocked(PortInfo portInfo) { final Intent intent = new Intent(UsbManager.ACTION_USB_PORT_CHANGED); intent.addFlags( @@ -1167,6 +1265,21 @@ public class UsbPortManager { Manifest.permission.MANAGE_USB)); } + private void sendDpAltModeCallbackLocked(PortInfo portInfo, IndentingPrintWriter pw) { + String portId = portInfo.mUsbPort.getId(); + synchronized (mDisplayPortListenerLock) { + for (IDisplayPortAltModeInfoListener mListener : mDisplayPortListeners.values()) { + try { + mListener.onDisplayPortAltModeInfoChanged(portId, + portInfo.mUsbPortStatus.getDisplayPortAltModeInfo()); + } catch (RemoteException e) { + logAndPrintException(pw, "Caught RemoteException at " + + "sendDpAltModeCallbackLocked", e); + } + } + } + } + private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) { if (!mConnected.containsKey(portInfo.mUsbPort.getId())) { return; @@ -1308,6 +1421,9 @@ public class UsbPortManager { public static final int COMPLIANCE_WARNING_UNCHANGED = 0; public static final int COMPLIANCE_WARNING_CHANGED = 1; + public static final int ALTMODE_INFO_UNCHANGED = 0; + public static final int ALTMODE_INFO_CHANGED = 1; + public final UsbPort mUsbPort; public UsbPortStatus mUsbPortStatus; public boolean mCanChangeMode; @@ -1321,18 +1437,23 @@ public class UsbPortManager { public long mLastConnectDurationMillis; // default initialized to 0 which means no changes reported public int mComplianceWarningChange; + // default initialized to 0 which means unchanged + public int mDisplayPortAltModeChange; PortInfo(@NonNull UsbManager usbManager, @NonNull String portId, int supportedModes, int supportedContaminantProtectionModes, boolean supportsEnableContaminantPresenceDetection, boolean supportsEnableContaminantPresenceProtection, - boolean supportsComplianceWarnings) { + boolean supportsComplianceWarnings, + int supportedAltModes) { mUsbPort = new UsbPort(usbManager, portId, supportedModes, supportedContaminantProtectionModes, supportsEnableContaminantPresenceDetection, supportsEnableContaminantPresenceProtection, - supportsComplianceWarnings); + supportsComplianceWarnings, + supportedAltModes); mComplianceWarningChange = COMPLIANCE_WARNING_UNCHANGED; + mDisplayPortAltModeChange = ALTMODE_INFO_UNCHANGED; } public boolean complianceWarningsChanged(@NonNull int[] complianceWarnings) { @@ -1344,6 +1465,34 @@ public class UsbPortManager { return true; } + public boolean displayPortAltModeChanged(DisplayPortAltModeInfo + displayPortAltModeInfo) { + DisplayPortAltModeInfo currentDisplayPortAltModeInfo = + mUsbPortStatus.getDisplayPortAltModeInfo(); + + mDisplayPortAltModeChange = ALTMODE_INFO_UNCHANGED; + + if (displayPortAltModeInfo == null + && currentDisplayPortAltModeInfo != null) { + mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED; + return true; + } + + if (currentDisplayPortAltModeInfo == null) { + if (displayPortAltModeInfo != null) { + mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED; + return true; + } + return false; + } + + if (!(currentDisplayPortAltModeInfo.equals(displayPortAltModeInfo))) { + mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED; + return true; + } + return false; + } + public boolean setStatus(int currentMode, boolean canChangeMode, int currentPowerRole, boolean canChangePowerRole, int currentDataRole, boolean canChangeDataRole, @@ -1364,7 +1513,7 @@ public class UsbPortManager { UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED, UsbPortStatus.DATA_STATUS_UNKNOWN, false, UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN, - new int[] {}); + new int[] {}, 0, null); dispositionChanged = true; } @@ -1410,7 +1559,7 @@ public class UsbPortManager { supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - new int[] {}); + new int[] {}, 0, null); dispositionChanged = true; } @@ -1431,8 +1580,16 @@ public class UsbPortManager { int supportedRoleCombinations, int contaminantProtectionStatus, int contaminantDetectionStatus, int usbDataStatus, boolean powerTransferLimited, int powerBrickConnectionStatus, - @NonNull int[] complianceWarnings) { + @NonNull int[] complianceWarnings, + int plugState, DisplayPortAltModeInfo displayPortAltModeInfo) { boolean dispositionChanged = false; + boolean complianceChanged = false; + boolean displayPortChanged = false; + + if (mUsbPortStatus != null) { + complianceChanged = complianceWarningsChanged(complianceWarnings); + displayPortChanged = displayPortAltModeChanged(displayPortAltModeInfo); + } mCanChangeMode = canChangeMode; mCanChangePowerRole = canChangePowerRole; @@ -1452,7 +1609,9 @@ public class UsbPortManager { || mUsbPortStatus.isPowerTransferLimited() != powerTransferLimited || mUsbPortStatus.getPowerBrickConnectionStatus() - != powerBrickConnectionStatus) { + != powerBrickConnectionStatus + || mUsbPortStatus.getPlugState() + != plugState) { if (mUsbPortStatus == null && complianceWarnings.length > 0) { mComplianceWarningChange = COMPLIANCE_WARNING_CHANGED; } @@ -1460,14 +1619,17 @@ public class UsbPortManager { supportedRoleCombinations, contaminantProtectionStatus, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - complianceWarnings); + complianceWarnings, plugState, displayPortAltModeInfo); dispositionChanged = true; - } else if (complianceWarningsChanged(complianceWarnings)) { - mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole, - supportedRoleCombinations, contaminantProtectionStatus, - contaminantDetectionStatus, usbDataStatus, - powerTransferLimited, powerBrickConnectionStatus, - complianceWarnings); + // Case used in order to send compliance warning broadcast or signal DisplayPort + // listeners. These targeted broadcasts don't use dispositionChanged to broadcast to + // general ACTION_USB_PORT_CHANGED. + } else if (complianceChanged || displayPortChanged) { + mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, + currentDataRole, supportedRoleCombinations, + contaminantProtectionStatus, contaminantDetectionStatus, + usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, + complianceWarnings, plugState, displayPortAltModeInfo); } if (mUsbPortStatus.isConnected() && mConnectedAtMillis == 0) { diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 6eb04d94e7570..7d84222d55a45 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -36,6 +36,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.hardware.usb.IUsbManager; +import android.hardware.usb.IDisplayPortAltModeInfoListener; import android.hardware.usb.IUsbOperationInternal; import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbAccessory; @@ -43,6 +44,7 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.DisplayPortAltModeInfo; import android.os.Binder; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -902,6 +904,45 @@ public class UsbService extends IUsbManager.Stub { } } + @Override + public boolean registerForDisplayPortEvents( + @NonNull IDisplayPortAltModeInfoListener listener) { + Objects.requireNonNull(listener, "registerForDisplayPortEvents: listener " + + "must not be null."); + + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + + final long ident = Binder.clearCallingIdentity(); + try { + if (mPortManager != null) { + return mPortManager.registerForDisplayPortEvents(listener); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + + return false; + } + + @Override + public void unregisterForDisplayPortEvents( + @NonNull IDisplayPortAltModeInfoListener listener) { + Objects.requireNonNull(listener, "unregisterForDisplayPortEvents: listener " + + "must not be null."); + + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + + final long ident = Binder.clearCallingIdentity(); + try { + if (mPortManager != null) { + mPortManager.unregisterForDisplayPortEvents(listener); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @NeverCompile // Avoid size overhead of debugging code. @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { @@ -993,6 +1034,7 @@ public class UsbService extends IUsbManager.Stub { int i; boolean supportsComplianceWarnings = false; + boolean supportsDisplayPortAltMode = false; switch (args[2]) { case "ufp": supportedModes = MODE_UFP; @@ -1015,14 +1057,17 @@ public class UsbService extends IUsbManager.Stub { case "--compliance-warnings": supportsComplianceWarnings = true; continue; + case "--displayport": + supportsDisplayPortAltMode = true; + continue; default: pw.println("Invalid Identifier: " + args[i]); } } if (mPortManager != null) { mPortManager.addSimulatedPort(portId, supportedModes, - supportsComplianceWarnings, - pw); + supportsComplianceWarnings, supportsDisplayPortAltMode, + pw); pw.println(); mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), "", 0); @@ -1124,6 +1169,29 @@ public class UsbService extends IUsbManager.Stub { mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), "", 0); } + } else if ("set-displayport-status".equals(args[0]) && args.length == 5) { + final String portId = args[1]; + final int partnerSinkStatus = Integer.parseInt(args[2]); + final int cableStatus = Integer.parseInt(args[3]); + final int displayPortNumLanes = Integer.parseInt(args[4]); + if (mPortManager != null) { + mPortManager.simulateDisplayPortAltModeInfo(portId, + partnerSinkStatus, cableStatus, displayPortNumLanes, pw); + pw.println(); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); + } + } else if ("reset-displayport-status".equals(args[0]) && args.length == 2) { + final String portId = args[1]; + if (mPortManager != null) { + mPortManager.simulateDisplayPortAltModeInfo(portId, + DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN, + DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN, + 0, pw); + pw.println(); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); + } } else if ("ports".equals(args[0]) && args.length == 1) { if (mPortManager != null) { mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), @@ -1138,6 +1206,7 @@ public class UsbService extends IUsbManager.Stub { pw.println(" add-port "); pw.println(" include:"); pw.println(" --compliance-warnings: enables compliance warnings on port"); + pw.println(" --displayport: enables DisplayPort Alt Mode on port"); pw.println(" connect-port "); pw.println(" (add ? suffix if mode, power role, or data role can be changed)"); pw.println(" disconnect-port "); @@ -1148,7 +1217,8 @@ public class UsbService extends IUsbManager.Stub { pw.println(" dumpsys usb set-port-roles \"default\" source device"); pw.println(); pw.println("Example USB type C port simulation with full capabilities:"); - pw.println(" dumpsys usb add-port \"matrix\" dual --compliance-warnings"); + pw.println(" dumpsys usb add-port \"matrix\" dual --compliance-warnings " + + "--displayport"); pw.println(" dumpsys usb connect-port \"matrix\" ufp? sink? device?"); pw.println(" dumpsys usb ports"); pw.println(" dumpsys usb disconnect-port \"matrix\""); @@ -1186,6 +1256,14 @@ public class UsbService extends IUsbManager.Stub { pw.println(" 3: bc12"); pw.println(" 4: missing rp"); pw.println(); + pw.println("Example simulate DisplayPort Alt Mode Changes:"); + pw.println(" dumpsys usb add-port \"matrix\" dual --displayport"); + pw.println(" dumpsys usb set-displayport-status \"matrix\" " + + " "); + pw.println(" dumpsys usb reset-displayport-status \"matrix\""); + pw.println("reset-displayport-status can also be used in order to set"); + pw.println("the DisplayPortInfo to default values."); + pw.println(); pw.println("Example USB device descriptors:"); pw.println(" dumpsys usb dump-descriptors -dump-short"); pw.println(" dumpsys usb dump-descriptors -dump-tree"); 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 e6a3e53435076..ef32e938217e8 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 @@ -15,7 +15,9 @@ */ package com.android.server.usb.hal.port; +import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.DisplayPortAltModeInfo; import android.os.Parcel; import android.os.Parcelable; @@ -42,6 +44,9 @@ public final class RawPortInfo implements Parcelable { public int powerBrickConnectionStatus; public final boolean supportsComplianceWarnings; public int[] complianceWarnings; + public int plugState; + public int supportedAltModes; + public DisplayPortAltModeInfo displayPortAltModeInfo; public RawPortInfo(String portId, int supportedModes) { this.portId = portId; @@ -56,6 +61,9 @@ public final class RawPortInfo implements Parcelable { this.powerBrickConnectionStatus = UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN; this.supportsComplianceWarnings = false; this.complianceWarnings = new int[] {}; + this.plugState = UsbPortStatus.PLUG_STATE_UNKNOWN; + this.supportedAltModes = 0; + this.displayPortAltModeInfo = null; } public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes, @@ -76,7 +84,8 @@ public final class RawPortInfo implements Parcelable { supportsEnableContaminantPresenceProtection, contaminantProtectionStatus, supportsEnableContaminantPresenceDetection, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - false, new int[] {}); + false, new int[] {}, UsbPortStatus.PLUG_STATE_UNKNOWN, + 0, null); } public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes, @@ -91,7 +100,10 @@ public final class RawPortInfo implements Parcelable { boolean powerTransferLimited, int powerBrickConnectionStatus, boolean supportsComplianceWarnings, - int[] complianceWarnings) { + int[] complianceWarnings, + int plugState, + int supportedAltModes, + DisplayPortAltModeInfo displayPortAltModeInfo) { this.portId = portId; this.supportedModes = supportedModes; this.supportedContaminantProtectionModes = supportedContaminantProtectionModes; @@ -112,6 +124,9 @@ public final class RawPortInfo implements Parcelable { this.powerBrickConnectionStatus = powerBrickConnectionStatus; this.supportsComplianceWarnings = supportsComplianceWarnings; this.complianceWarnings = complianceWarnings; + this.plugState = plugState; + this.supportedAltModes = supportedAltModes; + this.displayPortAltModeInfo = displayPortAltModeInfo; } @Override @@ -139,12 +154,19 @@ public final class RawPortInfo implements Parcelable { dest.writeInt(powerBrickConnectionStatus); dest.writeBoolean(supportsComplianceWarnings); dest.writeIntArray(complianceWarnings); + dest.writeInt(plugState); + dest.writeInt(supportedAltModes); + if ((supportedAltModes & UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT) != 0) { + displayPortAltModeInfo.writeToParcel(dest, 0); + } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public RawPortInfo createFromParcel(Parcel in) { + DisplayPortAltModeInfo displayPortAltModeInfo; + String id = in.readString(); int supportedModes = in.readInt(); int supportedContaminantProtectionModes = in.readInt(); @@ -163,6 +185,13 @@ public final class RawPortInfo implements Parcelable { int powerBrickConnectionStatus = in.readInt(); boolean supportsComplianceWarnings = in.readBoolean(); int[] complianceWarnings = in.createIntArray(); + int plugState = in.readInt(); + int supportedAltModes = in.readInt(); + if ((supportedAltModes & UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT) != 0) { + displayPortAltModeInfo = DisplayPortAltModeInfo.CREATOR.createFromParcel(in); + } else { + displayPortAltModeInfo = null; + } return new RawPortInfo(id, supportedModes, supportedContaminantProtectionModes, currentMode, canChangeMode, currentPowerRole, canChangePowerRole, @@ -172,7 +201,8 @@ public final class RawPortInfo implements Parcelable { supportsEnableContaminantPresenceDetection, contaminantDetectionStatus, usbDataStatus, powerTransferLimited, powerBrickConnectionStatus, - supportsComplianceWarnings, complianceWarnings); + supportsComplianceWarnings, complianceWarnings, + plugState, supportedAltModes, displayPortAltModeInfo); } @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 ff4268fda93e6..b9ccacea7aa48 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 @@ -35,6 +35,10 @@ import android.hardware.usb.IUsbCallback; import android.hardware.usb.PortRole; import android.hardware.usb.PortStatus; import android.hardware.usb.ComplianceWarning; +import android.hardware.usb.DisplayPortAltModeInfo; +import android.hardware.usb.AltModeData; +import android.hardware.usb.AltModeData.DisplayPortAltModeData; +import android.hardware.usb.DisplayPortAltModePinAssignment; import android.os.Build; import android.os.ServiceManager; import android.os.IBinder; @@ -600,6 +604,47 @@ public final class UsbPortAidl implements UsbPortHal { return newComplianceWarnings.toArray(); } + private int toSupportedAltModesInt(android.hardware.usb.AltModeData[] supportedAltModes) { + int supportedAltModesInt = 0; + for (android.hardware.usb.AltModeData altModeData : supportedAltModes) { + switch (altModeData.getTag()) { + case AltModeData.displayPortAltModeData: + supportedAltModesInt |= UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT; + break; + } + } + return supportedAltModesInt; + } + + private int toDisplayPortAltModeNumLanesInt(int pinAssignment) { + switch (pinAssignment) { + case DisplayPortAltModePinAssignment.A: + case DisplayPortAltModePinAssignment.C: + case DisplayPortAltModePinAssignment.E: + return 4; + case DisplayPortAltModePinAssignment.B: + case DisplayPortAltModePinAssignment.D: + case DisplayPortAltModePinAssignment.F: + return 2; + default: + return 0; + } + } + + private DisplayPortAltModeInfo formatDisplayPortAltModeInfo( + android.hardware.usb.AltModeData[] supportedAltModes) { + for (android.hardware.usb.AltModeData altModeData : supportedAltModes) { + if (altModeData.getTag() == AltModeData.displayPortAltModeData) { + DisplayPortAltModeData displayPortData = + altModeData.getDisplayPortAltModeData(); + return new DisplayPortAltModeInfo(displayPortData.partnerSinkStatus, + displayPortData.cableStatus, + toDisplayPortAltModeNumLanesInt(displayPortData.pinAssignment)); + } + } + return null; + } + @Override public void notifyPortStatusChange( android.hardware.usb.PortStatus[] currentPortStatus, int retval) { @@ -635,7 +680,10 @@ public final class UsbPortAidl implements UsbPortHal { current.powerTransferLimited, current.powerBrickStatus, current.supportsComplianceWarnings, - formatComplianceWarnings(current.complianceWarnings)); + formatComplianceWarnings(current.complianceWarnings), + current.plugOrientation, + toSupportedAltModesInt(current.supportedAltModes), + formatDisplayPortAltModeInfo(current.supportedAltModes)); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback AIDL V1: " + current.portName); 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 10403c1a5f73a..a7ecabb7c80e6 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 @@ -35,7 +35,8 @@ import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE; import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE; import static android.hardware.usb.UsbPortStatus.DATA_STATUS_UNKNOWN; - +import static android.hardware.usb.UsbPortStatus.PLUG_STATE_UNKNOWN; +import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN; import static com.android.server.usb.UsbPortManager.logAndPrint; import static com.android.server.usb.UsbPortManager.logAndPrintException; @@ -422,7 +423,10 @@ public final class UsbPortHidl implements UsbPortHal { false, CONTAMINANT_PROTECTION_NONE, false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataStatus, false, POWER_BRICK_STATUS_UNKNOWN, - false, new int[] {}); + false, new int[] {}, + PLUG_STATE_UNKNOWN, + 0, + null); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_0: " + current.portName); @@ -457,7 +461,10 @@ public final class UsbPortHidl implements UsbPortHal { false, CONTAMINANT_PROTECTION_NONE, false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataStatus, false, POWER_BRICK_STATUS_UNKNOWN, - false, new int[] {}); + false, new int[] {}, + PLUG_STATE_UNKNOWN, + 0, + null); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_1: " + current.status.portName); @@ -496,7 +503,10 @@ public final class UsbPortHidl implements UsbPortHal { current.contaminantDetectionStatus, sUsbDataStatus, false, POWER_BRICK_STATUS_UNKNOWN, - false, new int[] {}); + false, new int[] {}, + PLUG_STATE_UNKNOWN, + 0, + null); newPortInfo.add(temp); UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_2: " + current.status_1_1.status.portName);