Merge "libbinder_rs: Add libbinder_rs_on_trusty_mock" into main
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 23f185e..23f33d8 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -37,9 +37,6 @@
     name: "libdumpstateutil",
     defaults: ["dumpstate_cflag_defaults"],
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     srcs: [
         "DumpstateInternal.cpp",
         "DumpstateUtil.cpp",
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 401400d..57a48d7 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -365,9 +365,6 @@
 
     // for vndbinder
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     recovery_available: true,
     double_loadable: true,
     // TODO(b/153609531): remove when no longer needed.
@@ -676,6 +673,7 @@
         "//packages/modules/Virtualization:__subpackages__",
         "//device/google/cuttlefish/shared/minidroid:__subpackages__",
         "//system/software_defined_vehicle:__subpackages__",
+        "//visibility:any_system_partition",
     ],
 }
 
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 42dd691..54457fc 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -44,6 +44,7 @@
 int BpBinder::sNumTrackedUids = 0;
 std::atomic_bool BpBinder::sCountByUidEnabled(false);
 binder_proxy_limit_callback BpBinder::sLimitCallback;
+binder_proxy_warning_callback BpBinder::sWarningCallback;
 bool BpBinder::sBinderProxyThrottleCreate = false;
 
 static StaticString16 kDescriptorUninit(u"");
@@ -52,6 +53,9 @@
 uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
 // Another arbitrary value a binder count needs to drop below before another callback will be called
 uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
+// Arbitrary value between low and high watermark on a bad behaving app to
+// trigger a warning callback.
+uint32_t BpBinder::sBinderProxyCountWarningWatermark = 2250;
 
 std::atomic<uint32_t> BpBinder::sBinderProxyCount(0);
 std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0);
@@ -63,7 +67,8 @@
 
 enum {
     LIMIT_REACHED_MASK = 0x80000000,        // A flag denoting that the limit has been reached
-    COUNTING_VALUE_MASK = 0x7FFFFFFF,       // A mask of the remaining bits for the count value
+    WARNING_REACHED_MASK = 0x40000000,      // A flag denoting that the warning has been reached
+    COUNTING_VALUE_MASK = 0x3FFFFFFF,       // A mask of the remaining bits for the count value
 };
 
 BpBinder::ObjectManager::ObjectManager()
