Add fields to infer UsbPortStatus and allow enabling usb while docked

Adding two fields to UsbPortStatus to infer the following:
a. usbDataStatus: To infer the current USB data status of the port.
b. powerBrickStatus: To infer whether a power brick is connected
                     to the USB port.

The change also adds a new method, enableUsbDataWhileDocked to
allow enabling Usb port while being docked.

Bug: 211677613
Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
Change-Id: I4fb352679a52326bf4b0fc5aa3d218a0f34cecdb
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
index 73c7b82..4ba9ff8 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -36,6 +36,7 @@
 interface IUsb {
   oneway void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
   oneway void enableUsbData(in String portName, boolean enable, long transactionId);
+  oneway void enableUsbDataWhileDocked(in String portName, long transactionId);
   oneway void queryPortStatus(long transactionId);
   oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
   oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
index 85861e9..57f02c5 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
@@ -37,6 +37,7 @@
   oneway void notifyPortStatusChange(in android.hardware.usb.PortStatus[] currentPortStatus, in android.hardware.usb.Status retval);
   oneway void notifyRoleSwitchStatus(in String portName, in android.hardware.usb.PortRole newRole, in android.hardware.usb.Status retval, long transactionId);
   oneway void notifyEnableUsbDataStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyEnableUsbDataWhileDockedStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
   oneway void notifyContaminantEnabledStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
   oneway void notifyQueryPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
   oneway void notifyLimitPowerTransferStatus(in String portName, boolean limit, in android.hardware.usb.Status retval, long transactionId);
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
index 14bb90f..dfd99fb 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -47,6 +47,7 @@
   android.hardware.usb.ContaminantProtectionStatus contaminantProtectionStatus = android.hardware.usb.ContaminantProtectionStatus.NONE;
   boolean supportsEnableContaminantPresenceDetection;
   android.hardware.usb.ContaminantDetectionStatus contaminantDetectionStatus = android.hardware.usb.ContaminantDetectionStatus.NOT_SUPPORTED;
-  boolean usbDataEnabled;
+  android.hardware.usb.UsbDataStatus[] usbDataStatus;
   boolean powerTransferLimited;
+  android.hardware.usb.PowerBrickStatus powerBrickStatus;
 }
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl
new file mode 100644
index 0000000..01d2fdd
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PowerBrickStatus {
+  UNKNOWN = 0,
+  CONNECTED = 1,
+  NOT_CONNECTED = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
new file mode 100644
index 0000000..e2c0cfb
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum UsbDataStatus {
+  UNKNOWN = 0,
+  ENABLED = 1,
+  DISABLED_OVERHEAT = 2,
+  DISABLED_CONTAMINANT = 3,
+  DISABLED_DOCK = 4,
+  DISABLED_FORCE = 5,
+  DISABLED_DEBUG = 6,
+}
diff --git a/usb/aidl/android/hardware/usb/IUsb.aidl b/usb/aidl/android/hardware/usb/IUsb.aidl
index 1596d9a..d296fbb 100644
--- a/usb/aidl/android/hardware/usb/IUsb.aidl
+++ b/usb/aidl/android/hardware/usb/IUsb.aidl
@@ -49,6 +49,15 @@
     void enableUsbData(in String portName, boolean enable, long transactionId);
 
     /**
+     * This function is used to enable USB controller if and when the controller
+     * disabled due to docking event.
+     *
+     * @param portName Name of the port.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void enableUsbDataWhileDocked(in String portName, long transactionId);
+
+    /**
      * This functions is used to request the hal for the current status
      * status of the Type-C ports. The result of the query would be sent
      * through the IUsbCallback object's notifyRoleSwitchStatus
diff --git a/usb/aidl/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
index b733fed..e33672a 100644
--- a/usb/aidl/android/hardware/usb/IUsbCallback.aidl
+++ b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
@@ -63,6 +63,16 @@
             long transactionId);
 
     /**
+     * Used to notify the result of enableUsbDataWhileDocked call to the caller.
+     *
+     * @param portName name of the port for which the enableUsbDataWhileDocked is requested.
+     * @param retval SUCCESS if current request succeeded. FAILURE otherwise.
+     * @param transactionId transactionId sent during enableUsbDataWhileDocked request.
+     */
+    void notifyEnableUsbDataWhileDockedStatus(in String portName, in Status retval,
+            long transactionId);
+
+    /**
      * Used to notify the result of enableContaminantPresenceDetection.
      *
      * @param portName name of the port for which contaminant detection is enabled/disabled.
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
index fb979e5..51bee71 100644
--- a/usb/aidl/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -22,6 +22,8 @@
 import android.hardware.usb.PortDataRole;
 import android.hardware.usb.PortMode;
 import android.hardware.usb.PortPowerRole;
+import android.hardware.usb.PowerBrickStatus;
+import android.hardware.usb.UsbDataStatus;
 
 @VintfStability
 parcelable PortStatus {
@@ -102,10 +104,15 @@
     ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
     /**
      * UsbData status of the port.
+     * Lists reasons for USB data being disabled.
      */
-    boolean usbDataEnabled;
+    UsbDataStatus[] usbDataStatus;
     /**
      * Denoted whether power transfer is limited in the port.
      */
     boolean powerTransferLimited;
+    /**
+     * Denotes whether Power brick is connected.
+     */
+    PowerBrickStatus powerBrickStatus;
 }
