Support to set thread name in ThreadUtil

Netd resolver uses ThreadUtil to create lookup threads.
This change facilitates DNS debugging by means of appending
uid to the thread name.

MDnsSdListener monitor thread is renamed to MDnsSdMonitor.

Bug: 128404051
Test: cd systen/netd && atest
Change-Id: I7ea2edef3f1eb0fffe8ea00fb7b281dac7b7ef2e
diff --git a/libnetdutils/ThreadUtilTest.cpp b/libnetdutils/ThreadUtilTest.cpp
index 2fe63b7..8fad8b8 100644
--- a/libnetdutils/ThreadUtilTest.cpp
+++ b/libnetdutils/ThreadUtilTest.cpp
@@ -14,22 +14,49 @@
  * limitations under the License.
  */
 
+#include <string>
+
+#include <android-base/expected.h>
 #include <gtest/gtest.h>
+#include <netdutils/ThreadUtil.h>
 
-#include "netdutils/ThreadUtil.h"
-
-namespace android {
-namespace netdutils {
+namespace android::netdutils {
 
 namespace {
 
+android::base::expected<std::string, int> getThreadName() {
+    char name[16] = {};
+    if (const int ret = pthread_getname_np(pthread_self(), name, sizeof(name)); ret != 0) {
+        return android::base::unexpected(ret);
+    }
+    return std::string(name);
+}
+
 class NoopRun {
   public:
-    NoopRun() { instanceNum++; }
-    ~NoopRun() { instanceNum--; }
+    explicit NoopRun(const std::string& name = "") : mName(name) { instanceNum++; }
+
+    // Destructor happens in the thread.
+    ~NoopRun() {
+        if (checkName) {
+            auto expected = getThreadName();
+            EXPECT_TRUE(expected.has_value());
+            EXPECT_EQ(mExpectedName, expected.value());
+        }
+        instanceNum--;
+    }
 
     void run() {}
 
+    std::string threadName() { return mName; }
+
+    // Set the expected thread name which will be used to check if it matches the actual thread
+    // name which is returned from the system call. The check will happen in the destructor.
+    void setExpectedName(const std::string& expectedName) {
+        checkName = true;
+        mExpectedName = expectedName;
+    }
+
     static bool waitForAllReleased(int timeoutMs) {
         constexpr int intervalMs = 20;
         int limit = timeoutMs / intervalMs;
@@ -44,6 +71,11 @@
 
     // To track how many instances are alive.
     static std::atomic<int> instanceNum;
+
+  private:
+    std::string mName;
+    std::string mExpectedName;
+    bool checkName = false;
 };
 
 std::atomic<int> NoopRun::instanceNum;
@@ -61,5 +93,30 @@
     EXPECT_EQ(0, NoopRun::instanceNum);
 }
 
-}  // namespace netdutils
-}  // namespace android
+TEST(ThreadUtilTest, SetThreadName) {
+    NoopRun::instanceNum = 0;
+
+    // Test thread name empty.
+    NoopRun* obj1 = new NoopRun();
+    obj1->setExpectedName("");
+
+    // Test normal case.
+    NoopRun* obj2 = new NoopRun("TestName");
+    obj2->setExpectedName("TestName");
+
+    // Test thread name too long.
+    std::string name("TestNameTooooLong");
+    NoopRun* obj3 = new NoopRun(name);
+    obj3->setExpectedName(name.substr(0, 15));
+
+    // Thread names are examined in their destructors.
+    EXPECT_EQ(3, NoopRun::instanceNum);
+    threadLaunch(obj1);
+    threadLaunch(obj2);
+    threadLaunch(obj3);
+
+    EXPECT_TRUE(NoopRun::waitForAllReleased(1000));
+    EXPECT_EQ(0, NoopRun::instanceNum);
+}
+
+}  // namespace android::netdutils