@@ -181,7 +186,13 @@
                 sLastLimitCallbackMap[trackedUid] = trackedValue;
             }
         } else {
-            if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
+            uint32_t currentValue = trackedValue & COUNTING_VALUE_MASK;
+            if (currentValue >= sBinderProxyCountWarningWatermark
+                    && currentValue < sBinderProxyCountHighWatermark
+                    && ((trackedValue & WARNING_REACHED_MASK) == 0)) [[unlikely]] {
+                sTrackingMap[trackedUid] |= WARNING_REACHED_MASK;
+                if (sWarningCallback) sWarningCallback(trackedUid);
+            } else if (currentValue >= sBinderProxyCountHighWatermark) {
                 ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
                       getuid(), trackedUid, trackedValue);
                 sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
@@ -609,11 +620,11 @@
                   binderHandle());
         } else {
             auto countingValue = trackedValue & COUNTING_VALUE_MASK;
-            if ((trackedValue & LIMIT_REACHED_MASK) &&
+            if ((trackedValue & (LIMIT_REACHED_MASK | WARNING_REACHED_MASK)) &&
                 (countingValue <= sBinderProxyCountLowWatermark)) [[unlikely]] {
                 ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
                       getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
-                sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
+                sTrackingMap[mTrackedUid] &= ~(LIMIT_REACHED_MASK | WARNING_REACHED_MASK);
                 sLastLimitCallbackMap.erase(mTrackedUid);
             }
             if (--sTrackingMap[mTrackedUid] == 0) {
@@ -730,15 +741,18 @@
 void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
 void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
 
-void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
+void BpBinder::setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+                                                binder_proxy_warning_callback cbw) {
     RpcMutexUniqueLock _l(sTrackingLock);
-    sLimitCallback = cb;
+    sLimitCallback = std::move(cbl);
+    sWarningCallback = std::move(cbw);
 }
 
-void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
+void BpBinder::setBinderProxyCountWatermarks(int high, int low, int warning) {
     RpcMutexUniqueLock _l(sTrackingLock);
     sBinderProxyCountHighWatermark = high;
     sBinderProxyCountLowWatermark = low;
+    sBinderProxyCountWarningWatermark = warning;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 89a4d27..9f03907 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -35,7 +35,8 @@
 }
 class ProcessState;
 
-using binder_proxy_limit_callback = void(*)(int);
+using binder_proxy_limit_callback = std::function<void(int)>;
+using binder_proxy_warning_callback = std::function<void(int)>;
 
 class BpBinder : public IBinder
 {
@@ -86,8 +87,9 @@
     static void         enableCountByUid();
     static void         disableCountByUid();
     static void         setCountByUidEnabled(bool enable);
-    static void         setLimitCallback(binder_proxy_limit_callback cb);
-    static void         setBinderProxyCountWatermarks(int high, int low);
+    static void         setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+                                                         binder_proxy_warning_callback cbw);
+    static void         setBinderProxyCountWatermarks(int high, int low, int warning);
     static uint32_t     getBinderProxyCount();
 
     std::optional<int32_t> getDebugBinderHandle() const;
@@ -212,6 +214,8 @@
     static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
     static std::atomic<uint32_t>                sBinderProxyCount;
     static std::atomic<uint32_t>                sBinderProxyCountWarned;
+    static binder_proxy_warning_callback        sWarningCallback;
+    static uint32_t                             sBinderProxyCountWarningWatermark;
 };
 
 } // namespace android
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 0ee96e7..2cea14f 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -115,6 +115,7 @@
     BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
     BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
     BINDER_LIB_TEST_GETPID,
+    BINDER_LIB_TEST_GETUID,
     BINDER_LIB_TEST_ECHO_VECTOR,
     BINDER_LIB_TEST_GET_NON_BLOCKING_FD,
     BINDER_LIB_TEST_REJECT_OBJECTS,
@@ -1477,6 +1478,86 @@
     EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
 }
 
