Merge "Change g.*Converter to fromXml."
diff --git a/.clang-format b/.clang-format
index 03af56d..6725a1f 100644
--- a/.clang-format
+++ b/.clang-format
@@ -11,3 +11,4 @@
 IndentWidth: 4
 PenaltyBreakBeforeFirstCallParameter: 100000
 SpacesBeforeTrailingComments: 1
+IncludeBlocks: Preserve
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index f48f1fb..aff32c3 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -99,6 +99,7 @@
         "libhidlbase",
         "liblog",
         "libutils",
+        "libbinderdebug",
     ],
     srcs: [
         "DumpstateService.cpp",
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c2ae341..b8df99f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2177,13 +2177,13 @@
     }
 
     /*
-     * mount debugfs for non-user builds with ro.product.enforce_debugfs_restrictions
+     * mount debugfs for non-user builds with ro.product.debugfs_restrictions.enabled
      * set to true and unmount it after invoking dumpstateBoard_* methods.
      * This is to enable debug builds to not have debugfs mounted during runtime.
      * It will also ensure that debugfs is only accessed by the dumpstate HAL.
      */
     auto mount_debugfs =
-        android::base::GetBoolProperty("ro.product.enforce_debugfs_restrictions", false);
+        android::base::GetBoolProperty("ro.product.debugfs_restrictions.enabled", false);
     if (mount_debugfs) {
         RunCommand("mount debugfs", {"mount", "-t", "debugfs", "debugfs", "/sys/kernel/debug"},
                    AS_ROOT_20);
diff --git a/cmds/dumpsys/Android.bp b/cmds/dumpsys/Android.bp
index 91aa018..6ab6b7f 100644
--- a/cmds/dumpsys/Android.bp
+++ b/cmds/dumpsys/Android.bp
@@ -32,6 +32,7 @@
         "libutils",
         "liblog",
         "libbinder",
+        "libbinderdebug",
     ],
 
     static_libs: [
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index a017246..ba1c449 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -25,6 +25,7 @@
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
 #include <binder/TextOutput.h>
+#include <binderdebug/BinderDebug.h>
 #include <serviceutils/PriorityDumper.h>
 #include <utils/Log.h>
 #include <utils/Vector.h>
@@ -60,13 +61,15 @@
             "usage: dumpsys\n"
             "         To dump all services.\n"
             "or:\n"
-            "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--help | -l | --skip SERVICES "
+            "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--thread] [--help | -l | "
+            "--skip SERVICES "
             "| SERVICE [ARGS]]\n"
             "         --help: shows this help\n"
             "         -l: only list services, do not dump them\n"
             "         -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n"
             "         -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n"
             "         --pid: dump PID instead of usual dump\n"
+            "         --thread: dump thread usage instead of usual dump\n"
             "         --proto: filter services that support dumping data in proto format. Dumps\n"
             "               will be in proto format.\n"
             "         --priority LEVEL: filter services based on specified priority\n"
@@ -125,7 +128,8 @@
     Type type = Type::DUMP;
     int timeoutArgMs = 10000;
     int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
-    static struct option longOptions[] = {{"pid", no_argument, 0, 0},
+    static struct option longOptions[] = {{"thread", no_argument, 0, 0},
+                                          {"pid", no_argument, 0, 0},
                                           {"priority", required_argument, 0, 0},
                                           {"proto", no_argument, 0, 0},
                                           {"skip", no_argument, 0, 0},
@@ -163,6 +167,8 @@
                 }
             } else if (!strcmp(longOptions[optionIndex].name, "pid")) {
                 type = Type::PID;
+            } else if (!strcmp(longOptions[optionIndex].name, "thread")) {
+                type = Type::THREAD;
             }
             break;
 
@@ -329,6 +335,23 @@
      return OK;
 }
 
