From 0c1f69415fe2f97bd337b24dd721b40f26832452 Mon Sep 17 00:00:00 2001 From: Kuen-Han Tsai Date: Wed, 7 Aug 2024 12:27:27 +0800 Subject: [PATCH] Limit hub tuning when enable_hub is enabled Some external hubs have the same VID and PID as the internal hub, causing unintended hub tuning and compatibility issues. This patch restricts hub tuning to only the internal hub located on bus 1, port 1 when enable_hub is set to 1. Bug: 353650207 Test: Verified an external GL852G speakerphone dock works when docked. Test: adb shell cmd android.hardware.usb.IUsb/default hub-vendor-cmd Flag: EXEMPT bugfix Change-Id: If2cfe6684e4f5fafaab34bf7a4e4b4cd464d6575 Signed-off-by: Kuen-Han Tsai --- usb/usb/Usb.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp index 2c42b116..5b38729b 100644 --- a/usb/usb/Usb.cpp +++ b/usb/usb/Usb.cpp @@ -51,6 +51,7 @@ namespace usb_flags = android::hardware::usb::flags; using aidl::android::frameworks::stats::IStats; using android::base::GetProperty; +using android::base::ParseInt; using android::base::Tokenize; using android::base::Trim; using android::hardware::google::pixel::getStatsService; @@ -91,6 +92,8 @@ constexpr char kThermalZoneForTempReadPrimary[] = "usb_pwr_therm2"; constexpr char kThermalZoneForTempReadSecondary1[] = "usb_pwr_therm"; constexpr char kThermalZoneForTempReadSecondary2[] = "qi_therm"; constexpr char kPogoUsbActive[] = "/sys/devices/platform/google,pogo/pogo_usb_active"; +constexpr char kPogoEnableHub[] = "/sys/devices/platform/google,pogo/enable_hub"; +constexpr char kInternalHubDevnum[] = "/sys/bus/usb/devices/1-1/devnum"; constexpr char KPogoMoveDataToUsb[] = "/sys/devices/platform/google,pogo/move_data_to_usb"; constexpr char kPowerSupplyUsbType[] = "/sys/class/power_supply/usb/usb_type"; constexpr char kUdcUeventRegex[] = @@ -471,11 +474,16 @@ bool switchMode(const string &portName, const PortRole &in_role, struct Usb *usb return roleSwitch; } -static int usbDeviceRemoved(const char *devname, void* client_data) { - return 0; +static int getInternalHubUniqueId() { + string internalHubDevnum; + int devnum = 0, internalHubUniqueId = -1; + if (ReadFileToString(kInternalHubDevnum, &internalHubDevnum) && + ParseInt(Trim(internalHubDevnum).c_str(), &devnum)) + internalHubUniqueId = 1000 + devnum; + return internalHubUniqueId; } -static int usbDeviceAdded(const char *devname, void* client_data) { +static Status tuneInternalHub(const char *devname, void* client_data) { uint16_t vendorId, productId; struct usb_device *device; ::aidl::android::hardware::usb::Usb *usb; @@ -484,7 +492,7 @@ static int usbDeviceAdded(const char *devname, void* client_data) { device = usb_device_open(devname); if (!device) { ALOGE("usb_device_open failed\n"); - return 0; + return Status::ERROR; } usb = (::aidl::android::hardware::usb::Usb *)client_data; @@ -506,6 +514,26 @@ static int usbDeviceAdded(const char *devname, void* client_data) { usb_device_close(device); + return Status::SUCCESS; +} + +static int usbDeviceRemoved(const char *devname, void* client_data) { + return 0; +} + +static int usbDeviceAdded(const char *devname, void* client_data) { + string pogoEnableHub; + int uniqueId = 0; + + // Enable hub tuning when the pogo dock is connected. + if (ReadFileToString(kPogoEnableHub, &pogoEnableHub) && Trim(pogoEnableHub) == "1") { + // If enable_hub is set to 1, the internal hub is the first enumearted device on bus 1 and + // port 1. + uniqueId = usb_device_get_unique_id_from_name(devname); + if (uniqueId == getInternalHubUniqueId()) + tuneInternalHub(devname, client_data); + } + return 0; }