+static constexpr int kBpCountHighWatermark = 20;
+static constexpr int kBpCountLowWatermark = 10;
+static constexpr int kBpCountWarningWatermark = 15;
+static constexpr int kInvalidUid = -1;
+
+TEST_F(BinderLibTest, BinderProxyCountCallback) {
+    Parcel data, reply;
+    sp<IBinder> server = addServer();
+    ASSERT_NE(server, nullptr);
+
+    BpBinder::enableCountByUid();
+    EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_GETUID, data, &reply), StatusEq(NO_ERROR));
+    int32_t uid = reply.readInt32();
+    ASSERT_NE(uid, kInvalidUid);
+
+    uint32_t initialCount = BpBinder::getBinderProxyCount();
+    {
+        uint32_t count = initialCount;
+        BpBinder::setBinderProxyCountWatermarks(kBpCountHighWatermark,
+                                                kBpCountLowWatermark,
+                                                kBpCountWarningWatermark);
+        int limitCallbackUid = kInvalidUid;
+        int warningCallbackUid = kInvalidUid;
+        BpBinder::setBinderProxyCountEventCallback([&](int uid) { limitCallbackUid = uid; },
+                                                   [&](int uid) { warningCallbackUid = uid; });
+
+        std::vector<sp<IBinder> > proxies;
+        auto createProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+            warningCallbackUid = limitCallbackUid = kInvalidUid;
+            ASSERT_THAT(server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply),
+                        StatusEq(NO_ERROR));
+            proxies.push_back(reply.readStrongBinder());
+            EXPECT_EQ(BpBinder::getBinderProxyCount(), ++count);
+            EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+            EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+        };
+        auto removeProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+            warningCallbackUid = limitCallbackUid = kInvalidUid;
+            proxies.pop_back();
+            EXPECT_EQ(BpBinder::getBinderProxyCount(), --count);
+            EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+            EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+        };
+
+        // Test the increment/decrement of the binder proxies.
+        for (int i = 1; i <= kBpCountWarningWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+        for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+        createProxyOnce(kInvalidUid, kInvalidUid);
+        for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, kInvalidUid);
+
+        // Go down below the low watermark.
+        for (int i = kBpCountHighWatermark; i >= kBpCountLowWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        for (int i = kBpCountLowWatermark; i <= kBpCountWarningWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+        for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+        createProxyOnce(kInvalidUid, kInvalidUid);
+        for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, kInvalidUid);
+    }
+    EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
+}
+
 class BinderLibRpcTestBase : public BinderLibTest {
 public:
     void SetUp() override {
@@ -1680,6 +1761,9 @@
             case BINDER_LIB_TEST_GETPID:
                 reply->writeInt32(getpid());
                 return NO_ERROR;
+            case BINDER_LIB_TEST_GETUID:
+                reply->writeInt32(getuid());
+                return NO_ERROR;
             case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT:
                 usleep(5000);
                 [[fallthrough]];
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
index 0a584bf..83d0ca7 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
@@ -95,14 +95,16 @@
                  },
                  [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void {
-                     binder_proxy_limit_callback cb = binder_proxy_limit_callback();
-                     bpbinder->setLimitCallback(cb);
+                     binder_proxy_limit_callback cbl = binder_proxy_limit_callback();
+                     binder_proxy_warning_callback cbw = binder_proxy_warning_callback();
+                     bpbinder->setBinderProxyCountEventCallback(cbl, cbw);
                  },
                  [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void {
                      int high = fdp->ConsumeIntegral<int>();
                      int low = fdp->ConsumeIntegral<int>();
-                     bpbinder->setBinderProxyCountWatermarks(high, low);
+                     int warning = fdp->ConsumeIntegral<int>();
+                     bpbinder->setBinderProxyCountWatermarks(high, low, warning);
                  }};
 
 } // namespace android
diff --git a/libs/binder/trusty/RpcServerTrusty.cpp b/libs/binder/trusty/RpcServerTrusty.cpp
index 1f857a0..17919c2 100644
--- a/libs/binder/trusty/RpcServerTrusty.cpp
+++ b/libs/binder/trusty/RpcServerTrusty.cpp
@@ -60,7 +60,7 @@
 
 RpcServerTrusty::RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName,
                                  std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize)