+static status_t dumpThreadsToFd(const sp<IBinder>& service, const unique_fd& fd) {
+    pid_t pid;
+    status_t status = service->getDebugPid(&pid);
+    if (status != OK) {
+        return status;
+    }
+    BinderPidInfo pidInfo;
+    status = getBinderPidInfo(BinderDebugContext::BINDER, pid, &pidInfo);
+    if (status != OK) {
+        return status;
+    }
+    WriteStringToFd("Threads in use: " + std::to_string(pidInfo.threadUsage) + "/" +
+                        std::to_string(pidInfo.threadCount) + "\n",
+                    fd.get());
+    return OK;
+}
+
 status_t Dumpsys::startDumpThread(Type type, const String16& serviceName,
                                   const Vector<String16>& args) {
     sp<IBinder> service = sm_->checkService(serviceName);
@@ -359,6 +382,9 @@
         case Type::PID:
             err = dumpPidToFd(service, remote_end);
             break;
+        case Type::THREAD:
+            err = dumpThreadsToFd(service, remote_end);
+            break;
         default:
             std::cerr << "Unknown dump type" << static_cast<int>(type) << std::endl;
             return;
diff --git a/cmds/dumpsys/dumpsys.h b/cmds/dumpsys/dumpsys.h
index 929c55c..349947c 100644
--- a/cmds/dumpsys/dumpsys.h
+++ b/cmds/dumpsys/dumpsys.h
@@ -52,13 +52,14 @@
     static void setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags);
 
     enum class Type {
-        DUMP,  // dump using `dump` function
-        PID,   // dump pid of server only
+        DUMP,    // dump using `dump` function
+        PID,     // dump pid of server only
+        THREAD,  // dump thread usage of server only
     };
 
     /**
      * Starts a thread to connect to a service and get its dump output. The thread redirects
-     * the output to a pipe. Thread must be stopped by a subsequent callto {@code
+     * the output to a pipe. Thread must be stopped by a subsequent call to {@code
      * stopDumpThread}.
      * @param serviceName
      * @param args list of arguments to pass to service dump method.
diff --git a/cmds/dumpsys/tests/Android.bp b/cmds/dumpsys/tests/Android.bp
index 6854c75..58fec30 100644
--- a/cmds/dumpsys/tests/Android.bp
+++ b/cmds/dumpsys/tests/Android.bp
@@ -19,6 +19,7 @@
         "libbase",
         "libbinder",
         "libutils",
+        "libbinderdebug",
     ],
 
     static_libs: [
@@ -26,6 +27,4 @@
         "libgmock",
         "libserviceutils",
     ],
-
-    clang: true,
 }
diff --git a/cmds/dumpsys/tests/AndroidTest.xml b/cmds/dumpsys/tests/AndroidTest.xml
index 1a8c67f..c2351d9 100644
--- a/cmds/dumpsys/tests/AndroidTest.xml
+++ b/cmds/dumpsys/tests/AndroidTest.xml
@@ -23,4 +23,4 @@
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="dumpsys_test" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 67a77f6..39af7df 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -16,12 +16,15 @@
 
 #include "../dumpsys.h"
 
+#include <regex>
 #include <vector>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 #include <android-base/file.h>
+#include <binder/Binder.h>
+#include <binder/ProcessState.h>
 #include <serviceutils/PriorityDumper.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
@@ -222,6 +225,10 @@
         EXPECT_THAT(stdout_, HasSubstr(expected));
     }
 
+    void AssertOutputFormat(const std::string format) {
+        EXPECT_THAT(stdout_, testing::MatchesRegex(format));
+    }
+
     void AssertDumped(const std::string& service, const std::string& dump) {
         EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump));
         EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: "));
@@ -574,6 +581,30 @@
     AssertOutput(std::to_string(getpid()) + "\n");
 }
 
+// Tests 'dumpsys --thread'
+TEST_F(DumpsysTest, ListAllServicesWithThread) {
+    ExpectListServices({"Locksmith", "Valet"});
+    ExpectCheckService("Locksmith");
+    ExpectCheckService("Valet");
+
+    CallMain({"--thread"});
+
+    AssertRunningServices({"Locksmith", "Valet"});
+
+    const std::string format("(.|\n)*((Threads in use: [0-9]+/[0-9]+)?\n-(.|\n)*){2}");
+    AssertOutputFormat(format);
+}
+
+// Tests 'dumpsys --thread service_name'
+TEST_F(DumpsysTest, ListServiceWithThread) {
+    ExpectCheckService("Locksmith");
+
+    CallMain({"--thread", "Locksmith"});
+    // returns an empty string without root enabled
+    const std::string format("(^$|Threads in use: [0-9]/[0-9]+\n)");
+    AssertOutputFormat(format);
+}
+
 TEST_F(DumpsysTest, GetBytesWritten) {
     const char* serviceName = "service2";
     const char* dumpContents = "dump1";
@@ -599,3 +630,13 @@
                         /* as_proto = */ false, elapsedDuration, bytesWritten);
     EXPECT_THAT(status, Eq(INVALID_OPERATION));
 }
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+
+    // start a binder thread pool for testing --thread option
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(8);
+    ProcessState::self()->startThreadPool();
+
+    return RUN_ALL_TESTS();
+}
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 79fa6ba..cba8207 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -60,10 +60,6 @@
 // Currently, these are only on system android (not vendor, not host)
 // TODO(b/183654927) - move these into separate libraries
 libbinder_device_interface_sources = [
-    "AppOpsManager.cpp",
-    "IAppOpsCallback.cpp",
-    "IAppOpsService.cpp",
-
     "IPermissionController.cpp",
     "PermissionCache.cpp",
     "PermissionController.cpp",
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index 4aff92b..22e0466 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -18,6 +18,16 @@
 
 #include <binder/RpcConnection.h>
 
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <string_view>
+
 #include <binder/Parcel.h>
 #include <binder/Stability.h>
 #include <utils/String8.h>
@@ -25,11 +35,6 @@
 #include "RpcState.h"
 #include "RpcWireFormat.h"
 
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
 #ifdef __GLIBC__
 extern "C" pid_t gettid();
 #endif
@@ -41,6 +46,7 @@
 namespace android {
 
 using base::unique_fd;
+using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;
 
 RpcConnection::SocketAddress::~SocketAddress() {}
 
@@ -120,6 +126,70 @@
 
 #endif // __BIONIC__
 
+class SocketAddressImpl : public RpcConnection::SocketAddress {
+public:
+    SocketAddressImpl(const sockaddr* addr, size_t size, const String8& desc)
+          : mAddr(addr), mSize(size), mDesc(desc) {}
+    [[nodiscard]] std::string toString() const override {
+        return std::string(mDesc.c_str(), mDesc.size());
+    }
+    [[nodiscard]] const sockaddr* addr() const override { return mAddr; }
+    [[nodiscard]] size_t addrSize() const override { return mSize; }
+    void set(const sockaddr* addr, size_t size) {
+        mAddr = addr;
+        mSize = size;
+    }
+
+private:
+    const sockaddr* mAddr = nullptr;
+    size_t mSize = 0;
+    String8 mDesc;
+};
+
+AddrInfo GetAddrInfo(const char* addr, unsigned int port) {
+    addrinfo hint{
+            .ai_flags = 0,
+            .ai_family = AF_UNSPEC,
+            .ai_socktype = SOCK_STREAM,
+            .ai_protocol = 0,
+    };
+    addrinfo* aiStart = nullptr;
+    if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) {
+        ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc));
+        return AddrInfo(nullptr, nullptr);
+    }
+    if (aiStart == nullptr) {
+        ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port);
+        return AddrInfo(nullptr, nullptr);
+    }
+    return AddrInfo(aiStart, &freeaddrinfo);
+}
+
+bool RpcConnection::setupInetServer(unsigned int port) {
+    auto aiStart = GetAddrInfo("127.0.0.1", port);
+    if (aiStart == nullptr) return false;
+    SocketAddressImpl socketAddress(nullptr, 0, String8::format("127.0.0.1:%u", port));
+    for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
+        socketAddress.set(ai->ai_addr, ai->ai_addrlen);
+        if (setupSocketServer(socketAddress)) return true;
+    }
+    ALOGE("None of the socket address resolved for 127.0.0.1:%u can be set up as inet server.",
+          port);
+    return false;
+}
+
+bool RpcConnection::addInetClient(const char* addr, unsigned int port) {
+    auto aiStart = GetAddrInfo(addr, port);
+    if (aiStart == nullptr) return false;
+    SocketAddressImpl socketAddress(nullptr, 0, String8::format("%s:%u", addr, port));
+    for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
+        socketAddress.set(ai->ai_addr, ai->ai_addrlen);
+        if (addSocketClient(socketAddress)) return true;
+    }
+    ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
+    return false;
+}
+
 bool RpcConnection::addNullDebuggingClient() {
     unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
 
diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h
index dba47b4..1763d10 100644
--- a/libs/binder/include/binder/RpcConnection.h
+++ b/libs/binder/include/binder/RpcConnection.h
@@ -74,6 +74,16 @@
 #endif // __BIONIC__
 
     /**
+     * Creates an RPC server at the current port.
+     */
+    [[nodiscard]] bool setupInetServer(unsigned int port);
+
+    /**
+     * Connects to an RPC server at the given address and port.
+     */
+    [[nodiscard]] bool addInetClient(const char* addr, unsigned int port);
+
+    /**
      * For debugging!
      *
      * Sets up an empty socket. All queries to this socket which require a
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index e12a429..57c9013 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -65,15 +65,15 @@
         // rustified
         "--constified-enum", "android::c_interface::consts::.*",
 
-        "--whitelist-type", "android::c_interface::.*",
-        "--whitelist-type", "AStatus",
-        "--whitelist-type", "AIBinder_Class",
-        "--whitelist-type", "AIBinder",
-        "--whitelist-type", "AIBinder_Weak",
-        "--whitelist-type", "AIBinder_DeathRecipient",
-        "--whitelist-type", "AParcel",
-        "--whitelist-type", "binder_status_t",
-        "--whitelist-function", ".*",
+        "--allowlist-type", "android::c_interface::.*",
+        "--allowlist-type", "AStatus",
+        "--allowlist-type", "AIBinder_Class",
+        "--allowlist-type", "AIBinder",
+        "--allowlist-type", "AIBinder_Weak",
+        "--allowlist-type", "AIBinder_DeathRecipient",
+        "--allowlist-type", "AParcel",
+        "--allowlist-type", "binder_status_t",
+        "--allowlist-function", ".*",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 0bf76c6..607860f 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -114,8 +114,8 @@
     source_stem: "bindings",
     cpp_std: "gnu++17",
     bindgen_flags: [
-        "--whitelist-type", "Transaction",
-        "--whitelist-var", "TESTDATA_.*",
+        "--allowlist-type", "Transaction",
+        "--allowlist-var", "TESTDATA_.*",
     ],
 
     shared_libs: [
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 3340293..ec4ced2 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -257,6 +257,7 @@
 #ifdef __BIONIC__
     VSOCK,
 #endif // __BIONIC__
+    INET,
 };
 static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
     switch (info.param) {
@@ -266,6 +267,8 @@
         case SocketType::VSOCK:
             return "vm_socket";
 #endif // __BIONIC__
+        case SocketType::INET:
+            return "inet_socket";
         default:
             LOG_ALWAYS_FATAL("Unknown socket type");
             return "";
@@ -305,6 +308,9 @@
                             CHECK(connection->setupVsockServer(port));
                             break;
 #endif // __BIONIC__
+                        case SocketType::INET:
+                            CHECK(connection->setupInetServer(port));
+                            break;
                         default:
                             LOG_ALWAYS_FATAL("Unknown socket type");
                     }
@@ -335,6 +341,9 @@
                         if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
                         break;
 #endif // __BIONIC__
+                    case SocketType::INET:
+                        if (ret.connection->addInetClient("127.0.0.1", port)) goto success;
+                        break;
                     default:
                         LOG_ALWAYS_FATAL("Unknown socket type");
                 }
@@ -852,12 +861,13 @@
 }
 
 INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
-                        ::testing::Values(SocketType::UNIX
+                        ::testing::ValuesIn({
+                                SocketType::UNIX,
 #ifdef __BIONIC__
-                                          ,
-                                          SocketType::VSOCK
+                                SocketType::VSOCK,
 #endif // __BIONIC__
-                                          ),
+                                SocketType::INET,
+                        }),
                         PrintSocketType);
 
 } // namespace android
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
new file mode 100644
index 0000000..dd38224
--- /dev/null
+++ b/libs/permission/Android.bp
@@ -0,0 +1,14 @@
+cc_library_shared {
+    name: "libpermission",
+    srcs: [
+        "AppOpsManager.cpp",
+        "IAppOpsCallback.cpp",
+        "IAppOpsService.cpp",
+    ],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/libs/binder/AppOpsManager.cpp b/libs/permission/AppOpsManager.cpp
similarity index 100%
rename from libs/binder/AppOpsManager.cpp
rename to libs/permission/AppOpsManager.cpp
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/permission/IAppOpsCallback.cpp
similarity index 100%
rename from libs/binder/IAppOpsCallback.cpp
rename to libs/permission/IAppOpsCallback.cpp
diff --git a/libs/binder/IAppOpsService.cpp b/libs/permission/IAppOpsService.cpp
similarity index 100%
rename from libs/binder/IAppOpsService.cpp
rename to libs/permission/IAppOpsService.cpp
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h
similarity index 100%
rename from libs/binder/include/binder/AppOpsManager.h
rename to libs/permission/include/binder/AppOpsManager.h
diff --git a/libs/binder/include/binder/IAppOpsCallback.h b/libs/permission/include/binder/IAppOpsCallback.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsCallback.h
rename to libs/permission/include/binder/IAppOpsCallback.h
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/permission/include/binder/IAppOpsService.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsService.h
rename to libs/permission/include/binder/IAppOpsService.h
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 497c33c..edd453a 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -48,11 +48,10 @@
         "libutils",
         "liblog",
         "libhardware",
+        "libpermission",
     ],
 
     export_include_dirs: ["include"],
 
-    export_shared_lib_headers: ["libbinder", "libhardware"],
+    export_shared_lib_headers: ["libbinder", "libpermission", "libhardware"],
 }
-
-subdirs = ["tests"]
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 9aecaff..4151b45 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -54,6 +54,7 @@
         "libbinder",
         "libsensor",
         "libsensorprivacy",
+        "libpermission",
         "libprotoutil",
         "libcrypto",
         "libbase",
@@ -74,6 +75,7 @@
         "libactivitymanager_aidl",
         "libsensor",
         "libsensorprivacy",
+        "libpermission",
     ],
 }