Support USB V1.2 HAL
USB V1.2 HAL supports contaminant detection interface.
Bug: 119642987
Bug: 117330206
Bug: 77606903
Test: Manually tested for notification pop-up
Change-Id: I304fb4933ba8b8eaa08c32c9e8c116cba7aa6380
diff --git a/Android.bp b/Android.bp
index b68312b..8f18a46 100644
--- a/Android.bp
+++ b/Android.bp
@@ -749,6 +749,7 @@
"android.hardware.tv.input-V1.0-java-constants",
"android.hardware.usb-V1.0-java-constants",
"android.hardware.usb-V1.1-java-constants",
+ "android.hardware.usb-V1.2-java-constants",
"android.hardware.vibrator-V1.0-java",
"android.hardware.vibrator-V1.1-java",
"android.hardware.vibrator-V1.2-java",
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index edc3f94..299a00a 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -120,6 +120,9 @@
/* Sets the port's current role. */
void setPortRoles(in String portId, int powerRole, int dataRole);
+ /* Enable/disable contaminant detection */
+ void enableContaminantDetection(in String portId, boolean enable);
+
/* Sets USB device connection handler. */
void setUsbDeviceConnectionHandler(in ComponentName usbDeviceConnectionHandler);
}
diff --git a/core/java/android/hardware/usb/ParcelableUsbPort.java b/core/java/android/hardware/usb/ParcelableUsbPort.java
index 7f7ba96..30388af 100644
--- a/core/java/android/hardware/usb/ParcelableUsbPort.java
+++ b/core/java/android/hardware/usb/ParcelableUsbPort.java
@@ -31,10 +31,21 @@
public final class ParcelableUsbPort implements Parcelable {
private final @NonNull String mId;
private final int mSupportedModes;
+ private final int mSupportedContaminantProtectionModes;
+ private final boolean mSupportsEnableContaminantPresenceProtection;
+ private final boolean mSupportsEnableContaminantPresenceDetection;
- private ParcelableUsbPort(@NonNull String id, int supportedModes) {
+ private ParcelableUsbPort(@NonNull String id, int supportedModes,
+ int supportedContaminantProtectionModes,
+ boolean supportsEnableContaminantPresenceProtection,
+ boolean supportsEnableContaminantPresenceDetection) {
mId = id;
mSupportedModes = supportedModes;
+ mSupportedContaminantProtectionModes = supportedContaminantProtectionModes;
+ mSupportsEnableContaminantPresenceProtection =
+ supportsEnableContaminantPresenceProtection;
+ mSupportsEnableContaminantPresenceDetection =
+ supportsEnableContaminantPresenceDetection;
}
/**
@@ -45,7 +56,10 @@
* @return The parcelable version of the port
*/
public static @NonNull ParcelableUsbPort of(@NonNull UsbPort port) {
- return new ParcelableUsbPort(port.getId(), port.getSupportedModes());
+ return new ParcelableUsbPort(port.getId(), port.getSupportedModes(),
+ port.getSupportedContaminantProtectionModes(),
+ port.supportsEnableContaminantPresenceProtection(),
+ port.supportsEnableContaminantPresenceDetection());
}
/**
@@ -56,7 +70,9 @@
* @return The UsbPort for this object
*/
public @NonNull UsbPort getUsbPort(@NonNull UsbManager usbManager) {
- return new UsbPort(usbManager, mId, mSupportedModes);
+ return new UsbPort(usbManager, mId, mSupportedModes, mSupportedContaminantProtectionModes,
+ mSupportsEnableContaminantPresenceProtection,
+ mSupportsEnableContaminantPresenceDetection);
}
@Override
@@ -68,6 +84,9 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mId);
dest.writeInt(mSupportedModes);
+ dest.writeInt(mSupportedContaminantProtectionModes);
+ dest.writeBoolean(mSupportsEnableContaminantPresenceProtection);
+ dest.writeBoolean(mSupportsEnableContaminantPresenceDetection);
}
public static final Creator<ParcelableUsbPort> CREATOR =
@@ -76,7 +95,14 @@
public ParcelableUsbPort createFromParcel(Parcel in) {
String id = in.readString();
int supportedModes = in.readInt();
- return new ParcelableUsbPort(id, supportedModes);
+ int supportedContaminantProtectionModes = in.readInt();
+ boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
+ boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
+
+ return new ParcelableUsbPort(id, supportedModes,
+ supportedContaminantProtectionModes,
+ supportsEnableContaminantPresenceProtection,
+ supportsEnableContaminantPresenceDetection);
}
@Override
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 6014478..eb148b9 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -854,6 +854,20 @@
}
/**
+ * Enables USB port contaminant detection algorithm.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ void enableContaminantDetection(@NonNull UsbPort port, boolean enable) {
+ try {
+ mService.enableContaminantDetection(port.getId(), enable);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Sets the component that will handle USB device connection.
* <p>
* Setting component allows to specify external USB host manager to handle use cases, where
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index 37154e4..c674480 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -16,6 +16,10 @@
package android.hardware.usb;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_DETECTED;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_DISABLED;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_NONE;
@@ -48,16 +52,21 @@
private final String mId;
private final int mSupportedModes;
private final UsbManager mUsbManager;
+ private final int mSupportedContaminantProtectionModes;
+ private final boolean mSupportsEnableContaminantPresenceProtection;
+ private final boolean mSupportsEnableContaminantPresenceDetection;
private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES;
-
/**
* Points to the first power role in the IUsb HAL.
*/
private static final int POWER_ROLE_OFFSET = Constants.PortPowerRole.NONE;
/** @hide */
- public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes) {
+ public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes,
+ int supportedContaminantProtectionModes,
+ boolean supportsEnableContaminantPresenceProtection,
+ boolean supportsEnableContaminantPresenceDetection) {
Preconditions.checkNotNull(id);
Preconditions.checkFlagsArgument(supportedModes,
MODE_DFP | MODE_UFP | MODE_AUDIO_ACCESSORY | MODE_DEBUG_ACCESSORY);
@@ -65,6 +74,11 @@
mUsbManager = usbManager;
mId = id;
mSupportedModes = supportedModes;
+ mSupportedContaminantProtectionModes = supportedContaminantProtectionModes;
+ mSupportsEnableContaminantPresenceProtection =
+ supportsEnableContaminantPresenceProtection;
+ mSupportsEnableContaminantPresenceDetection =
+ supportsEnableContaminantPresenceDetection;
}
/**
@@ -93,6 +107,36 @@
return mSupportedModes;
}
+ /**
+ * Gets the supported port proctection modes when the port is contaminated.
+ * <p>
+ * The actual mode of the port is decided by the hardware
+ * </p>
+ *
+ * @hide
+ */
+ public int getSupportedContaminantProtectionModes() {
+ return mSupportedContaminantProtectionModes;
+ }
+
+ /**
+ * Tells if UsbService can enable/disable contaminant presence protection.
+ *
+ * @hide
+ */
+ public boolean supportsEnableContaminantPresenceProtection() {
+ return mSupportsEnableContaminantPresenceProtection;
+ }
+
+ /**
+ * Tells if UsbService can enable/disable contaminant presence detection.
+ *
+ * @hide
+ */
+ public boolean supportsEnableContaminantPresenceDetection() {
+ return mSupportsEnableContaminantPresenceDetection;
+ }
+
/**
* Gets the status of this USB port.
*
@@ -131,6 +175,12 @@
}
/**
+ * @hide
+ **/
+ public void enableContaminantDetection(boolean enable) {
+ mUsbManager.enableContaminantDetection(this, enable);
+ }
+ /**
* Combines one power and one data role together into a unique value with
* exactly one bit set. This can be used to efficiently determine whether
* a combination of roles is supported by testing whether that bit is present
@@ -206,6 +256,22 @@
}
/** @hide */
+ public static String contaminantPresenceStatusToString(int contaminantPresenceStatus) {
+ switch (contaminantPresenceStatus) {
+ case CONTAMINANT_DETECTION_NOT_SUPPORTED:
+ return "not-supported";
+ case CONTAMINANT_DETECTION_DISABLED:
+ return "disabled";
+ case CONTAMINANT_DETECTION_DETECTED:
+ return "detected";
+ case CONTAMINANT_DETECTION_NOT_DETECTED:
+ return "not detected";
+ default:
+ return Integer.toString(contaminantPresenceStatus);
+ }
+ }
+
+ /** @hide */
public static String roleCombinationsToString(int combo) {
StringBuilder result = new StringBuilder();
result.append("[");
@@ -264,6 +330,11 @@
@Override
public String toString() {
- return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
+ return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes)
+ + "supportedContaminantProtectionModes=" + mSupportedContaminantProtectionModes
+ + "supportsEnableContaminantPresenceProtection="
+ + mSupportsEnableContaminantPresenceProtection
+ + "supportsEnableContaminantPresenceDetection="
+ + mSupportsEnableContaminantPresenceDetection;
}
}
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index d30201a..426dba8 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -39,6 +39,8 @@
private final @UsbPowerRole int mCurrentPowerRole;
private final @UsbDataRole int mCurrentDataRole;
private final int mSupportedRoleCombinations;
+ private final @ContaminantProtectionStatus int mContaminantProtectionStatus;
+ private final @ContaminantDetectionStatus int mContaminantDetectionStatus;
/**
* Power role: This USB port does not have a power role.
@@ -131,6 +133,93 @@
public static final int MODE_DEBUG_ACCESSORY =
android.hardware.usb.V1_1.Constants.PortMode_1_1.DEBUG_ACCESSORY;
+ /**
+ * Contaminant presence detection not supported by the device.
+ * @hide
+ */
+ public static final int CONTAMINANT_DETECTION_NOT_SUPPORTED =
+ android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.NOT_SUPPORTED;
+
+ /**
+ * Contaminant presence detection supported but disabled.
+ * @hide
+ */
+ public static final int CONTAMINANT_DETECTION_DISABLED =
+ android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.DISABLED;
+
+ /**
+ * Contaminant presence enabled but not detected.
+ * @hide
+ */
+ public static final int CONTAMINANT_DETECTION_NOT_DETECTED =
+ android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.NOT_DETECTED;
+
+ /**
+ * Contaminant presence enabled and detected.
+ * @hide
+ */
+ public static final int CONTAMINANT_DETECTION_DETECTED =
+ android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.DETECTED;
+
+ /**
+ * Contaminant protection - No action performed upon detection of
+ * contaminant presence.
+ * @hide
+ */
+ public static final int CONTAMINANT_PROTECTION_NONE =
+ android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.NONE;
+
+ /**
+ * Contaminant protection - Port is forced to sink upon detection of
+ * contaminant presence.
+ * @hide
+ */
+ public static final int CONTAMINANT_PROTECTION_SINK =
+ android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_SINK;
+
+ /**
+ * Contaminant protection - Port is forced to source upon detection of
+ * contaminant presence.
+ * @hide
+ */
+ public static final int CONTAMINANT_PROTECTION_SOURCE =
+ android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_SOURCE;
+
+ /**
+ * Contaminant protection - Port is disabled upon detection of
+ * contaminant presence.
+ * @hide
+ */
+ public static final int CONTAMINANT_PROTECTION_FORCE_DISABLE =
+ android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_DISABLE;
+
+ /**
+ * Contaminant protection - Port is disabled upon detection of
+ * contaminant presence.
+ * @hide
+ */
+ public static final int CONTAMINANT_PROTECTION_DISABLED =
+ android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.DISABLED;
+
+ @IntDef(prefix = { "CONTAMINANT_DETECION_" }, flag = true, value = {
+ CONTAMINANT_DETECTION_NOT_SUPPORTED,
+ CONTAMINANT_DETECTION_DISABLED,
+ CONTAMINANT_DETECTION_NOT_DETECTED,
+ CONTAMINANT_DETECTION_DETECTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ContaminantDetectionStatus{}
+
+ @IntDef(prefix = { "CONTAMINANT_PROTECTION_" }, flag = true, value = {
+ CONTAMINANT_PROTECTION_NONE,
+ CONTAMINANT_PROTECTION_SINK,
+ CONTAMINANT_PROTECTION_SOURCE,
+ CONTAMINANT_PROTECTION_FORCE_DISABLE,
+ CONTAMINANT_PROTECTION_DISABLED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ContaminantProtectionStatus{}
+
@IntDef(prefix = { "MODE_" }, flag = true, value = {
MODE_NONE,
MODE_DFP,
@@ -142,12 +231,15 @@
@interface UsbPortMode{}
/** @hide */
- public UsbPortStatus(int currentMode, @UsbPowerRole int currentPowerRole,
- @UsbDataRole int currentDataRole, int supportedRoleCombinations) {
+ public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
+ int supportedRoleCombinations, int contaminantProtectionStatus,
+ int contaminantDetectionStatus) {
mCurrentMode = currentMode;
mCurrentPowerRole = currentPowerRole;
mCurrentDataRole = currentDataRole;
mSupportedRoleCombinations = supportedRoleCombinations;
+ mContaminantProtectionStatus = contaminantProtectionStatus;
+ mContaminantDetectionStatus = contaminantDetectionStatus;
}
/**
@@ -212,6 +304,24 @@
return mSupportedRoleCombinations;
}
+ /**
+ * Returns contaminant detection status.
+ *
+ * @hide
+ */
+ public @ContaminantDetectionStatus int getContaminantDetectionStatus() {
+ return mContaminantDetectionStatus;
+ }
+
+ /**
+ * Returns contamiant protection status.
+ *
+ * @hide
+ */
+ public @ContaminantProtectionStatus int getContaminantProtectionStatus() {
+ return mContaminantProtectionStatus;
+ }
+
@Override
public String toString() {
return "UsbPortStatus{connected=" + isConnected()
@@ -220,6 +330,10 @@
+ ", currentDataRole=" + UsbPort.dataRoleToString(mCurrentDataRole)
+ ", supportedRoleCombinations="
+ UsbPort.roleCombinationsToString(mSupportedRoleCombinations)
+ + ", contaminantDetectionStatus="
+ + getContaminantDetectionStatus()
+ + ", contaminantProtectionStatus="
+ + getContaminantProtectionStatus()
+ "}";
}
@@ -234,6 +348,8 @@
dest.writeInt(mCurrentPowerRole);
dest.writeInt(mCurrentDataRole);
dest.writeInt(mSupportedRoleCombinations);
+ dest.writeInt(mContaminantProtectionStatus);
+ dest.writeInt(mContaminantDetectionStatus);
}
public static final Parcelable.Creator<UsbPortStatus> CREATOR =
@@ -244,8 +360,11 @@
int currentPowerRole = in.readInt();
int currentDataRole = in.readInt();
int supportedRoleCombinations = in.readInt();
+ int contaminantProtectionStatus = in.readInt();
+ int contaminantDetectionStatus = in.readInt();
return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
- supportedRoleCombinations);
+ supportedRoleCombinations, contaminantProtectionStatus,
+ contaminantDetectionStatus);
}
@Override
diff --git a/core/java/com/android/internal/usb/DumpUtils.java b/core/java/com/android/internal/usb/DumpUtils.java
index 240c2e7..3260136 100644
--- a/core/java/com/android/internal/usb/DumpUtils.java
+++ b/core/java/com/android/internal/usb/DumpUtils.java
@@ -196,6 +196,15 @@
}
}
+ private static void writeContaminantPresenceStatus(@NonNull DualDumpOutputStream dump,
+ @NonNull String idName, long id, int contaminantPresenceStatus) {
+ if (dump.isProto()) {
+ dump.write(idName, id, contaminantPresenceStatus);
+ } else {
+ dump.write(idName, id,
+ UsbPort.contaminantPresenceStatusToString(contaminantPresenceStatus));
+ }
+ }
public static void writePortStatus(@NonNull DualDumpOutputStream dump, @NonNull String idName,
long id, @NonNull UsbPortStatus status) {
@@ -232,6 +241,10 @@
dump.end(roleCombinationToken);
}
+ writeContaminantPresenceStatus(dump, "contaminant_presence_status",
+ UsbPortStatusProto.CONTAMINANT_PRESENCE_STATUS,
+ status.getContaminantDetectionStatus());
+
dump.end(token);
}
}
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index f7dcee2..00fae3d 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -245,11 +245,20 @@
DATA_ROLE_DEVICE = 2;
}
+ /* Same as android.hardware.usb.V1_2.Constants.ContaminantPresenceStatus */
+ enum ContaminantPresenceStatus {
+ CONTAMINANT_STATUS_NOT_SUPPORTED = 0;
+ CONTAMINANT_STATUS_DISABLED = 1;
+ CONTAMINANT_STATUS_NOT_DETECTED = 2;
+ CONTAMINANT_STATUS_DETECTED = 3;
+ }
+
optional bool connected = 1;
optional UsbPortProto.Mode current_mode = 2;
optional PowerRole power_role = 3;
optional DataRole data_role = 4;
repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
+ optional ContaminantPresenceStatus contaminant_presence_status = 6;
}
message UsbPortStatusRoleCombinationProto {
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index feb7b76..20855b7 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -10,6 +10,7 @@
static_libs: [
"android.hardware.usb-V1.0-java",
"android.hardware.usb-V1.1-java",
+ "android.hardware.usb-V1.2-java",
"android.hardware.usb.gadget-V1.0-java",
],
}
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 6f210e3..3d051d8 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -16,6 +16,8 @@
package com.android.server.usb;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST;
import static android.hardware.usb.UsbPortStatus.MODE_DFP;
@@ -35,13 +37,13 @@
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
-import android.hardware.usb.V1_0.IUsb;
import android.hardware.usb.V1_0.PortRole;
import android.hardware.usb.V1_0.PortRoleType;
-import android.hardware.usb.V1_0.PortStatus;
import android.hardware.usb.V1_0.Status;
-import android.hardware.usb.V1_1.IUsbCallback;
import android.hardware.usb.V1_1.PortStatus_1_1;
+import android.hardware.usb.V1_2.IUsb;
+import android.hardware.usb.V1_2.IUsbCallback;
+import android.hardware.usb.V1_2.PortStatus;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.os.Bundle;
@@ -184,6 +186,43 @@
}
}
+ /**
+ * Enables/disables contaminant detection.
+ *
+ * @param portId port identifier.
+ * @param enable enable contaminant detection when set to true.
+ */
+ public void enableContaminantDetection(@NonNull String portId, boolean enable,
+ @NonNull IndentingPrintWriter pw) {
+ final PortInfo portInfo = mPorts.get(portId);
+ if (portInfo == null) {
+ if (pw != null) {
+ pw.println("No such USB port: " + portId);
+ }
+ return;
+ }
+
+ if (!portInfo.mUsbPort.supportsEnableContaminantPresenceDetection()) {
+ return;
+ }
+
+ if ((enable && portInfo.mUsbPortStatus.getContaminantDetectionStatus()
+ != UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) || (!enable
+ && portInfo.mUsbPortStatus.getContaminantDetectionStatus()
+ == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED)
+ || (portInfo.mUsbPortStatus.getContaminantDetectionStatus()
+ == UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED)) {
+ return;
+ }
+
+ try {
+ // Oneway call into the hal
+ mProxy.enableContaminantPresenceDetection(portId, enable);
+ } catch (RemoteException e) {
+ logAndPrintException(null, "Failed to set contaminant detection", e);
+ }
+ }
+
public void setPortRoles(String portId, int newPowerRole, int newDataRole,
IndentingPrintWriter pw) {
synchronized (mLock) {
@@ -441,7 +480,8 @@
this.portManager = portManager;
}
- public void notifyPortStatusChange(ArrayList<PortStatus> currentPortStatus, int retval) {
+ public void notifyPortStatusChange(
+ ArrayList<android.hardware.usb.V1_0.PortStatus> currentPortStatus, int retval) {
if (!portManager.mSystemReady) {
return;
}
@@ -453,14 +493,17 @@
ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
- for (PortStatus current : currentPortStatus) {
+ for (android.hardware.usb.V1_0.PortStatus current : currentPortStatus) {
RawPortInfo temp = new RawPortInfo(current.portName,
- current.supportedModes, current.currentMode,
+ current.supportedModes, CONTAMINANT_PROTECTION_NONE,
+ current.currentMode,
current.canChangeMode, current.currentPowerRole,
current.canChangePowerRole,
- current.currentDataRole, current.canChangeDataRole);
+ current.currentDataRole, current.canChangeDataRole,
+ false, CONTAMINANT_PROTECTION_NONE,
+ false, CONTAMINANT_DETECTION_NOT_SUPPORTED);
newPortInfo.add(temp);
- logAndPrint(Log.INFO, pw, "ClientCallback: " + current.portName);
+ logAndPrint(Log.INFO, pw, "ClientCallback V1_0: " + current.portName);
}
Message message = portManager.mHandler.obtainMessage();
@@ -485,14 +528,61 @@
ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
- for (PortStatus_1_1 current : currentPortStatus) {
+ int numStatus = currentPortStatus.size();
+ for (int i = 0; i < numStatus; i++) {
+ PortStatus_1_1 current = currentPortStatus.get(i);
RawPortInfo temp = new RawPortInfo(current.status.portName,
- current.supportedModes, current.currentMode,
+ current.supportedModes, CONTAMINANT_PROTECTION_NONE,
+ current.currentMode,
current.status.canChangeMode, current.status.currentPowerRole,
current.status.canChangePowerRole,
- current.status.currentDataRole, current.status.canChangeDataRole);
+ current.status.currentDataRole, current.status.canChangeDataRole,
+ false, CONTAMINANT_PROTECTION_NONE,
+ false, CONTAMINANT_DETECTION_NOT_SUPPORTED);
newPortInfo.add(temp);
- logAndPrint(Log.INFO, pw, "ClientCallback: " + current.status.portName);
+ logAndPrint(Log.INFO, pw, "ClientCallback V1_1: " + current.status.portName);
+ }
+
+ Message message = portManager.mHandler.obtainMessage();
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
+ message.what = MSG_UPDATE_PORTS;
+ message.setData(bundle);
+ portManager.mHandler.sendMessage(message);
+ }
+
+ public void notifyPortStatusChange_1_2(
+ ArrayList<PortStatus> currentPortStatus, int retval) {
+ if (!portManager.mSystemReady) {
+ return;
+ }
+
+ if (retval != Status.SUCCESS) {
+ logAndPrint(Log.ERROR, pw, "port status enquiry failed");
+ return;
+ }
+
+ ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
+
+ int numStatus = currentPortStatus.size();
+ for (int i = 0; i < numStatus; i++) {
+ PortStatus current = currentPortStatus.get(i);
+ RawPortInfo temp = new RawPortInfo(current.status_1_1.status.portName,
+ current.status_1_1.supportedModes,
+ current.supportedContaminantProtectionModes,
+ current.status_1_1.currentMode,
+ current.status_1_1.status.canChangeMode,
+ current.status_1_1.status.currentPowerRole,
+ current.status_1_1.status.canChangePowerRole,
+ current.status_1_1.status.currentDataRole,
+ current.status_1_1.status.canChangeDataRole,
+ current.supportsEnableContaminantPresenceProtection,
+ current.contaminantProtectionStatus,
+ current.supportsEnableContaminantPresenceDetection,
+ current.contaminantDetectionStatus);
+ newPortInfo.add(temp);
+ logAndPrint(Log.INFO, pw, "ClientCallback V1_2: "
+ + current.status_1_1.status.portName);
}
Message message = portManager.mHandler.obtainMessage();
@@ -573,16 +663,26 @@
for (int i = 0; i < count; i++) {
final RawPortInfo portInfo = mSimulatedPorts.valueAt(i);
addOrUpdatePortLocked(portInfo.portId, portInfo.supportedModes,
+ portInfo.supportedContaminantProtectionModes,
portInfo.currentMode, portInfo.canChangeMode,
portInfo.currentPowerRole, portInfo.canChangePowerRole,
- portInfo.currentDataRole, portInfo.canChangeDataRole, pw);
+ portInfo.currentDataRole, portInfo.canChangeDataRole,
+ portInfo.supportsEnableContaminantPresenceProtection,
+ portInfo.contaminantProtectionStatus,
+ portInfo.supportsEnableContaminantPresenceDetection,
+ portInfo.contaminantDetectionStatus, pw);
}
} else {
for (RawPortInfo currentPortInfo : newPortInfo) {
addOrUpdatePortLocked(currentPortInfo.portId, currentPortInfo.supportedModes,
+ currentPortInfo.supportedContaminantProtectionModes,
currentPortInfo.currentMode, currentPortInfo.canChangeMode,
currentPortInfo.currentPowerRole, currentPortInfo.canChangePowerRole,
- currentPortInfo.currentDataRole, currentPortInfo.canChangeDataRole, pw);
+ currentPortInfo.currentDataRole, currentPortInfo.canChangeDataRole,
+ currentPortInfo.supportsEnableContaminantPresenceProtection,
+ currentPortInfo.contaminantProtectionStatus,
+ currentPortInfo.supportsEnableContaminantPresenceDetection,
+ currentPortInfo.contaminantDetectionStatus, pw);
}
}
@@ -608,12 +708,16 @@
}
}
-
// Must only be called by updatePortsLocked.
private void addOrUpdatePortLocked(String portId, int supportedModes,
+ int supportedContaminantProtectionModes,
int currentMode, boolean canChangeMode,
int currentPowerRole, boolean canChangePowerRole,
int currentDataRole, boolean canChangeDataRole,
+ boolean supportsEnableContaminantPresenceProtection,
+ int contaminantProtectionStatus,
+ boolean supportsEnableContaminantPresenceDetection,
+ int contaminantDetectionStatus,
IndentingPrintWriter pw) {
// Only allow mode switch capability for dual role ports.
// Validate that the current mode matches the supported modes we expect.
@@ -664,12 +768,15 @@
// Update the port data structures.
PortInfo portInfo = mPorts.get(portId);
if (portInfo == null) {
- portInfo = new PortInfo(mContext.getSystemService(UsbManager.class), portId,
- supportedModes);
+ portInfo = new PortInfo(mContext.getSystemService(UsbManager.class),
+ portId, supportedModes, supportedContaminantProtectionModes,
+ supportsEnableContaminantPresenceProtection,
+ supportsEnableContaminantPresenceDetection);
portInfo.setStatus(currentMode, canChangeMode,
currentPowerRole, canChangePowerRole,
currentDataRole, canChangeDataRole,
- supportedRoleCombinations);
+ supportedRoleCombinations, contaminantProtectionStatus,
+ contaminantDetectionStatus);
mPorts.put(portId, portInfo);
} else {
// Sanity check that ports aren't changing definition out from under us.
@@ -681,10 +788,32 @@
+ ", current=" + UsbPort.modeToString(supportedModes));
}
+ if (supportsEnableContaminantPresenceProtection
+ != portInfo.mUsbPort.supportsEnableContaminantPresenceProtection()) {
+ logAndPrint(Log.WARN, pw,
+ "Ignoring inconsistent supportsEnableContaminantPresenceProtection"
+ + "USB port driver (should be immutable): "
+ + "previous="
+ + portInfo.mUsbPort.supportsEnableContaminantPresenceProtection()
+ + ", current=" + supportsEnableContaminantPresenceProtection);
+ }
+
+ if (supportsEnableContaminantPresenceDetection
+ != portInfo.mUsbPort.supportsEnableContaminantPresenceDetection()) {
+ logAndPrint(Log.WARN, pw,
+ "Ignoring inconsistent supportsEnableContaminantPresenceDetection "
+ + "USB port driver (should be immutable): "
+ + "previous="
+ + portInfo.mUsbPort.supportsEnableContaminantPresenceDetection()
+ + ", current=" + supportsEnableContaminantPresenceDetection);
+ }
+
+
if (portInfo.setStatus(currentMode, canChangeMode,
currentPowerRole, canChangePowerRole,
currentDataRole, canChangeDataRole,
- supportedRoleCombinations)) {
+ supportedRoleCombinations, contaminantProtectionStatus,
+ contaminantDetectionStatus)) {
portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
} else {
portInfo.mDisposition = PortInfo.DISPOSITION_READY;
@@ -784,8 +913,14 @@
// 0 when port is connected. Else reports the last connected duration
public long mLastConnectDurationMillis;
- PortInfo(@NonNull UsbManager usbManager, @NonNull String portId, int supportedModes) {
- mUsbPort = new UsbPort(usbManager, portId, supportedModes);
+ PortInfo(@NonNull UsbManager usbManager, @NonNull String portId, int supportedModes,
+ int supportedContaminantProtectionModes,
+ boolean supportsEnableContaminantPresenceDetection,
+ boolean supportsEnableContaminantPresenceProtection) {
+ mUsbPort = new UsbPort(usbManager, portId, supportedModes,
+ supportedContaminantProtectionModes,
+ supportsEnableContaminantPresenceDetection,
+ supportsEnableContaminantPresenceProtection);
}
public boolean setStatus(int currentMode, boolean canChangeMode,
@@ -804,7 +939,45 @@
|| mUsbPortStatus.getSupportedRoleCombinations()
!= supportedRoleCombinations) {
mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
- supportedRoleCombinations);
+ supportedRoleCombinations, UsbPortStatus.CONTAMINANT_PROTECTION_NONE,
+ UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED);
+ dispositionChanged = true;
+ }
+
+ if (mUsbPortStatus.isConnected() && mConnectedAtMillis == 0) {
+ mConnectedAtMillis = SystemClock.elapsedRealtime();
+ mLastConnectDurationMillis = 0;
+ } else if (!mUsbPortStatus.isConnected() && mConnectedAtMillis != 0) {
+ mLastConnectDurationMillis = SystemClock.elapsedRealtime() - mConnectedAtMillis;
+ mConnectedAtMillis = 0;
+ }
+
+ return dispositionChanged;
+ }
+
+ public boolean setStatus(int currentMode, boolean canChangeMode,
+ int currentPowerRole, boolean canChangePowerRole,
+ int currentDataRole, boolean canChangeDataRole,
+ int supportedRoleCombinations, int contaminantProtectionStatus,
+ int contaminantDetectionStatus) {
+ boolean dispositionChanged = false;
+
+ mCanChangeMode = canChangeMode;
+ mCanChangePowerRole = canChangePowerRole;
+ mCanChangeDataRole = canChangeDataRole;
+ if (mUsbPortStatus == null
+ || mUsbPortStatus.getCurrentMode() != currentMode
+ || mUsbPortStatus.getCurrentPowerRole() != currentPowerRole
+ || mUsbPortStatus.getCurrentDataRole() != currentDataRole
+ || mUsbPortStatus.getSupportedRoleCombinations()
+ != supportedRoleCombinations
+ || mUsbPortStatus.getContaminantProtectionStatus()
+ != contaminantProtectionStatus
+ || mUsbPortStatus.getContaminantDetectionStatus()
+ != contaminantDetectionStatus) {
+ mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
+ supportedRoleCombinations, contaminantProtectionStatus,
+ contaminantDetectionStatus);
dispositionChanged = true;
}
@@ -855,32 +1028,54 @@
private static final class RawPortInfo implements Parcelable {
public final String portId;
public final int supportedModes;
+ public final int supportedContaminantProtectionModes;
public int currentMode;
public boolean canChangeMode;
public int currentPowerRole;
public boolean canChangePowerRole;
public int currentDataRole;
public boolean canChangeDataRole;
+ public boolean supportsEnableContaminantPresenceProtection;
+ public int contaminantProtectionStatus;
+ public boolean supportsEnableContaminantPresenceDetection;
+ public int contaminantDetectionStatus;
RawPortInfo(String portId, int supportedModes) {
this.portId = portId;
this.supportedModes = supportedModes;
+ this.supportedContaminantProtectionModes = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+ this.supportsEnableContaminantPresenceProtection = false;
+ this.contaminantProtectionStatus = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+ this.supportsEnableContaminantPresenceDetection = false;
+ this.contaminantDetectionStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
}
- RawPortInfo(String portId, int supportedModes,
+ RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes,
int currentMode, boolean canChangeMode,
int currentPowerRole, boolean canChangePowerRole,
- int currentDataRole, boolean canChangeDataRole) {
+ int currentDataRole, boolean canChangeDataRole,
+ boolean supportsEnableContaminantPresenceProtection,
+ int contaminantProtectionStatus,
+ boolean supportsEnableContaminantPresenceDetection,
+ int contaminantDetectionStatus) {
this.portId = portId;
this.supportedModes = supportedModes;
+ this.supportedContaminantProtectionModes = supportedContaminantProtectionModes;
this.currentMode = currentMode;
this.canChangeMode = canChangeMode;
this.currentPowerRole = currentPowerRole;
this.canChangePowerRole = canChangePowerRole;
this.currentDataRole = currentDataRole;
this.canChangeDataRole = canChangeDataRole;
+ this.supportsEnableContaminantPresenceProtection =
+ supportsEnableContaminantPresenceProtection;
+ this.contaminantProtectionStatus = contaminantProtectionStatus;
+ this.supportsEnableContaminantPresenceDetection =
+ supportsEnableContaminantPresenceDetection;
+ this.contaminantDetectionStatus = contaminantDetectionStatus;
}
+
@Override
public int describeContents() {
return 0;
@@ -890,35 +1085,50 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(portId);
dest.writeInt(supportedModes);
+ dest.writeInt(supportedContaminantProtectionModes);
dest.writeInt(currentMode);
dest.writeByte((byte) (canChangeMode ? 1 : 0));
dest.writeInt(currentPowerRole);
dest.writeByte((byte) (canChangePowerRole ? 1 : 0));
dest.writeInt(currentDataRole);
dest.writeByte((byte) (canChangeDataRole ? 1 : 0));
+ dest.writeBoolean(supportsEnableContaminantPresenceProtection);
+ dest.writeInt(contaminantProtectionStatus);
+ dest.writeBoolean(supportsEnableContaminantPresenceDetection);
+ dest.writeInt(contaminantDetectionStatus);
}
public static final Parcelable.Creator<RawPortInfo> CREATOR =
new Parcelable.Creator<RawPortInfo>() {
- @Override
- public RawPortInfo createFromParcel(Parcel in) {
- String id = in.readString();
- int supportedModes = in.readInt();
- int currentMode = in.readInt();
- boolean canChangeMode = in.readByte() != 0;
- int currentPowerRole = in.readInt();
- boolean canChangePowerRole = in.readByte() != 0;
- int currentDataRole = in.readInt();
- boolean canChangeDataRole = in.readByte() != 0;
- return new RawPortInfo(id, supportedModes, currentMode, canChangeMode,
- currentPowerRole, canChangePowerRole,
- currentDataRole, canChangeDataRole);
- }
+ @Override
+ public RawPortInfo createFromParcel(Parcel in) {
+ String id = in.readString();
+ int supportedModes = in.readInt();
+ int supportedContaminantProtectionModes = in.readInt();
+ int currentMode = in.readInt();
+ boolean canChangeMode = in.readByte() != 0;
+ int currentPowerRole = in.readInt();
+ boolean canChangePowerRole = in.readByte() != 0;
+ int currentDataRole = in.readInt();
+ boolean canChangeDataRole = in.readByte() != 0;
+ boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
+ int contaminantProtectionStatus = in.readInt();
+ boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
+ int contaminantDetectionStatus = in.readInt();
+ return new RawPortInfo(id, supportedModes,
+ supportedContaminantProtectionModes, currentMode, canChangeMode,
+ currentPowerRole, canChangePowerRole,
+ currentDataRole, canChangeDataRole,
+ supportsEnableContaminantPresenceProtection,
+ contaminantProtectionStatus,
+ supportsEnableContaminantPresenceDetection,
+ contaminantDetectionStatus);
+ }
- @Override
- public RawPortInfo[] newArray(int size) {
- return new RawPortInfo[size];
- }
- };
+ @Override
+ public RawPortInfo[] newArray(int size) {
+ return new RawPortInfo[size];
+ }
+ };
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 9115477..9be542f 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -554,6 +554,21 @@
}
@Override
+ public void enableContaminantDetection(String portId, boolean enable) {
+ Preconditions.checkNotNull(portId, "portId must not be null");
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (mPortManager != null) {
+ mPortManager.enableContaminantDetection(portId, enable, null);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public void setUsbDeviceConnectionHandler(ComponentName usbDeviceConnectionHandler) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
synchronized (mLock) {