diff options
Diffstat (limited to 'minadbd')
-rw-r--r-- | minadbd/Android.bp | 3 | ||||
-rw-r--r-- | minadbd/AndroidTest.xml | 3 | ||||
-rw-r--r-- | minadbd/minadbd_services.cpp | 41 |
3 files changed, 44 insertions, 3 deletions
diff --git a/minadbd/Android.bp b/minadbd/Android.bp index 4cdcac6d9..fb51a799a 100644 --- a/minadbd/Android.bp +++ b/minadbd/Android.bp @@ -24,7 +24,7 @@ cc_defaults { cpp_std: "experimental", include_dirs: [ - "system/core/adb", + "packages/modules/adb", ], header_libs: [ @@ -135,4 +135,5 @@ cc_test { test_suites: [ "device-tests", ], + require_root: true, } diff --git a/minadbd/AndroidTest.xml b/minadbd/AndroidTest.xml index 7ea235b7c..dbcbac250 100644 --- a/minadbd/AndroidTest.xml +++ b/minadbd/AndroidTest.xml @@ -18,9 +18,10 @@ <option name="cleanup" value="true" /> <option name="push" value="minadbd_test->/data/local/tmp/minadbd_test" /> </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> <option name="test-suite-tag" value="apct" /> <test class="com.android.tradefed.testtype.GTest" > <option name="native-test-device-path" value="/data/local/tmp" /> <option name="module-name" value="minadbd_test" /> </test> -</configuration>
\ No newline at end of file +</configuration> diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp index ff91ba931..0abe8675b 100644 --- a/minadbd/minadbd_services.cpp +++ b/minadbd/minadbd_services.cpp @@ -23,6 +23,7 @@ #include <string.h> #include <unistd.h> +#include <chrono> #include <functional> #include <memory> #include <set> @@ -142,10 +143,48 @@ static MinadbdErrorCode RunAdbFuseSideload(int sfd, const std::string& args, return kMinadbdSuccess; } +static bool WaitForSocketClose(int fd, std::chrono::milliseconds timeout) { + const auto begin = std::chrono::steady_clock::now(); + const auto end = begin + timeout; + while (std::chrono::steady_clock::now() < end) { + // We don't care about reading the socket, we just want to wait until + // socket closes. In this case .events = 0 will tell the kernel to wait + // for close events. + struct pollfd pfd = { .fd = fd, .events = 0 }; + auto timeout_ms = std::chrono::duration_cast<std::chrono::milliseconds>( + end - std::chrono::steady_clock::now()) + .count(); + int rc = TEMP_FAILURE_RETRY(adb_poll(&pfd, 1, timeout_ms)); + if (rc == 1) { + LOG(INFO) << "revents: " << pfd.revents; + if (pfd.revents & (POLLHUP | POLLRDHUP)) { + return true; + } + } else { + PLOG(ERROR) << "poll() failed"; + // poll failed, almost definitely due to timeout + // If not, you're screwed anyway, because it probably means the kernel ran + // out of memory. + return false; + } + } + return false; +} + // Sideload service always exits after serving an install command. static void SideloadHostService(unique_fd sfd, const std::string& args) { + using namespace std::chrono_literals; MinadbdCommandStatus status; - exit(RunAdbFuseSideload(sfd.get(), args, &status)); + auto error = RunAdbFuseSideload(sfd.get(), args, &status); + // No need to wait if the socket is already closed, meaning the other end + // already exited for some reason. + if (error != kMinadbdHostSocketIOError) { + // We sleep for a little bit just to wait for the host to receive last + // "DONEDONE" message. However minadbd process is likely to get terminated + // early due to exit_on_close + WaitForSocketClose(sfd, 3000ms); + } + exit(error); } // Rescue service waits for the next command after an install command. |