Merge "Usb DisplayPort alt mode frameworks api"
This commit is contained in:
@@ -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<android.hardware.usb.DisplayPortAltModeInfo> 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<android.hardware.usb.UsbPort> 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<java.lang.Integer>);
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
|
||||
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean supportsComplianceWarnings();
|
||||
@@ -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
|
||||
|
||||
19
core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl
Normal file
19
core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl
Normal file
@@ -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;
|
||||
206
core/java/android/hardware/usb/DisplayPortAltModeInfo.java
Normal file
206
core/java/android/hardware/usb/DisplayPortAltModeInfo.java
Normal file
@@ -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:
|
||||
* <ul>
|
||||
* <li> No port partner is connected to the device
|
||||
* <li> The USB Power Delivery Discover Identity command has not been issued to the port
|
||||
* partner via SOP messaging.
|
||||
* </ul>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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<DisplayPortAltModeInfo> CREATOR =
|
||||
new Parcelable.Creator<DisplayPortAltModeInfo>() {
|
||||
@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];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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<ParcelableUsbPort> 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
|
||||
|
||||
@@ -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<DisplayPortAltModeInfoListener, Executor> 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<DisplayPortAltModeInfoListener, Executor> 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.
|
||||
* <p>
|
||||
* 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<DisplayPortAltModeInfoListener,
|
||||
Executor>();
|
||||
}
|
||||
|
||||
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.
|
||||
* <p>
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
@@ -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,
|
||||
|
||||
@@ -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<UsbPortStatus> 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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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).
|
||||
* </p>
|
||||
*/
|
||||
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<IBinder, IDisplayPortAltModeInfoListener> mDisplayPortListeners =
|
||||
new ArrayMap<IBinder, IDisplayPortAltModeInfoListener>();
|
||||
|
||||
/**
|
||||
* 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<RawPortInfo> 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) {
|
||||
|
||||
@@ -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 <id> <ufp|dfp|dual|none> <optional args>");
|
||||
pw.println(" <optional args> include:");
|
||||
pw.println(" --compliance-warnings: enables compliance warnings on port");
|
||||
pw.println(" --displayport: enables DisplayPort Alt Mode on port");
|
||||
pw.println(" connect-port <id> <ufp|dfp><?> <source|sink><?> <host|device><?>");
|
||||
pw.println(" (add ? suffix if mode, power role, or data role can be changed)");
|
||||
pw.println(" disconnect-port <id>");
|
||||
@@ -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\" <partner-sink>"
|
||||
+ " <cable> <num-lanes>");
|
||||
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");
|
||||
|
||||
@@ -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<RawPortInfo> CREATOR =
|
||||
new Parcelable.Creator<RawPortInfo>() {
|
||||
@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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user