Support USB V1.3 HAL

USB V1.3 HAL include:
1. Add api to enable/disable USB data signaling
2. Add api to inquiry HAL version

Bug: 161414036
Test: build pass and functions are working normally
Signed-off-by: Albert Wang <albertccwang@google.com>
Change-Id: Idb946de553b63f1d9da565133306117a6a4a7dd8
Merged-In: Idb946de553b63f1d9da565133306117a6a4a7dd8
(cherry picked from commit bd9dfea4804f02fb54caeb549ec6f9a07b2b9aba)
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 227b9e2..115c1f2 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -55,7 +55,11 @@
                 + "       svc usb getGadgetHalVersion\n"
                 + "         Gets current Gadget Hal Version\n"
                 + "         possible values of Hal version are any of 'unknown', 'V1_0', 'V1_1',\n"
-                + "         'V1_2'\n";
+                + "         'V1_2'\n"
+                + "       svc usb getUsbHalVersion\n"
+                + "         Gets current USB Hal Version\n"
+                + "         possible values of Hal version are any of 'unknown', 'V1_0', 'V1_1',\n"
+                + "         'V1_2', 'V1_3'\n";
     }
 
     @Override
@@ -111,6 +115,25 @@
                     System.err.println("Error communicating with UsbManager: " + e);
                 }
                 return;
+            } else if ("getUsbHalVersion".equals(args[1])) {
+                try {
+                    int version = usbMgr.getUsbHalVersion();
+
+                    if (version == 13) {
+                        System.err.println("V1_3");
+                    } else if (version == 12) {
+                        System.err.println("V1_2");
+                    } else if (version == 11) {
+                        System.err.println("V1_1");
+                    } else if (version == 10) {
+                        System.err.println("V1_0");
+                    } else {
+                        System.err.println("unknown");
+                    }
+                } catch (RemoteException e) {
+                    System.err.println("Error communicating with UsbManager: " + e);
+                }
+                return;
             }
         }
         System.err.println(longHelp());
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 51d5139..b57fdf1 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -73,6 +73,7 @@
   public class UsbManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int getGadgetHalVersion();
     method public int getUsbBandwidth();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int getUsbHalVersion();
     field public static final int GADGET_HAL_NOT_SUPPORTED = -1; // 0xffffffff
     field public static final int GADGET_HAL_V1_0 = 10; // 0xa
     field public static final int GADGET_HAL_V1_1 = 11; // 0xb
@@ -85,6 +86,11 @@
     field public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480; // 0x1e0
     field public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2; // 0x2
     field public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1; // 0xffffffff
+    field public static final int USB_HAL_NOT_SUPPORTED = -1; // 0xffffffff
+    field public static final int USB_HAL_V1_0 = 10; // 0xa
+    field public static final int USB_HAL_V1_1 = 11; // 0xb
+    field public static final int USB_HAL_V1_2 = 12; // 0xc
+    field public static final int USB_HAL_V1_3 = 13; // 0xd
   }
 
 }
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index ca79901..7f07af7 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -135,6 +135,12 @@
     /* Resets the USB gadget. */
     void resetUsbGadget();
 
+    /* Set USB data on or off */
+    boolean enableUsbDataSignal(boolean enable);
+
+    /* Gets the USB Hal Version. */
+    int getUsbHalVersion();
+
     /* Get the functionfs control handle for the given function. Usb
      * descriptors will already be written, and the handle will be
      * ready to use.
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 5bac481..841fd2f 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -516,6 +516,46 @@
     public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024;
 
     /**
+     * The Value for USB hal is not presented.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_NOT_SUPPORTED = -1;
+
+    /**
+     * Value for USB Hal Version v1.0.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_V1_0 = 10;
+
+    /**
+     * Value for USB Hal Version v1.1.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_V1_1 = 11;
+
+    /**
+     * Value for USB Hal Version v1.2.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_V1_2 = 12;
+
+    /**
+     * Value for USB Hal Version v1.3.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_V1_3 = 13;
+
+    /**
      * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
      * {@hide}
      */
@@ -617,6 +657,16 @@
     })
     public @interface UsbGadgetHalVersion {}
 
+    /** @hide */
+    @IntDef(prefix = { "USB_HAL_" }, value = {
+            USB_HAL_NOT_SUPPORTED,
+            USB_HAL_V1_0,
+            USB_HAL_V1_1,
+            USB_HAL_V1_2,
+            USB_HAL_V1_3,
+    })
+    public @interface UsbHalVersion {}
+
     private final Context mContext;
     private final IUsbManager mService;
 
