Merge "binderRpcTest: threadpool race leak"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index bb6639e..99f7669 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -416,10 +416,12 @@
  */
 static int restorecon_app_data_lazy(const std::string& path, const std::string& seInfo, uid_t uid,
         bool existing) {
+    ScopedTrace tracer("restorecon-lazy");
     int res = 0;
     char* before = nullptr;
     char* after = nullptr;
     if (!existing) {
+        ScopedTrace tracer("new-path");
         if (selinux_android_restorecon_pkgdir(path.c_str(), seInfo.c_str(), uid,
                 SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
             PLOG(ERROR) << "Failed recursive restorecon for " << path;
@@ -446,6 +448,7 @@
     // If the initial top-level restorecon above changed the label, then go
     // back and restorecon everything recursively
     if (strcmp(before, after)) {
+        ScopedTrace tracer("label-change");
         if (existing) {
             LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at "
                     << path << "; running recursive restorecon";
@@ -480,11 +483,15 @@
 
 static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid, gid_t gid,
                            long project_id) {
-    if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, gid) != 0) {
-        PLOG(ERROR) << "Failed to prepare " << path;
-        return -1;
+    {
+        ScopedTrace tracer("prepare-dir");
+        if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, gid) != 0) {
+            PLOG(ERROR) << "Failed to prepare " << path;
+            return -1;
+        }
     }
     if (internal_storage_has_project_id()) {
+        ScopedTrace tracer("set-quota");
         return set_quota_project_id(path, project_id, true);
     }
     return 0;
@@ -493,14 +500,20 @@
 static int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t target_mode,
                                  uid_t uid, gid_t gid, long project_id) {
     auto path = StringPrintf("%s/%s", parent.c_str(), name);
-    int ret = prepare_app_cache_dir(parent, name, target_mode, uid, gid);
+    int ret;
+    {
+        ScopedTrace tracer("prepare-cache-dir");
+        ret = prepare_app_cache_dir(parent, name, target_mode, uid, gid);
+    }
     if (ret == 0 && internal_storage_has_project_id()) {
+        ScopedTrace tracer("set-quota-cache-dir");
         return set_quota_project_id(path, project_id, true);
     }
     return ret;
 }
 
 static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) {
+    ScopedTrace tracer("prepare-app-profile");
     int32_t uid = multiuser_get_uid(userId, appId);
     int shared_app_gid = multiuser_get_shared_gid(userId, appId);
     if (shared_app_gid == -1) {
@@ -633,6 +646,7 @@
                                         int32_t previousUid, int32_t cacheGid,
                                         const std::string& seInfo, mode_t targetMode,
                                         long projectIdApp, long projectIdCache) {
+    ScopedTrace tracer("create-dirs");
     struct stat st{};
     bool parent_dir_exists = (stat(path.c_str(), &st) == 0);
 
@@ -709,6 +723,7 @@
     long projectIdCache = get_project_id(uid, PROJECT_ID_APP_CACHE_START);
 
     if (flags & FLAG_STORAGE_CE) {
+        ScopedTrace tracer("ce");
         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname);
 
         auto status = createAppDataDirs(path, uid, uid, previousUid, cacheGid, seInfo, targetMode,
@@ -735,6 +750,7 @@
         }
     }
     if (flags & FLAG_STORAGE_DE) {
+        ScopedTrace tracer("de");
         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
 
         auto status = createAppDataDirs(path, uid, uid, previousUid, cacheGid, seInfo, targetMode,
@@ -752,13 +768,14 @@
     }
 
     if (flags & FLAG_STORAGE_SDK) {
+        ScopedTrace tracer("sdk");
         // Safe to ignore status since we can retry creating this by calling reconcileSdkData
         auto ignore = createSdkSandboxDataPackageDirectory(uuid, packageName, userId, appId, flags);
         if (!ignore.isOk()) {
             PLOG(WARNING) << "Failed to create sdk data package directory for " << packageName;
         }
-
     } else {
+        ScopedTrace tracer("destroy-sdk");
         // Package does not need sdk storage. Remove it.
         destroySdkSandboxDataPackageDirectory(uuid, packageName, userId, flags);
     }
@@ -1850,6 +1867,8 @@
     CHECK_ARGUMENT_UUID(uuid);
     LOCK_USER();
 
+    ScopedTrace tracer("create-user-data");
+
     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
     if (flags & FLAG_STORAGE_DE) {
         if (uuid_ == nullptr) {
diff --git a/cmds/installd/SysTrace.h b/cmds/installd/SysTrace.h
index 18506a9..0deaeb4 100644
--- a/cmds/installd/SysTrace.h
+++ b/cmds/installd/SysTrace.h
@@ -19,4 +19,16 @@
 namespace android::installd {
 void atrace_pm_begin(const char*);
 void atrace_pm_end();
+
+class ScopedTrace {
+public:
+    explicit ScopedTrace(const char* label) { atrace_pm_begin(label); }
+    ~ScopedTrace() { atrace_pm_end(); }
+
+private:
+    ScopedTrace(const ScopedTrace&) = delete;
+    ScopedTrace& operator=(const ScopedTrace&) = delete;
+    ScopedTrace(ScopedTrace&&) = delete;
+    ScopedTrace& operator=(ScopedTrace&&) = delete;
+};
 } /* namespace android::installd */
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 3433138..deff76b 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -525,7 +525,6 @@
         "libbase",
         "libbinder",
         "libbinder_ndk",
-        "libcutils_sockets",
         "liblog",
         "libutils",
     ],
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
index a157792..7d0acd1 100644
--- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
+++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
@@ -40,12 +40,13 @@
 [[nodiscard]] ARpcServer* ARpcServer_newVsock(AIBinder* service, unsigned int cid,
                                               unsigned int port);
 
-// Starts a Unix domain RPC server with a given init-managed Unix domain `name`
+// Starts a Unix domain RPC server with an open raw socket file descriptor
 // and a given root IBinder object.
-// The socket should be created in init.rc with the same `name`.
+// The socket should be created and bound to an address.
 // Returns an opaque handle to the running server instance, or null if the server
 // could not be started.
-[[nodiscard]] ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name);
+// The socket will be closed by the server once the server goes out of scope.
+[[nodiscard]] ARpcServer* ARpcServer_newBoundSocket(AIBinder* service, int socketFd);
 
 // Starts an RPC server that bootstraps sessions using an existing Unix domain
 // socket pair, with a given root IBinder object.
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
index a167f23..f51cd9b 100644
--- a/libs/binder/libbinder_rpc_unstable.cpp
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -105,22 +105,15 @@
     return createObjectHandle<ARpcServer>(server);
 }
 
-ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name) {
+ARpcServer* ARpcServer_newBoundSocket(AIBinder* service, int socketFd) {
     auto server = RpcServer::make();
-    auto fd = unique_fd(android_get_control_socket(name));
+    auto fd = unique_fd(socketFd);
     if (!fd.ok()) {
-        LOG(ERROR) << "Failed to get fd for the socket:" << name;
+        LOG(ERROR) << "Invalid socket fd " << socketFd;
         return nullptr;
     }
-    // Control socket fds are inherited from init, so they don't have O_CLOEXEC set.
-    // But we don't want any child processes to inherit the socket we are running
-    // the server on, so attempt to set the flag now.
-    if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
-        LOG(WARNING) << "Failed to set CLOEXEC on control socket with name " << name
-                     << " error: " << errno;
-    }
     if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) {
-        LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name
+        LOG(ERROR) << "Failed to set up RPC server with fd " << socketFd
                    << " error: " << statusToString(status).c_str();
         return nullptr;
     }
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
index 63679c2..50f7deb 100644
--- a/libs/binder/libbinder_rpc_unstable.map.txt
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -3,7 +3,7 @@
     ARpcServer_free;
     ARpcServer_join;
     ARpcServer_newInet;
-    ARpcServer_newInitUnixDomain;
+    ARpcServer_newBoundSocket;
     ARpcServer_newVsock;
     ARpcServer_shutdown;
     ARpcServer_start;
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index eba0556..27ce615 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -283,8 +283,8 @@
 
 TEST(NdkBinder, CheckServiceThatDoesExist) {
     AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
-    EXPECT_NE(nullptr, binder);
-    EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
+    ASSERT_NE(nullptr, binder) << "Could not get " << kExistingNonNdkService;
+    EXPECT_EQ(STATUS_OK, AIBinder_ping(binder)) << "Could not ping " << kExistingNonNdkService;
 
     AIBinder_decStrong(binder);
 }
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index c87876a..81f68f5 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -57,26 +57,17 @@
     }
 
     /// Creates a binder RPC server, serving the supplied binder service implementation on the given
