Merge "Add servicedispatcher"
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 424299d..509ee0e 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -83,7 +83,7 @@
  *
  * To clear a previous process binding, invoke with NETWORK_UNSPECIFIED.
  *
- * This is the equivalent of: [android.net.ConnectivityManager#setProcessDefaultNetwork()](https://developer.android.com/reference/android/net/ConnectivityManager.html#setProcessDefaultNetwork(android.net.Network))
+ * This is the equivalent of: [android.net.ConnectivityManager#bindProcessToNetwork()](https://developer.android.com/reference/android/net/ConnectivityManager.html#bindProcessToNetwork(android.net.Network))
  *
  * Available since API level 23.
  */
@@ -91,6 +91,41 @@
 
 
 /**
+ * Gets the |network| bound to the current process, as per android_setprocnetwork.
+ *
+ * This is the equivalent of: [android.net.ConnectivityManager#getBoundNetworkForProcess()](https://developer.android.com/reference/android/net/ConnectivityManager.html#getBoundNetworkForProcess(android.net.Network))
+ * Returns 0 on success, or -1 setting errno to EINVAL if a null pointer is
+ * passed in.
+ *
+ *
+ * Available since API level 31.
+ */
+int android_getprocnetwork(net_handle_t *network) __INTRODUCED_IN(31);
+
+/**
+ * Binds domain name resolutions performed by this process to |network|.
+ * android_setprocnetwork takes precedence over this setting.
+ *
+ * To clear a previous process binding, invoke with NETWORK_UNSPECIFIED.
+ * On success 0 is returned. On error -1 is returned, and errno is set.
+ *
+ * Available since API level 31.
+ */
+int android_setprocdns(net_handle_t network) __INTRODUCED_IN(31);
+
+/**
+ * Gets the |network| to which domain name resolutions are bound on the
+ * current process.
+ *
+ * Returns 0 on success, or -1 setting errno to EINVAL if a null pointer is
+ * passed in.
+ *
+ * Available since API level 31.
+ */
+int android_getprocdns(net_handle_t *network) __INTRODUCED_IN(31);
+
+
+/**
  * Perform hostname resolution via the DNS servers associated with |network|.
  *
  * All arguments (apart from |network|) are used identically as those passed
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 9be05d3..b9c8d20 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -71,6 +71,8 @@
 cc_library {
     name: "libbinder",
 
+    version_script: "libbinder.map",
+
     // for vndbinder
     vendor_available: true,
     vndk: {
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index c83c383..415b44e 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -197,9 +197,7 @@
 
 // ---------------------------------------------------------------------------
 
-BBinder::BBinder() : mExtras(nullptr), mStability(0)
-{
-}
+BBinder::BBinder() : mExtras(nullptr), mStability(0), mParceled(false) {}
 
 bool BBinder::isBinderAlive() const
 {
@@ -322,6 +320,10 @@
 
 void BBinder::setRequestingSid(bool requestingSid)
 {
+    ALOGW_IF(mParceled,
+             "setRequestingSid() should not be called after a binder object "
+             "is parceled/sent to another process");
+
     Extras* e = mExtras.load(std::memory_order_acquire);
 
     if (!e) {
@@ -344,6 +346,10 @@
 }
 
 void BBinder::setMinSchedulerPolicy(int policy, int priority) {
+    ALOGW_IF(mParceled,
+             "setMinSchedulerPolicy() should not be called after a binder object "
+             "is parceled/sent to another process");
+
     switch (policy) {
     case SCHED_NORMAL:
       LOG_ALWAYS_FATAL_IF(priority < -20 || priority > 19, "Invalid priority for SCHED_NORMAL: %d", priority);
@@ -391,6 +397,10 @@
 }
 
 void BBinder::setInheritRt(bool inheritRt) {
+    ALOGW_IF(mParceled,
+             "setInheritRt() should not be called after a binder object "
+             "is parceled/sent to another process");
+
     Extras* e = mExtras.load(std::memory_order_acquire);
 
     if (!e) {
@@ -410,10 +420,22 @@
 }
 
 void BBinder::setExtension(const sp<IBinder>& extension) {
+    ALOGW_IF(mParceled,
+             "setExtension() should not be called after a binder object "
+             "is parceled/sent to another process");
+
     Extras* e = getOrCreateExtras();
     e->mExtension = extension;
 }
 
+bool BBinder::wasParceled() {
+    return mParceled;
+}
+
+void BBinder::setParceled() {
+    mParceled = true;
+}
+
 status_t BBinder::setRpcClientDebug(const Parcel& data) {
     if constexpr (!kEnableRpcDevServers) {
         ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 47dd32e..d421060 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -129,8 +129,7 @@
     return checkCallingPermission(permission, nullptr, nullptr);
 }
 
-static String16 _permission("permission");
-
+static StaticString16 _permission(u"permission");
 
 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
 {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index d19b4d8..232a70c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -173,8 +173,8 @@
 status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder)
 {
     internal::Stability::tryMarkCompilationUnit(binder.get());
-    auto category = internal::Stability::getCategory(binder.get());
-    return writeInt32(category.repr());
+    int16_t rep = internal::Stability::getCategory(binder.get()).repr();
+    return writeInt32(rep);
 }
 
 status_t Parcel::finishUnflattenBinder(
@@ -184,7 +184,8 @@
     status_t status = readInt32(&stability);
     if (status != OK) return status;
 
-    status = internal::Stability::setRepr(binder.get(), stability, true /*log*/);
+    status = internal::Stability::setRepr(binder.get(), static_cast<int16_t>(stability),
+                                          true /*log*/);
     if (status != OK) return status;
 
     *out = binder;
@@ -195,8 +196,11 @@
     return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
 }
 
