Merge "Add a dumpService variant that uses libbinder_ndk."
diff --git a/staticlibs/native/nettestutils/Android.bp b/staticlibs/native/nettestutils/Android.bp
index 42df8e0..df3bb42 100644
--- a/staticlibs/native/nettestutils/Android.bp
+++ b/staticlibs/native/nettestutils/Android.bp
@@ -21,9 +21,15 @@
     export_include_dirs: ["include"],
     srcs: ["DumpService.cpp"],
 
+    // Don't depend on libbinder, because some users of this library may not want to link to it.
+    // CtsNativeNetPlatformTestCases is one such user. See r.android.com/2599405 .
+    header_libs: [
+        "libbinder_headers",
+    ],
+
     shared_libs: [
-        "libbinder",
         "libutils",
+        "libbinder_ndk",
     ],
     cflags: [
         "-Werror",
diff --git a/staticlibs/native/nettestutils/DumpService.cpp b/staticlibs/native/nettestutils/DumpService.cpp
index ba3d77e..40c3b9a 100644
--- a/staticlibs/native/nettestutils/DumpService.cpp
+++ b/staticlibs/native/nettestutils/DumpService.cpp
@@ -17,10 +17,12 @@
 #include "nettestutils/DumpService.h"
 
 #include <android-base/file.h>
+#include <android/binder_status.h>
 
 #include <sstream>
 #include <thread>
 
+// Version for code using libbinder (e.g., AIDL interfaces with the C++ backend).
 android::status_t dumpService(const android::sp<android::IBinder>& binder,
                               const std::vector<std::string>& args,
                               std::vector<std::string>& outputLines) {
@@ -55,3 +57,36 @@
 
   return android::OK;
 }
+
+// Version for code using libbinder_ndk (e.g., AIDL interfaces with the NDK backend)..
+android::status_t dumpService(const ndk::SpAIBinder& binder,
+                              const char** args,
+                              uint32_t num_args,
+                              std::vector<std::string>& outputLines) {
+  if (!outputLines.empty()) return -EUCLEAN;
+
+  android::base::unique_fd localFd, remoteFd;
+  if (!Pipe(&localFd, &remoteFd)) return -errno;
+
+  android::status_t ret;
+  // dump() blocks until another thread has consumed all its output.
+  std::thread dumpThread =
+      std::thread([&ret, binder, remoteFd{std::move(remoteFd)}, args, num_args]() {
+        ret = AIBinder_dump(binder.get(), remoteFd, args, num_args);
+  });
+
+  std::string dumpContent;
+  if (!android::base::ReadFdToString(localFd.get(), &dumpContent)) {
+    return -errno;
+  }
+  dumpThread.join();
+  if (ret != android::OK) return ret;
+
+  std::stringstream dumpStream(dumpContent);
+  std::string line;
+  while (std::getline(dumpStream, line)) {
+    outputLines.push_back(std::move(line));
+  }
+
+  return android::OK;
+}
diff --git a/staticlibs/native/nettestutils/include/nettestutils/DumpService.h b/staticlibs/native/nettestutils/include/nettestutils/DumpService.h
index 2a72181..323d752 100644
--- a/staticlibs/native/nettestutils/include/nettestutils/DumpService.h
+++ b/staticlibs/native/nettestutils/include/nettestutils/DumpService.h
@@ -15,9 +15,15 @@
  */
 
 #include <binder/Binder.h>
+#include <android/binder_auto_utils.h>
 
 #include <vector>
 
 android::status_t dumpService(const android::sp<android::IBinder>& binder,
                               const std::vector<std::string>& args,
                               std::vector<std::string>& outputLines);
+
+android::status_t dumpService(const ndk::SpAIBinder& binder,
+                              const char** args,
+                              uint32_t num_args,
+                              std::vector<std::string>& outputLines);