diff --git a/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl b/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl
new file mode 100644
index 0000000..620fb25
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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;
+
+@VintfStability
+enum PowerBrickStatus {
+    /**
+     * Status not known.
+     */
+    UNKNOWN = 0,
+    /**
+     * Port partner is power brick.
+     */
+    CONNECTED = 1,
+    /**
+     * Port partner is not power brick.
+     */
+    NOT_CONNECTED = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
new file mode 100644
index 0000000..4b6a41a
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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;
+
+@VintfStability
+enum UsbDataStatus {
+    /**
+     * USB data status not known.
+     */
+    UNKNOWN = 0,
+    /**
+     * USB data is enabled.
+     */
+    ENABLED = 1,
+    /**
+     * USB data is disabled as the port is hot.
+     */
+    DISABLED_OVERHEAT = 2,
+    /**
+     * USB data is disabled as port is contaminated.
+     */
+    DISABLED_CONTAMINANT = 3,
+    /**
+     * USB data is disabled due to dock.
+     */
+    DISABLED_DOCK = 4,
+    /**
+     * USB data is disabled by USB Service.
+     */
+    DISABLED_FORCE = 5,
+    /**
+     * USB data disabled for debug.
+     */
+    DISABLED_DEBUG = 6
+}
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
index 0624963..92b09a2 100644
--- a/usb/aidl/default/Usb.cpp
+++ b/usb/aidl/default/Usb.cpp
@@ -74,6 +74,22 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus Usb::enableUsbDataWhileDocked(const string& in_portName, int64_t in_transactionId) {
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyEnableUsbDataWhileDockedStatus(
+            in_portName, Status::NOT_SUPPORTED, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("notifyEnableUsbDataWhileDockedStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+
+    return ScopedAStatus::ok();
+}
+
 Status queryMoistureDetectionStatus(std::vector<PortStatus> *currentPortStatus) {
     string enabled, status, path, DetectedPath;
 
@@ -473,7 +489,7 @@
                 port.second ? canSwitchRoleHelper(port.first) : false;
 
             (*currentPortStatus)[i].supportedModes.push_back(PortMode::DRP);
-            (*currentPortStatus)[i].usbDataEnabled = true;
+            (*currentPortStatus)[i].usbDataStatus.push_back(UsbDataStatus::ENABLED);
 
             ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
                 "usbDataEnabled:%d",
diff --git a/usb/aidl/default/Usb.h b/usb/aidl/default/Usb.h
index 71ec938..7e8422e 100644
--- a/usb/aidl/default/Usb.h
+++ b/usb/aidl/default/Usb.h
@@ -54,6 +54,8 @@
             int64_t in_transactionId) override;
     ScopedAStatus enableUsbData(const string& in_portName, bool in_enable,
             int64_t in_transactionId) override;
+    ScopedAStatus enableUsbDataWhileDocked(const string& in_portName,
+            int64_t in_transactionId) override;
     ScopedAStatus limitPowerTransfer(const std::string& in_portName, bool in_limit,
             int64_t in_transactionId)override;