-    /// socket file name. The socket should be initialized in init.rc with the same name.
-    pub fn new_init_unix_domain(
-        mut service: SpIBinder,
-        socket_name: &str,
-    ) -> Result<RpcServer, Error> {
-        let socket_name = match CString::new(socket_name) {
-            Ok(s) => s,
-            Err(e) => {
-                log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
-                return Err(Error::from(ErrorKind::InvalidInput));
-            }
-        };
+    /// socket file descriptor. The socket should be bound to an address before calling this
+    /// function.
+    pub fn new_bound_socket(mut service: SpIBinder, socket_fd: OwnedFd) -> Result<RpcServer, Error> {
         let service = service.as_native_mut();
 
         // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
         // Plus the binder objects are threadsafe.
+        // The server takes ownership of the socket FD.
         unsafe {
-            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInitUnixDomain(
-                service,
-                socket_name.as_ptr(),
+            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket(
+                service, socket_fd.into_raw_fd(),
             ))
         }
     }
diff --git a/libs/binder/rust/tests/binderRustNdkInteropTest.cpp b/libs/binder/rust/tests/binderRustNdkInteropTest.cpp
index 59ca6ed..663b9bb 100644
--- a/libs/binder/rust/tests/binderRustNdkInteropTest.cpp
+++ b/libs/binder/rust/tests/binderRustNdkInteropTest.cpp
@@ -54,14 +54,12 @@
     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
 
     auto interface = aidl::IBinderRustNdkInteropTest::fromBinder(binder);
-    // TODO(b/167723746): this test requires that fromBinder allow association
-    // with an already associated local binder by treating it as remote.
-    EXPECT_EQ(interface, nullptr);
+    EXPECT_NE(interface, nullptr);
 
-    // std::string in("testing");
-    // std::string out;
-    // EXPECT_TRUE(interface->echo(in, &out).isOk());
-    // EXPECT_EQ(in, out);
+    std::string in("testing");
+    std::string out;
+    EXPECT_TRUE(interface->echo(in, &out).isOk());
+    EXPECT_EQ(in, out);
 }
 
 int main(int argc, char** argv) {
diff --git a/libs/nativewindow/include/android/hardware_buffer_aidl.h b/libs/nativewindow/include/android/hardware_buffer_aidl.h
index 9fea21e..e269f0d 100644
--- a/libs/nativewindow/include/android/hardware_buffer_aidl.h
+++ b/libs/nativewindow/include/android/hardware_buffer_aidl.h
@@ -34,6 +34,10 @@
 #include <android/hardware_buffer.h>
 #include <sys/cdefs.h>
 
+#ifdef __cplusplus
+#include <string>
+#endif
+
 __BEGIN_DECLS
 
 /**
@@ -119,6 +123,13 @@
     inline AHardwareBuffer* _Nullable get() const { return mBuffer; }
     inline explicit operator bool () const { return mBuffer != nullptr; }
 
+    inline bool operator!=(const HardwareBuffer& rhs) const { return get() != rhs.get(); }
+    inline bool operator<(const HardwareBuffer& rhs) const { return get() < rhs.get(); }
+    inline bool operator<=(const HardwareBuffer& rhs) const { return get() <= rhs.get(); }
+    inline bool operator==(const HardwareBuffer& rhs) const { return get() == rhs.get(); }
+    inline bool operator>(const HardwareBuffer& rhs) const { return get() > rhs.get(); }
+    inline bool operator>=(const HardwareBuffer& rhs) const { return get() >= rhs.get(); }
+
     HardwareBuffer& operator=(HardwareBuffer&& other) noexcept {
         reset(other.release());
         return *this;
@@ -135,6 +146,15 @@
         return ret;
     }
 
+    inline std::string toString() const {
+        if (!mBuffer) {
+            return "<HardwareBuffer: Invalid>";
+        }
+        uint64_t id = 0;
+        AHardwareBuffer_getId(mBuffer, &id);
+        return "<HardwareBuffer " + std::to_string(id) + ">";
+    }
+
 private:
     HardwareBuffer(const HardwareBuffer& other) = delete;
     HardwareBuffer& operator=(const HardwareBuffer& other) = delete;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 96164c0..9b62894 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -5879,9 +5879,9 @@
             StringPrintf("%s does not have a focused window", application->getName().c_str());
     updateLastAnrStateLocked(*application, reason);
 
-    auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
+    auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
         scoped_unlock unlock(mLock);
-        mPolicy->notifyNoFocusedWindowAnr(application);
+        mPolicy->notifyNoFocusedWindowAnr(app);
     };
     postCommandLocked(std::move(command));
 }
@@ -5942,9 +5942,9 @@
 void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
                                                           std::optional<int32_t> pid,
                                                           std::string reason) {
-    auto command = [this, token, pid, reason = std::move(reason)]() REQUIRES(mLock) {
+    auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
         scoped_unlock unlock(mLock);
-        mPolicy->notifyWindowUnresponsive(token, pid, reason);
+        mPolicy->notifyWindowUnresponsive(token, pid, r);
     };
     postCommandLocked(std::move(command));
 }