diff options
| author | Badhri Jagan Sridharan <badhri@google.com> | 2018-07-18 18:03:44 -0700 |
|---|---|---|
| committer | Thierry Strudel <tstrudel@google.com> | 2018-07-20 16:44:32 +0000 |
| commit | 6aa47331376378baec051ccb846d28e85dee5f69 (patch) | |
| tree | 47e314a581493565557d9746b587b9260a395365 /usb | |
| parent | 9d2d028b64c90e52c5044c1b66608a112c1eb5ae (diff) | |
UsbGadget: Fix switching functions
Sleep only when time elapsed since the last disconnect
is less than the PULL_UP_DELAY. This ensures that the hal
does not miss the 2 second timeout while switching between
functions.
Also, enclose write within TEMP_FAILURE_RETRY to prevent
being returned from EINTR.
Bug: 111424620
Test: a. Switch between multiple functions.
b. while true; do fastboot reboot; adb wait-for-device;
adb shell getprop ro.bootmode; adb root; sleep 2;
adb wait-for-device; adb reboot bootloader; done;
Change-Id: Ic8c418c145e4fe070b407c22eef803e10ae41077
Diffstat (limited to 'usb')
| -rw-r--r-- | usb/UsbGadget.cpp | 37 | ||||
| -rw-r--r-- | usb/UsbGadget.h | 2 |
2 files changed, 32 insertions, 7 deletions
diff --git a/usb/UsbGadget.cpp b/usb/UsbGadget.cpp index f319f39..74afc99 100644 --- a/usb/UsbGadget.cpp +++ b/usb/UsbGadget.cpp @@ -95,6 +95,7 @@ static void *monitorFfs(void *param) { char buf[BUFFER_SIZE]; bool writeUdc = true, stopMonitor = false; struct epoll_event events[EPOLL_EVENTS]; + steady_clock::time_point disconnect; bool descriptorWritten = true; for (int i = 0; i < static_cast<int>(usbGadget->mEndpointList.size()); i++) { @@ -105,11 +106,16 @@ static void *monitorFfs(void *param) { } // notify here if the endpoints are already present. - if (descriptorWritten && !!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) { - lock_guard<mutex> lock(usbGadget->mLock); - usbGadget->mCurrentUsbFunctionsApplied = true; - gadgetPullup = true; - usbGadget->mCv.notify_all(); + if (descriptorWritten) { + usleep(PULL_UP_DELAY); + if (!!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) { + lock_guard<mutex> lock(usbGadget->mLock); + usbGadget->mCurrentUsbFunctionsApplied = true; + gadgetPullup = true; + writeUdc = false; + ALOGI("GADGET pulled up"); + usbGadget->mCv.notify_all(); + } } while (!stopMonitor) { @@ -146,8 +152,14 @@ static void *monitorFfs(void *param) { if (!descriptorPresent && !writeUdc) { if (DEBUG) ALOGI("endpoints not up"); writeUdc = true; + disconnect = std::chrono::steady_clock::now(); } else if (descriptorPresent && writeUdc) { - usleep(PULL_UP_DELAY); + steady_clock::time_point temp = steady_clock::now(); + + if (std::chrono::duration_cast<microseconds>(temp - disconnect).count() + < PULL_UP_DELAY) + usleep(PULL_UP_DELAY); + if(!!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) { lock_guard<mutex> lock(usbGadget->mLock); usbGadget->mCurrentUsbFunctionsApplied = true; @@ -246,8 +258,17 @@ V1_0::Status UsbGadget::tearDownGadget() { if (mMonitorCreated) { uint64_t flag = 100; + unsigned long ret; + // Stop the monitor thread by writing into signal fd. - write(mEventFd, &flag, sizeof(flag)); + ret = TEMP_FAILURE_RETRY(write(mEventFd, &flag, sizeof(flag))); + if (ret < 0) { + ALOGE("Error writing errno=%d", errno); + } else if (ret < sizeof(flag)) { + ALOGE("Short write length=%zd", ret); + } + + ALOGI("mMonitor signalled to exit"); mMonitor->join(); mMonitorCreated = false; ALOGI("mMonitor destroyed"); @@ -583,6 +604,8 @@ Return<void> UsbGadget::setCurrentUsbFunctions( goto error; } + ALOGI("Returned from tearDown gadget"); + // Leave the gadget pulled down to give time for the host to sense disconnect. usleep(DISCONNECT_WAIT_US); diff --git a/usb/UsbGadget.h b/usb/UsbGadget.h index 9a2c4dd..a0aa42b 100644 --- a/usb/UsbGadget.h +++ b/usb/UsbGadget.h @@ -50,6 +50,7 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +using ::std::chrono::steady_clock; using ::std::lock_guard; using ::std::move; using ::std::mutex; @@ -57,6 +58,7 @@ using ::std::string; using ::std::thread; using ::std::unique_ptr; using ::std::vector; +using namespace std::chrono; using namespace std::chrono_literals; struct UsbGadget : public IUsbGadget { |