-      : mRpcServer(sp<RpcServer>::make(std::move(ctx))),
+      : mRpcServer(makeRpcServer(std::move(ctx))),
         mPortName(std::move(portName)),
         mPortAcl(std::move(portAcl)) {
     mTipcPort.name = mPortName.c_str();
@@ -68,10 +68,6 @@
     mTipcPort.msg_queue_len = 6; // Three each way
     mTipcPort.priv = this;
 
-    // TODO(b/266741352): follow-up to prevent needing this in the future
-    // Trusty needs to be set to the latest stable version that is in prebuilts there.
-    LOG_ALWAYS_FATAL_IF(!mRpcServer->setProtocolVersion(0));
-
     if (mPortAcl) {
         // Initialize the array of pointers to uuids.
         // The pointers in mUuidPtrs should stay valid across moves of
@@ -101,8 +97,13 @@
 int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const uuid* peer,
                                    void** ctx_p) {
     auto* server = reinterpret_cast<RpcServerTrusty*>(const_cast<void*>(port->priv));
-    server->mRpcServer->mShutdownTrigger = FdTrigger::make();
-    server->mRpcServer->mConnectingThreads[rpc_this_thread::get_id()] = RpcMaybeThread();
+    return handleConnectInternal(server->mRpcServer.get(), chan, peer, ctx_p);
+}
+
+int RpcServerTrusty::handleConnectInternal(RpcServer* rpcServer, handle_t chan, const uuid* peer,
+                                           void** ctx_p) {
+    rpcServer->mShutdownTrigger = FdTrigger::make();
+    rpcServer->mConnectingThreads[rpc_this_thread::get_id()] = RpcMaybeThread();
 
     int rc = NO_ERROR;
     auto joinFn = [&](sp<RpcSession>&& session, RpcSession::PreJoinSetupResult&& result) {
@@ -138,13 +139,17 @@
     std::array<uint8_t, RpcServer::kRpcAddressSize> addr;
     constexpr size_t addrLen = sizeof(*peer);
     memcpy(addr.data(), peer, addrLen);
-    RpcServer::establishConnection(sp(server->mRpcServer), std::move(transportFd), addr, addrLen,
-                                   joinFn);
+    RpcServer::establishConnection(sp<RpcServer>::fromExisting(rpcServer), std::move(transportFd),
+                                   addr, addrLen, joinFn);
 
     return rc;
 }
 
 int RpcServerTrusty::handleMessage(const tipc_port* /*port*/, handle_t /*chan*/, void* ctx) {
+    return handleMessageInternal(ctx);
+}
+
+int RpcServerTrusty::handleMessageInternal(void* ctx) {
     auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
     LOG_ALWAYS_FATAL_IF(channelContext == nullptr,
                         "bad state: message received on uninitialized channel");
@@ -162,6 +167,10 @@
 }
 
 void RpcServerTrusty::handleDisconnect(const tipc_port* /*port*/, handle_t /*chan*/, void* ctx) {
+    return handleDisconnectInternal(ctx);
+}
+
+void RpcServerTrusty::handleDisconnectInternal(void* ctx) {
     auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
     if (channelContext == nullptr) {
         // Connections marked "incoming" (outgoing from the server's side)
diff --git a/libs/binder/trusty/build-config-usertests b/libs/binder/trusty/build-config-usertests
index d0a1fbc..72e5ff9 100644
--- a/libs/binder/trusty/build-config-usertests
+++ b/libs/binder/trusty/build-config-usertests
@@ -16,4 +16,5 @@
 
 [
     porttest("com.android.trusty.binderRpcTest"),
+    porttest("com.android.trusty.rust.binder_rpc_test.test"),
 ]
diff --git a/libs/binder/trusty/include/binder/RpcServerTrusty.h b/libs/binder/trusty/include/binder/RpcServerTrusty.h
index f35d6c2..bd1d90f 100644
--- a/libs/binder/trusty/include/binder/RpcServerTrusty.h
+++ b/libs/binder/trusty/include/binder/RpcServerTrusty.h
@@ -88,6 +88,18 @@
     explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName,
                              std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize);
 
+    // Internal helper that creates the RpcServer.
+    // This is used both from here and Rust.
+    static sp<RpcServer> makeRpcServer(std::unique_ptr<RpcTransportCtx> ctx) {
+        auto rpcServer = sp<RpcServer>::make(std::move(ctx));
+
+        // TODO(b/266741352): follow-up to prevent needing this in the future
+        // Trusty needs to be set to the latest stable version that is in prebuilts there.
+        LOG_ALWAYS_FATAL_IF(!rpcServer->setProtocolVersion(0));
+
+        return rpcServer;
+    }
+
     // The Rpc-specific context maintained for every open TIPC channel.
     struct ChannelContext {
         sp<RpcSession> session;
@@ -99,6 +111,11 @@
     static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx);
     static void handleChannelCleanup(void* ctx);
 
+    static int handleConnectInternal(RpcServer* rpcServer, handle_t chan, const uuid* peer,
+                                     void** ctx_p);
+    static int handleMessageInternal(void* ctx);
+    static void handleDisconnectInternal(void* ctx);
+
     static constexpr tipc_srv_ops kTipcOps = {
             .on_connect = &handleConnect,
             .on_message = &handleMessage,
diff --git a/libs/binder/trusty/rust/binder_rpc_test/aidl/rules.mk b/libs/binder/trusty/rust/binder_rpc_test/aidl/rules.mk
new file mode 100644
index 0000000..1b0dca0
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/aidl/rules.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_TESTS_DIR := $(LOCAL_DIR)/../../../../tests
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_AIDL_LANGUAGE := rust
+
+MODULE_CRATE_NAME := binder_rpc_test_aidl
+
+MODULE_AIDLS := \
+	$(LIBBINDER_TESTS_DIR)/BinderRpcTestClientInfo.aidl \
+	$(LIBBINDER_TESTS_DIR)/BinderRpcTestServerConfig.aidl \
+	$(LIBBINDER_TESTS_DIR)/BinderRpcTestServerInfo.aidl \
+	$(LIBBINDER_TESTS_DIR)/IBinderRpcCallback.aidl \
+	$(LIBBINDER_TESTS_DIR)/IBinderRpcSession.aidl \
+	$(LIBBINDER_TESTS_DIR)/IBinderRpcTest.aidl \
+	$(LIBBINDER_TESTS_DIR)/ParcelableCertificateData.aidl \
+
+include make/aidl.mk
diff --git a/libs/binder/trusty/rust/binder_rpc_test/main.rs b/libs/binder/trusty/rust/binder_rpc_test/main.rs
new file mode 100644
index 0000000..a71ce2c
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/main.rs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#![cfg(test)]
+
+use binder::{IBinder, Strong};
+use binder_rpc_test_aidl::aidl::IBinderRpcTest::IBinderRpcTest;
+use rpcbinder::RpcSession;
+use trusty_std::ffi::{CString, FallibleCString};
+
+test::init!();
+
+const SERVICE_PORT: &str = "com.android.trusty.binderRpcTestService.V1";
+
+fn get_service() -> Strong<dyn IBinderRpcTest> {
+    let port = CString::try_new(SERVICE_PORT).expect("Failed to allocate port name");
+    RpcSession::new().setup_trusty_client(port.as_c_str()).expect("Failed to create session")
+}
+
+#[test]
+fn ping() {
+    let srv = get_service();
+    assert_eq!(srv.as_binder().ping_binder(), Ok(()));
+}
diff --git a/libs/binder/trusty/rust/binder_rpc_test/manifest.json b/libs/binder/trusty/rust/binder_rpc_test/manifest.json
new file mode 100644
index 0000000..c2ecaa4
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/manifest.json
@@ -0,0 +1,9 @@
+{
+    "uuid": "91eed949-8a9e-4569-9c83-5935fb624025",
+    "app_name": "rust_binder_rpc_test",
+    "min_heap": 16384,
+    "min_stack": 16384,
+    "mgmt_flags": {
+        "non_critical_app": true
+    }
+}
diff --git a/libs/binder/trusty/rust/binder_rpc_test/rules.mk b/libs/binder/trusty/rust/binder_rpc_test/rules.mk
new file mode 100644
index 0000000..192a159
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/rules.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_DIR := $(LOCAL_DIR)/../../..
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/main.rs
+
+MODULE_CRATE_NAME := binder_rpc_test
+
+MODULE_LIBRARY_DEPS += \
+	$(LIBBINDER_DIR)/trusty/rust \
+	$(LIBBINDER_DIR)/trusty/rust/rpcbinder \
+	$(LOCAL_DIR)/aidl \
+	trusty/user/base/lib/trusty-std \
+
+MODULE_RUST_TESTS := true
+
+MANIFEST := $(LOCAL_DIR)/manifest.json
+
+include make/library.mk
diff --git a/libs/binder/trusty/usertests-inc.mk b/libs/binder/trusty/usertests-inc.mk
index 1300121..241e668 100644
--- a/libs/binder/trusty/usertests-inc.mk
+++ b/libs/binder/trusty/usertests-inc.mk
@@ -17,3 +17,6 @@
 	frameworks/native/libs/binder/trusty/binderRpcTest \
 	frameworks/native/libs/binder/trusty/binderRpcTest/service \
 
+TRUSTY_RUST_USER_TESTS += \
+	frameworks/native/libs/binder/trusty/rust/binder_rpc_test \
+
diff --git a/libs/bufferqueueconverter/Android.bp b/libs/bufferqueueconverter/Android.bp
index 3fe71ce..2c25f74 100644
--- a/libs/bufferqueueconverter/Android.bp
+++ b/libs/bufferqueueconverter/Android.bp
@@ -16,9 +16,6 @@
 cc_library {
     name: "libbufferqueueconverter",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     double_loadable: true,
 
     srcs: [
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index aab1276..6e2b803 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -37,10 +37,7 @@
     },
 
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        support_system_process: true,
-    },
+    double_loadable: true,
     apex_available: [
         "//apex_available:platform",
         "com.android.media.swcodec",
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index eb4d3df..8643148 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -281,10 +281,6 @@
 cc_library_shared {
     name: "libgui",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-        private: true,
-    },
     double_loadable: true,
 
     defaults: [
diff --git a/libs/nativewindow/rust/Android.bp b/libs/nativewindow/rust/Android.bp
index 90d0a8e..798d804 100644
--- a/libs/nativewindow/rust/Android.bp
+++ b/libs/nativewindow/rust/Android.bp
@@ -53,6 +53,10 @@
     },
     min_sdk_version: "VanillaIceCream",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_library {
@@ -77,6 +81,10 @@
     },
     min_sdk_version: "VanillaIceCream",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_test {
@@ -115,6 +123,10 @@
     },
     min_sdk_version: "VanillaIceCream",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
+    ],
 }
 
 rust_test {
diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs
index 22ad834..dc3f51f 100644
--- a/libs/nativewindow/rust/src/lib.rs
+++ b/libs/nativewindow/rust/src/lib.rs
@@ -16,7 +16,8 @@
 
 extern crate nativewindow_bindgen as ffi;
 
-pub mod surface;
+mod surface;
+pub use surface::Surface;
 
 pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
 
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index ec0ab4e..f84d145 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -104,9 +104,6 @@
 cc_library_shared {
     name: "libui",
     vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
     double_loadable: true,
 
     cflags: [
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index 0aee7d4..ffc1dd7 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -2,7 +2,6 @@
 
 adyabr@google.com
 alecmouri@google.com
-chaviw@google.com
 domlaskowski@google.com
 jreck@google.com
 lpy@google.com
@@ -10,5 +9,6 @@
 racarr@google.com
 ramindani@google.com
 rnlee@google.com
+sallyqi@google.com
 scroggo@google.com
 vishnun@google.com
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c56dc83..f7cc13e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -72,6 +72,7 @@
 #include <gui/TraceUtils.h>
 #include <hidl/ServiceManagement.h>
 #include <layerproto/LayerProtoParser.h>
+#include <linux/sched/types.h>
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
 #include <private/gui/SyncFeatures.h>
@@ -7565,20 +7566,6 @@
         return NO_ERROR;
     }
 
-    // Currently, there is no wrapper in bionic: b/183240349.
-    struct sched_attr {
-        uint32_t size;
-        uint32_t sched_policy;
-        uint64_t sched_flags;
-        int32_t sched_nice;
-        uint32_t sched_priority;
-        uint64_t sched_runtime;
-        uint64_t sched_deadline;
-        uint64_t sched_period;
-        uint32_t sched_util_min;
-        uint32_t sched_util_max;
-    };
-
     sched_attr attr = {};
     attr.size = sizeof(attr);