@@ -1076,6 +1126,26 @@
     }
 
     /**
+     * Get the Current USB Hal Version.
+     * <p>
+     * This function returns the current USB Hal Version.
+     * </p>
+     *
+     * @return a integer {@code USB_HAL_*} represent hal version.
+     *
+     * {@hide}
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    public @UsbHalVersion int getUsbHalVersion() {
+        try {
+            return mService.getUsbHalVersion();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Resets the USB Gadget.
      * <p>
      * Performs USB data stack reset through USB Gadget HAL.
@@ -1095,6 +1165,28 @@
     }
 
     /**
+     * Enable/Disable the USB data signaling.
+     * <p>
+     * Enables/Disables USB data path in all the USB ports.
+     * It will force to stop or restore USB data signaling.
+     * </p>
+     *
+     * @param enable enable or disable USB data signaling
+     * @return true enable or disable USB data successfully
+     *         false if something wrong
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    public boolean enableUsbDataSignal(boolean enable) {
+        try {
+            return mService.enableUsbDataSignal(enable);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns a list of physical USB ports on the device.
      * <p>
      * This list is guaranteed to contain all dual-role USB Type C ports but it might
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index aa8bbde..89e5d5f 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -19,6 +19,7 @@
         "android.hardware.usb-V1.0-java",
         "android.hardware.usb-V1.1-java",
         "android.hardware.usb-V1.2-java",
+        "android.hardware.usb-V1.3-java",
         "android.hardware.usb.gadget-V1.0-java",
         "android.hardware.usb.gadget-V1.1-java",
         "android.hardware.usb.gadget-V1.2-java",
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ca18c57..6bf6715 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -42,13 +42,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.Status;
 import android.hardware.usb.V1_1.PortStatus_1_1;
 import android.hardware.usb.V1_2.IUsbCallback;
 import android.hardware.usb.V1_2.PortStatus;
+import android.hardware.usb.V1_3.IUsb;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.Bundle;
@@ -156,6 +156,9 @@
      */
     private int mIsPortContaminatedNotificationId;
 
+    private boolean mEnableUsbDataSignaling;
+    protected int mCurrentUsbHalVersion;
+
     public UsbPortManager(Context context) {
         mContext = context;
         try {
@@ -181,6 +184,7 @@
         if (mProxy != null) {
             try {
                 mProxy.queryPortStatus();
+                mEnableUsbDataSignaling = true;
             } catch (RemoteException e) {
                 logAndPrintException(null,
                         "ServiceStart: Failed to query port status", e);
@@ -346,6 +350,66 @@
         }
     }
 
+    /**
+     * Enable/disable the USB data signaling
+     *
+     * @param enable enable or disable USB data signaling
+     */
+    public boolean enableUsbDataSignal(boolean enable) {
+        try {
+            mEnableUsbDataSignaling = enable;
+            // Call into the hal. Use the castFrom method from HIDL.
+            android.hardware.usb.V1_3.IUsb proxy = android.hardware.usb.V1_3.IUsb.castFrom(mProxy);
+            return proxy.enableUsbDataSignal(enable);
+        } catch (RemoteException e) {
+            logAndPrintException(null, "Failed to set USB data signaling", e);
+            return false;
+        } catch (ClassCastException e) {
+            logAndPrintException(null, "Method only applicable to V1.3 or above implementation", e);
+            return false;
+        }
+    }
+
+    /**
+     * Get USB HAL version
+     *
+     * @param none
+     */
+    public int getUsbHalVersion() {
+        return mCurrentUsbHalVersion;
+    }
+
+    /**
+     * update USB HAL version
+     *
+     * @param none
+     */
+    private void updateUsbHalVersion() {
+        android.hardware.usb.V1_3.IUsb usbProxy_V1_3 =
+                android.hardware.usb.V1_3.IUsb.castFrom(mProxy);
+        if (usbProxy_V1_3 != null) {
+            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_3;
+            return;
+        }
+
+        android.hardware.usb.V1_2.IUsb usbProxy_V1_2 =
+                android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
+        if (usbProxy_V1_2 != null) {
+            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_2;
+            return;
+        }
+
+        android.hardware.usb.V1_1.IUsb usbProxy_V1_1 =
+                android.hardware.usb.V1_1.IUsb.castFrom(mProxy);
+        if (usbProxy_V1_1 != null) {
+            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_1;
+            return;
+        }
+
+        mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
+        return;
+    }
+
     public void setPortRoles(String portId, int newPowerRole, int newDataRole,
             IndentingPrintWriter pw) {
         synchronized (mLock) {
@@ -610,6 +674,9 @@
             for (PortInfo portInfo : mPorts.values()) {
                 portInfo.dump(dump, "usb_ports", UsbPortManagerProto.USB_PORTS);
             }
+
+            dump.write("enable_usb_data_signaling", UsbPortManagerProto.ENABLE_USB_DATA_SIGNALING,
+                    mEnableUsbDataSignaling);
         }
 
         dump.end(token);
@@ -783,6 +850,7 @@
                 mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
                 mProxy.setCallback(mHALCallback);
                 mProxy.queryPortStatus();
+                mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
             } catch (NoSuchElementException e) {
                 logAndPrintException(pw, "connectToProxy: usb hal service not found."
                         + " Did the service fail to start?", e);
@@ -1115,6 +1183,7 @@
                 case MSG_SYSTEM_READY: {
                     mNotificationManager = (NotificationManager)
                             mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+                    updateUsbHalVersion();
                     break;
                 }
             }
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index edd4a38..9a13d76 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -745,6 +745,38 @@
     }
 
     @Override
+    public int getUsbHalVersion() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            if (mPortManager != null) {
+                return mPortManager.getUsbHalVersion();
+            } else {
+                return UsbManager.USB_HAL_NOT_SUPPORTED;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public boolean enableUsbDataSignal(boolean enable) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            if (mPortManager != null) {
+                return mPortManager.enableUsbDataSignal(enable);
+            } else {
+                return false;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
     public void setUsbDeviceConnectionHandler(ComponentName usbDeviceConnectionHandler) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
         synchronized (mLock) {