-status_t Parcel::flattenBinder(const sp<IBinder>& binder)
-{
+status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
+    BBinder* local = nullptr;
+    if (binder) local = binder->localBinder();
+    if (local) local->setParceled();
+
     if (isForRpc()) {
         if (binder) {
             status_t status = writeInt32(1); // non-null
@@ -222,7 +226,6 @@
     }
 
     if (binder != nullptr) {
-        BBinder *local = binder->localBinder();
         if (!local) {
             BpBinder *proxy = binder->remoteBinder();
             if (proxy == nullptr) {
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 5ffee06..2f378da 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -153,7 +153,22 @@
 
     status_t status;
     while ((status = mShutdownTrigger->triggerablePollRead(mServer)) == OK) {
-        (void)acceptOne();
+        unique_fd clientFd(TEMP_FAILURE_RETRY(
+                accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
+
+        if (clientFd < 0) {
+            ALOGE("Could not accept4 socket: %s", strerror(errno));
+            continue;
+        }
+        LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+
+        {
+            std::lock_guard<std::mutex> _l(mLock);
+            std::thread thread =
+                    std::thread(&RpcServer::establishConnection, sp<RpcServer>::fromExisting(this),
+                                std::move(clientFd));
+            mConnectingThreads[thread.get_id()] = std::move(thread);
+        }
     }
     LOG_RPC_DETAIL("RpcServer::join exiting with %s", statusToString(status).c_str());
 
@@ -164,26 +179,6 @@
     mShutdownCv.notify_all();
 }
 
-bool RpcServer::acceptOne() {
-    unique_fd clientFd(
-            TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
-
-    if (clientFd < 0) {
-        ALOGE("Could not accept4 socket: %s", strerror(errno));
-        return false;
-    }
-    LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
-
-    {
-        std::lock_guard<std::mutex> _l(mLock);
-        std::thread thread = std::thread(&RpcServer::establishConnection,
-                                         sp<RpcServer>::fromExisting(this), std::move(clientFd));
-        mConnectingThreads[thread.get_id()] = std::move(thread);
-    }
-
-    return true;
-}
-
 bool RpcServer::shutdown() {
     std::unique_lock<std::mutex> _l(mLock);
     if (mShutdownTrigger == nullptr) {
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index a27dff5..c563377 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -240,7 +240,8 @@
     sp<RpcConnection> connection = session->assignServerToThisThread(std::move(client));
 
     while (true) {
-        status_t error = session->state()->getAndExecuteCommand(connection->fd, session);
+        status_t error = session->state()->getAndExecuteCommand(connection->fd, session,
+                                                                RpcState::CommandType::ANY);
 
         if (error != OK) {
             LOG_RPC_DETAIL("Binder connection thread closing w/ status %s",
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 76df970..93f1529 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -134,6 +134,15 @@
 
 void RpcState::dump() {
     std::lock_guard<std::mutex> _l(mNodeMutex);
+    dumpLocked();
+}
+
+void RpcState::terminate() {
+    std::unique_lock<std::mutex> _l(mNodeMutex);
+    terminate(_l);
+}
+
+void RpcState::dumpLocked() {
     ALOGE("DUMP OF RpcState %p", this);
     ALOGE("DUMP OF RpcState (%zu nodes)", mNodeForAddress.size());
     for (const auto& [address, node] : mNodeForAddress) {
@@ -161,10 +170,10 @@
     ALOGE("END DUMP OF RpcState");
 }
 
-void RpcState::terminate() {
+void RpcState::terminate(std::unique_lock<std::mutex>& lock) {
     if (SHOULD_LOG_RPC_DETAIL) {
         ALOGE("RpcState::terminate()");
-        dump();
+        dumpLocked();
     }
 
     // if the destructor of a binder object makes another RPC call, then calling
@@ -172,20 +181,20 @@
     // mNodeMutex is no longer taken.
     std::vector<sp<IBinder>> tempHoldBinder;
 
-    {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
-        mTerminated = true;
-        for (auto& [address, node] : mNodeForAddress) {
-            sp<IBinder> binder = node.binder.promote();
-            LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
+    mTerminated = true;
+    for (auto& [address, node] : mNodeForAddress) {
+        sp<IBinder> binder = node.binder.promote();
+        LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
 
-            if (node.sentRef != nullptr) {
-                tempHoldBinder.push_back(node.sentRef);
-            }
+        if (node.sentRef != nullptr) {
+            tempHoldBinder.push_back(node.sentRef);
         }
-
-        mNodeForAddress.clear();
     }
+
+    mNodeForAddress.clear();
+
+    lock.unlock();
+    tempHoldBinder.clear(); // explicit
 }
 
 RpcState::CommandData::CommandData(size_t size) : mSize(size) {
@@ -341,52 +350,57 @@
     uint64_t asyncNumber = 0;
 
     if (!address.isZero()) {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
+        std::unique_lock<std::mutex> _l(mNodeMutex);
         if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
         auto it = mNodeForAddress.find(address);
         LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s",
                             address.toString().c_str());
 
         if (flags & IBinder::FLAG_ONEWAY) {
-            asyncNumber = it->second.asyncNumber++;
+            asyncNumber = it->second.asyncNumber;
+            if (!nodeProgressAsyncNumber(&it->second, _l)) return DEAD_OBJECT;
         }
     }
 
+    LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+                                        sizeof(RpcWireTransaction) <
+                                data.dataSize(),
+                        "Too much data %zu", data.dataSize());
+
+    RpcWireHeader command{
+            .command = RPC_COMMAND_TRANSACT,
+            .bodySize = static_cast<uint32_t>(sizeof(RpcWireTransaction) + data.dataSize()),
+    };
     RpcWireTransaction transaction{
             .address = address.viewRawEmbedded(),
             .code = code,
             .flags = flags,
             .asyncNumber = asyncNumber,
     };
-
-    CommandData transactionData(sizeof(RpcWireTransaction) + data.dataSize());
+    CommandData transactionData(sizeof(RpcWireHeader) + sizeof(RpcWireTransaction) +
+                                data.dataSize());
     if (!transactionData.valid()) {
         return NO_MEMORY;
     }
 
-    memcpy(transactionData.data() + 0, &transaction, sizeof(RpcWireTransaction));
-    memcpy(transactionData.data() + sizeof(RpcWireTransaction), data.data(), data.dataSize());
+    memcpy(transactionData.data() + 0, &command, sizeof(RpcWireHeader));
+    memcpy(transactionData.data() + sizeof(RpcWireHeader), &transaction,
+           sizeof(RpcWireTransaction));
+    memcpy(transactionData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireTransaction), data.data(),
+           data.dataSize());
 
-    if (transactionData.size() > std::numeric_limits<uint32_t>::max()) {
-        ALOGE("Transaction size too big %zu", transactionData.size());
-        return BAD_VALUE;
-    }
-
-    RpcWireHeader command{
-            .command = RPC_COMMAND_TRANSACT,
-            .bodySize = static_cast<uint32_t>(transactionData.size()),
-    };
-
-    if (status_t status = rpcSend(fd, "transact header", &command, sizeof(command)); status != OK)
-        return status;
     if (status_t status =
-                rpcSend(fd, "command body", transactionData.data(), transactionData.size());
+                rpcSend(fd, "transaction", transactionData.data(), transactionData.size());
         status != OK)
         return status;
 
     if (flags & IBinder::FLAG_ONEWAY) {
         LOG_RPC_DETAIL("Oneway command, so no longer waiting on %d", fd.get());
-        return OK; // do not wait for result
+
+        // Do not wait on result.
+        // However, too many oneway calls may cause refcounts to build up and fill up the socket,
+        // so process those.
+        return drainCommands(fd, session, CommandType::CONTROL_ONLY);
     }
 
     LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction.");
@@ -413,7 +427,8 @@
 
         if (command.command == RPC_COMMAND_REPLY) break;
 
-        if (status_t status = processServerCommand(fd, session, command); status != OK)
+        if (status_t status = processServerCommand(fd, session, command, CommandType::ANY);
+            status != OK)
             return status;
     }
 
@@ -453,9 +468,8 @@
                             addr.toString().c_str());
 
         it->second.timesRecd--;
-        if (it->second.timesRecd == 0 && it->second.timesSent == 0) {
-            mNodeForAddress.erase(it);
-        }
+        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
+                            "Bad state. RpcState shouldn't own received binder");
     }
 
     RpcWireHeader cmd = {
@@ -471,7 +485,8 @@
     return OK;
 }
 
-status_t RpcState::getAndExecuteCommand(const base::unique_fd& fd, const sp<RpcSession>& session) {
+status_t RpcState::getAndExecuteCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
+                                        CommandType type) {
     LOG_RPC_DETAIL("getAndExecuteCommand on fd %d", fd.get());
 
     RpcWireHeader command;
@@ -479,11 +494,21 @@
         status != OK)
         return status;
 
-    return processServerCommand(fd, session, command);
+    return processServerCommand(fd, session, command, type);
+}
+
+status_t RpcState::drainCommands(const base::unique_fd& fd, const sp<RpcSession>& session,
+                                 CommandType type) {
+    uint8_t buf;
+    while (0 < TEMP_FAILURE_RETRY(recv(fd.get(), &buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT))) {
+        status_t status = getAndExecuteCommand(fd, session, type);
+        if (status != OK) return status;
+    }
+    return OK;
 }
 
 status_t RpcState::processServerCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                        const RpcWireHeader& command) {
+                                        const RpcWireHeader& command, CommandType type) {
     IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
     IPCThreadState::SpGuard spGuard{
             .address = __builtin_frame_address(0),
@@ -501,6 +526,7 @@
 
     switch (command.command) {
         case RPC_COMMAND_TRANSACT:
+            if (type != CommandType::ANY) return BAD_TYPE;
             return processTransact(fd, session, command);
         case RPC_COMMAND_DEC_STRONG:
             return processDecStrong(fd, session, command);
@@ -681,13 +707,7 @@
             // last refcount dropped after this transaction happened
             if (it == mNodeForAddress.end()) return OK;
 
-            // note - only updated now, instead of later, so that other threads
-            // will queue any later transactions
-
-            // TODO(b/183140903): support > 2**64 async transactions
-            //     (we can do this by allowing asyncNumber to wrap, since we
-            //     don't expect more than 2**64 simultaneous transactions)
-            it->second.asyncNumber++;
+            if (!nodeProgressAsyncNumber(&it->second, _l)) return DEAD_OBJECT;
 
             if (it->second.asyncTodo.size() == 0) return OK;
             if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) {
@@ -711,35 +731,29 @@
         return OK;
     }
 
+    LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+                                        sizeof(RpcWireReply) <
+                                reply.dataSize(),
+                        "Too much data for reply %zu", reply.dataSize());
+
+    RpcWireHeader cmdReply{
+            .command = RPC_COMMAND_REPLY,
+            .bodySize = static_cast<uint32_t>(sizeof(RpcWireReply) + reply.dataSize()),
+    };
     RpcWireReply rpcReply{
             .status = replyStatus,
     };
 
-    CommandData replyData(sizeof(RpcWireReply) + reply.dataSize());
+    CommandData replyData(sizeof(RpcWireHeader) + sizeof(RpcWireReply) + reply.dataSize());
     if (!replyData.valid()) {
         return NO_MEMORY;
     }
-    memcpy(replyData.data() + 0, &rpcReply, sizeof(RpcWireReply));
-    memcpy(replyData.data() + sizeof(RpcWireReply), reply.data(), reply.dataSize());
+    memcpy(replyData.data() + 0, &cmdReply, sizeof(RpcWireHeader));
+    memcpy(replyData.data() + sizeof(RpcWireHeader), &rpcReply, sizeof(RpcWireReply));
+    memcpy(replyData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireReply), reply.data(),
+           reply.dataSize());
 
-    if (replyData.size() > std::numeric_limits<uint32_t>::max()) {
-        ALOGE("Reply size too big %zu", transactionData.size());
-        terminate();
-        return BAD_VALUE;
-    }
-
-    RpcWireHeader cmdReply{
-            .command = RPC_COMMAND_REPLY,
-            .bodySize = static_cast<uint32_t>(replyData.size()),
-    };
-
-    if (status_t status = rpcSend(fd, "reply header", &cmdReply, sizeof(RpcWireHeader));
-        status != OK)
-        return status;
-    if (status_t status = rpcSend(fd, "reply body", replyData.data(), replyData.size());
-        status != OK)
-        return status;
-    return OK;
+    return rpcSend(fd, "reply", replyData.data(), replyData.size());
 }
 
 status_t RpcState::processDecStrong(const base::unique_fd& fd, const sp<RpcSession>& session,
@@ -788,22 +802,40 @@
     LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s",
                         addr.toString().c_str());
 
-    sp<IBinder> tempHold;
-
     it->second.timesSent--;
-    if (it->second.timesSent == 0) {
-        tempHold = it->second.sentRef;
-        it->second.sentRef = nullptr;
-
-        if (it->second.timesRecd == 0) {
-            mNodeForAddress.erase(it);
-        }
-    }
-
+    sp<IBinder> tempHold = tryEraseNode(it);
     _l.unlock();
     tempHold = nullptr; // destructor may make binder calls on this session
 
     return OK;
 }
 
+sp<IBinder> RpcState::tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it) {
+    sp<IBinder> ref;
+
+    if (it->second.timesSent == 0) {
+        ref = std::move(it->second.sentRef);
+
+        if (it->second.timesRecd == 0) {
+            LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
+                                "Can't delete binder w/ pending async transactions");
+            mNodeForAddress.erase(it);
+        }
+    }
+
+    return ref;
+}
+
+bool RpcState::nodeProgressAsyncNumber(BinderNode* node, std::unique_lock<std::mutex>& lock) {
+    // 2**64 =~ 10**19 =~ 1000 transactions per second for 585 million years to
+    // a single binder
+    if (node->asyncNumber >= std::numeric_limits<decltype(node->asyncNumber)>::max()) {
+        ALOGE("Out of async transaction IDs. Terminating");
+        terminate(lock);
+        return false;
+    }
+    node->asyncNumber++;
+    return true;
+}
+
 } // namespace android
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index d63c1c3..81ff458 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -66,8 +66,15 @@
                                            const sp<RpcSession>& session, Parcel* reply,
                                            uint32_t flags);
     [[nodiscard]] status_t sendDecStrong(const base::unique_fd& fd, const RpcAddress& address);
+
+    enum class CommandType {
+        ANY,
+        CONTROL_ONLY,
+    };
     [[nodiscard]] status_t getAndExecuteCommand(const base::unique_fd& fd,
-                                                const sp<RpcSession>& session);
+                                                const sp<RpcSession>& session, CommandType type);
+    [[nodiscard]] status_t drainCommands(const base::unique_fd& fd, const sp<RpcSession>& session,
+                                         CommandType type);
 
     /**
      * Called by Parcel for outgoing binders. This implies one refcount of
@@ -106,6 +113,9 @@
     void terminate();
 
 private:
+    void dumpLocked();
+    void terminate(std::unique_lock<std::mutex>& lock);
+
     // Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
     // large allocations to avoid being requested from allocating too much data.
     struct CommandData {
@@ -129,7 +139,7 @@
                                         Parcel* reply);
     [[nodiscard]] status_t processServerCommand(const base::unique_fd& fd,
                                                 const sp<RpcSession>& session,
-                                                const RpcWireHeader& command);
+                                                const RpcWireHeader& command, CommandType type);
     [[nodiscard]] status_t processTransact(const base::unique_fd& fd, const sp<RpcSession>& session,
                                            const RpcWireHeader& command);
     [[nodiscard]] status_t processTransactInternal(const base::unique_fd& fd,
@@ -188,6 +198,16 @@
         // (no additional data specific to remote binders)
     };
 
+    // checks if there is any reference left to a node and erases it. If erase
+    // happens, and there is a strong reference to the binder kept by
+    // binderNode, this returns that strong reference, so that it can be
+    // dropped after any locks are removed.
+    sp<IBinder> tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it);
+    // true - success
+    // false - state terminated, lock gone, halt
+    [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node,
+                                               std::unique_lock<std::mutex>& lock);
+
     std::mutex mNodeMutex;
     bool mTerminated = false;
     // binders known by both sides of a session
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 601ce96..dac3819 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -33,7 +33,6 @@
 Stability::Category Stability::Category::currentFromLevel(Level level) {
     return {
         .version = kBinderWireFormatVersion,
-        .reserved = {0},
         .level = level,
     };
 }
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 754f87c..d162dda 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -94,6 +94,13 @@
 
     pid_t               getDebugPid();
 
+    // Whether this binder has been sent to another process.
+    bool wasParceled();
+    // Consider this binder as parceled (setup/init-related calls should no
+    // longer by called. This is automatically set by when this binder is sent
+    // to another process.
+    void setParceled();
+
     [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd,
                                              uint32_t maxRpcThreads);
 
@@ -119,10 +126,13 @@
     std::atomic<Extras*> mExtras;
 
     friend ::android::internal::Stability;
-    union {
-        int32_t mStability;
-        void* mReserved0;
-    };
+    int16_t mStability;
+    bool mParceled;
+    uint8_t mReserved0;
+
+#ifdef __LP64__
+    int32_t mReserved1;
+#endif
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 0082ec3..98db221 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -160,7 +160,6 @@
 
     static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd);
     bool setupSocketServer(const RpcSocketAddress& address);
-    [[nodiscard]] bool acceptOne();
 
     bool mAgreedExperimental = false;
     size_t mMaxThreads = 1;
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index 6bc607f..629b565 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -136,14 +136,15 @@
         VINTF = 0b111111,
     };
 
-    // This is the format of stability passed on the wire.
+    // This is the format of stability passed on the wire. It is only 2 bytes
+    // long, but 2 bytes in addition to this are reserved here. The difference
+    // in size is in order to free up space in BBinder, which is fixed by
+    // prebuilts inheriting from it.
     struct Category {
-        static inline Category fromRepr(int32_t representation) {
+        static inline Category fromRepr(int16_t representation) {
             return *reinterpret_cast<Category*>(&representation);
         }
-        int32_t repr() const {
-            return *reinterpret_cast<const int32_t*>(this);
-        }
+        int16_t repr() const { return *reinterpret_cast<const int16_t*>(this); }
         static inline Category currentFromLevel(Level level);
 
         bool operator== (const Category& o) const {
@@ -161,12 +162,10 @@
         // class must write parcels according to the version documented here.
         uint8_t version;
 
-        uint8_t reserved[2];
-
         // bitmask of Stability::Level
         Level level;
     };
-    static_assert(sizeof(Category) == sizeof(int32_t));
+    static_assert(sizeof(Category) == sizeof(int16_t));
 
     // returns the stability according to how this was built
     static Level getLocalLevel();
diff --git a/libs/binder/libbinder.map b/libs/binder/libbinder.map
new file mode 100644
index 0000000..9ca14bc
--- /dev/null
+++ b/libs/binder/libbinder.map
@@ -0,0 +1,5 @@
+# b/190148312: Populate with correct list of ABI symbols
+LIBBINDER {
+  global:
+    *;
+};
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index bb51bf0..ede4873 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -95,7 +95,7 @@
         "libbinder_ndk",
         "libutils",
     ],
-    test_suites: ["general-tests", "vts"],
+    test_suites: ["general-tests"],
     require_root: true,
 }
 
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 3289b5f..c4eacfd 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -29,6 +29,7 @@
 #include <gtest/gtest.h>
 
 #include <android-base/properties.h>
+#include <android-base/result-gmock.h>
 #include <android-base/result.h>
 #include <android-base/unique_fd.h>
 #include <binder/Binder.h>
@@ -52,6 +53,7 @@
 using namespace android;
 using namespace std::string_literals;
 using namespace std::chrono_literals;
+using android::base::testing::HasValue;
 using testing::ExplainMatchResult;
 using testing::Not;
 using testing::WithParamInterface;
@@ -62,15 +64,6 @@
     return expected == arg;
 }
 
-// e.g. Result<int32_t> v = 0; EXPECT_THAT(result, ResultHasValue(0));
-MATCHER_P(ResultHasValue, resultMatcher, "") {
-    if (!arg.ok()) {
-        *result_listener << "contains error " << arg.error();
-        return false;
-    }
-    return ExplainMatchResult(resultMatcher, arg.value(), result_listener);
-}
-
 static ::testing::AssertionResult IsPageAligned(void *buf) {
     if (((unsigned long)buf & ((unsigned long)PAGE_SIZE - 1)) == 0)
         return ::testing::AssertionSuccess();
@@ -443,6 +436,14 @@
         };
 };
 
+TEST_F(BinderLibTest, WasParceled) {
+    auto binder = sp<BBinder>::make();
+    EXPECT_FALSE(binder->wasParceled());
+    Parcel data;
+    data.writeStrongBinder(binder);
+    EXPECT_TRUE(binder->wasParceled());
+}
+
 TEST_F(BinderLibTest, NopTransaction) {
     Parcel data, reply;
     EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply),
@@ -514,7 +515,7 @@
 }
 
 TEST_F(BinderLibTest, GetId) {
-    EXPECT_THAT(GetId(m_server), ResultHasValue(0));
+    EXPECT_THAT(GetId(m_server), HasValue(0));
 }
 
 TEST_F(BinderLibTest, PtrSize) {
@@ -1279,7 +1280,7 @@
     sp<IBinder> server = isRemote ? sp<IBinder>(CreateRemoteService(id))
                                   : sp<IBinder>(sp<BinderLibTestService>::make(id, false));
     ASSERT_EQ(isRemote, !!server->remoteBinder());
-    ASSERT_THAT(GetId(server), ResultHasValue(id));
+    ASSERT_THAT(GetId(server), HasValue(id));
 
     unsigned int port = 0;
     // Fake servicedispatcher.
@@ -1309,7 +1310,7 @@
         EXPECT_EQ(OK, rpcServerBinder->pingBinder());
 
         // Check that |rpcServerBinder| and |server| points to the same service.
-        EXPECT_THAT(GetId(rpcServerBinder), ResultHasValue(id));
+        EXPECT_THAT(GetId(rpcServerBinder), HasValue(id));
 
         // Occupy the server thread. The server should still have enough threads to handle
         // other connections.
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index e48b7c5..0a970fb 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -876,7 +876,7 @@
 TEST_P(BinderRpc, OnewayStressTest) {
     constexpr size_t kNumClientThreads = 10;
     constexpr size_t kNumServerThreads = 10;
-    constexpr size_t kNumCalls = 50;
+    constexpr size_t kNumCalls = 500;
 
     auto proc = createRpcTestSocketServerProcess(kNumServerThreads);
 
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index fd1793b..90532ec 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -208,6 +208,7 @@
         case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH:
         case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT:
         case ANATIVEWINDOW_QUERY_TRANSFORM_HINT:
+        case ANATIVEWINDOW_QUERY_BUFFER_AGE:
             // these are part of the VNDK API
             break;
         case ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL: