UsbGadget: Update SDP enum timeout when gadget is pulled up

Indicate to the kernel that the usb gadget is pulled up
by writing to `update_sdp_enum_timeout` sysfs node. Write
to this node will inform the kernel that it can lower the SDP
timeout alarm value which is used to detect an SDP port
vs a DCP.

ported from c5c5b127a7ed0db559d286284fe77b656bef6945

Bug: 275687235
Test: Check `update_sdp_enum_timeout` is written into after usb
      gadget is pulled up. Verify that the alarm timeout lowers.
Change-Id: Id3ae7e7a20b236cec6604414a7f81860e868bdd0
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
diff --git a/usb/gadget/UsbGadget.cpp b/usb/gadget/UsbGadget.cpp
index 7ee7046..9b68e2c 100644
--- a/usb/gadget/UsbGadget.cpp
+++ b/usb/gadget/UsbGadget.cpp
@@ -41,10 +41,34 @@
 constexpr char kI2CPath[] = "/sys/devices/platform/10d50000.hsi2c/i2c-";
 constexpr char kAccessoryLimitCurrent[] = "i2c-max77759tcpc/usb_limit_accessory_current";
 constexpr char kAccessoryLimitCurrentEnable[] = "i2c-max77759tcpc/usb_limit_accessory_enable";
+constexpr char kUpdateSdpEnumTimeout[] = "i2c-max77759tcpc/update_sdp_enum_timeout";
 
 using ::android::base::GetBoolProperty;
 using ::android::hardware::google::pixel::usb::kUvcEnabled;
 
+Status getI2cBusHelper(string *name) {
+    DIR *dp;
+
+    dp = opendir(kHsi2cPath);
+    if (dp != NULL) {
+        struct dirent *ep;
+
+        while ((ep = readdir(dp))) {
+            if (ep->d_type == DT_DIR) {
+                if (string::npos != string(ep->d_name).find("i2c-")) {
+                    std::strtok(ep->d_name, "-");
+                    *name = std::strtok(NULL, "-");
+                }
+            }
+        }
+        closedir(dp);
+        return Status::SUCCESS;
+    }
+
+    ALOGE("Failed to open %s", kHsi2cPath);
+    return Status::ERROR;
+}
+
 UsbGadget::UsbGadget() : mGadgetIrqPath("") {
     if (access(OS_DESC_PATH, R_OK) != 0) {
         ALOGE("configfs setup not done yet");
@@ -97,6 +121,7 @@
 void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
     UsbGadget *gadget = (UsbGadget *)payload;
     gadget->mCurrentUsbFunctionsApplied = functionsApplied;
+    gadget->updateSdpEnumTimeout();
 }
 
 ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> &callback,
@@ -363,6 +388,22 @@
     return ScopedAStatus::ok();
 }
 
+void UsbGadget::updateSdpEnumTimeout() {
+    string i2c_node, update_sdp_enum_timeout_path;
+
+    Status status = getI2cBusHelper(&i2c_node);
+    if (status != Status::SUCCESS) {
+        ALOGE("%s: Unable to locate i2c bus node", __func__);
+    }
+
+    update_sdp_enum_timeout_path = kI2CPath + i2c_node + "/" + kUpdateSdpEnumTimeout;
+    if (!WriteStringToFile("1", update_sdp_enum_timeout_path)) {
+        ALOGE("%s: Unable to write to %s.", __func__, update_sdp_enum_timeout_path.c_str());
+    } else {
+        ALOGI("%s: Updated SDP enumeration timeout value.", __func__);
+    }
+}
+
 Status UsbGadget::setupFunctions(long functions,
         const shared_ptr<IUsbGadgetCallback> &callback, uint64_t timeout,
         int64_t in_transactionId) {
@@ -417,6 +458,7 @@
         mCurrentUsbFunctionsApplied = true;
         if (callback)
             callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+        updateSdpEnumTimeout();
         return Status::SUCCESS;
     }
 
@@ -441,28 +483,6 @@
     return Status::SUCCESS;
 }
 
-Status getI2cBusHelper(string *name) {
-    DIR *dp;
-
-    dp = opendir(kHsi2cPath);
-    if (dp != NULL) {
-        struct dirent *ep;
-
-        while ((ep = readdir(dp))) {
-            if (ep->d_type == DT_DIR) {
-                if (string::npos != string(ep->d_name).find("i2c-")) {
-                    std::strtok(ep->d_name, "-");
-                    *name = std::strtok(NULL, "-");
-                }
-            }
-        }
-        closedir(dp);
-        return Status::SUCCESS;
-    }
-
-    ALOGE("Failed to open %s", kHsi2cPath);
-    return Status::ERROR;
-}
 
 ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions,
                                                const shared_ptr<IUsbGadgetCallback> &callback,
diff --git a/usb/gadget/UsbGadget.h b/usb/gadget/UsbGadget.h
index 5975930..a6b63bd 100644
--- a/usb/gadget/UsbGadget.h
+++ b/usb/gadget/UsbGadget.h
@@ -115,6 +115,10 @@
 
     ScopedAStatus setVidPid(const char *vid,const char *pid);
 
+    // Indicates to the kernel that the gadget service is ready and the kernel can
+    // set SDP timeout to a lower value.
+    void updateSdpEnumTimeout();
+
   private:
     Status tearDownGadget();
     Status getUsbGadgetIrqPath();