diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp
new file mode 100644
index 0000000..68cc225
--- /dev/null
+++ b/libs/binderthreadstate/test.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <BnAidlStuff.h>
+#include <android-base/logging.h>
+#include <binder/IServiceManager.h>
+#include <binderthreadstate/CallerUtils.h>
+#include <binderthreadstateutilstest/1.0/IHidlStuff.h>
+#include <gtest/gtest.h>
+#include <hidl/HidlTransportSupport.h>
+#include <linux/prctl.h>
+#include <sys/prctl.h>
+
+using android::BinderCallType;
+using android::defaultServiceManager;
+using android::getCurrentServingCall;
+using android::getService;
+using android::OK;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::Return;
+using binderthreadstateutilstest::V1_0::IHidlStuff;
+
+constexpr size_t kP1Id = 1;
+constexpr size_t kP2Id = 2;
+
+// AIDL and HIDL are in separate namespaces so using same service names
+std::string id2name(size_t id) {
+    return "libbinderthreadstateutils-" + std::to_string(id);
+}
+
+// There are two servers calling each other recursively like this.
+//
+// P1           P2
+// |  --HIDL-->  |
+// |  <--HIDL--  |
+// |  --AIDL-->  |
+// |  <--AIDL--  |
+// |  --HIDL-->  |
+// |  <--HIDL--  |
+// |  --AIDL-->  |
+// |  <--AIDL--  |
+//   ..........
+//
+// Calls always come in pairs (AIDL returns AIDL, HIDL returns HIDL) because
+// this means that P1 always has a 'waitForResponse' call which can service the
+// returning call and continue the recursion. Of course, with more threads, more
+// complicated calls are possible, but this should do here.
+
+static void callHidl(size_t id, int32_t idx) {
+    auto stuff = IHidlStuff::getService(id2name(id));
+    CHECK(stuff->call(idx).isOk());
+}
+
+static void callAidl(size_t id, int32_t idx) {
+    sp<IAidlStuff> stuff;
+    CHECK(OK == android::getService<IAidlStuff>(String16(id2name(id).c_str()), &stuff));
+    CHECK(stuff->call(idx).isOk());
+}
+
+class HidlServer : public IHidlStuff {
+public:
+    HidlServer(size_t thisId, size_t otherId) : thisId(thisId), otherId(otherId) {}
+    size_t thisId;
+    size_t otherId;
+
+    Return<void> callLocal() {
+        CHECK(BinderCallType::NONE == getCurrentServingCall());
+        return android::hardware::Status::ok();
+    }
+    Return<void> call(int32_t idx) {
+        LOG(INFO) << "HidlServer CALL " << thisId << " to " << otherId << " at idx: " << idx
+                  << " with tid: " << gettid();
+        CHECK(BinderCallType::HWBINDER == getCurrentServingCall());
+        if (idx > 0) {
+            if (thisId == kP1Id && idx % 4 < 2) {
+                callHidl(otherId, idx - 1);
+            } else {
+                callAidl(otherId, idx - 1);
+            }
+        }
+        CHECK(BinderCallType::HWBINDER == getCurrentServingCall());
+        return android::hardware::Status::ok();
+    }
+};
+class AidlServer : public BnAidlStuff {
+public:
+    AidlServer(size_t thisId, size_t otherId) : thisId(thisId), otherId(otherId) {}
+    size_t thisId;
+    size_t otherId;
+
+    Status callLocal() {
+        CHECK(BinderCallType::NONE == getCurrentServingCall());
+        return Status::ok();
+    }
+    Status call(int32_t idx) {
+        LOG(INFO) << "AidlServer CALL " << thisId << " to " << otherId << " at idx: " << idx
+                  << " with tid: " << gettid();
+        CHECK(BinderCallType::BINDER == getCurrentServingCall());
+        if (idx > 0) {
+            if (thisId == kP2Id && idx % 4 < 2) {
+                callHidl(otherId, idx - 1);
+            } else {
+                callAidl(otherId, idx - 1);
+            }
+        }
+        CHECK(BinderCallType::BINDER == getCurrentServingCall());
+        return Status::ok();
+    }
+};
+
+TEST(BinderThreadState, LocalHidlCall) {
+    sp<IHidlStuff> server = new HidlServer(0, 0);
+    EXPECT_TRUE(server->callLocal().isOk());
+}
+
+TEST(BinderThreadState, LocalAidlCall) {
+    sp<IAidlStuff> server = new AidlServer(0, 0);
+    EXPECT_TRUE(server->callLocal().isOk());
+}
+
+TEST(BindThreadState, RemoteHidlCall) {
+    auto stuff = IHidlStuff::getService(id2name(kP1Id));
+    ASSERT_NE(nullptr, stuff);
+    ASSERT_TRUE(stuff->call(0).isOk());
+}
+TEST(BindThreadState, RemoteAidlCall) {
+    sp<IAidlStuff> stuff;
+    ASSERT_EQ(OK, android::getService<IAidlStuff>(String16(id2name(kP1Id).c_str()), &stuff));
+    ASSERT_NE(nullptr, stuff);
+    ASSERT_TRUE(stuff->call(0).isOk());
+}
+
+TEST(BindThreadState, RemoteNestedStartHidlCall) {
+    auto stuff = IHidlStuff::getService(id2name(kP1Id));
+    ASSERT_NE(nullptr, stuff);
+    ASSERT_TRUE(stuff->call(100).isOk());
+}
+TEST(BindThreadState, RemoteNestedStartAidlCall) {
+    sp<IAidlStuff> stuff;
+    ASSERT_EQ(OK, android::getService<IAidlStuff>(String16(id2name(kP1Id).c_str()), &stuff));
+    ASSERT_NE(nullptr, stuff);
+    EXPECT_TRUE(stuff->call(100).isOk());
+}
+
+int server(size_t thisId, size_t otherId) {
+    // AIDL
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    sp<AidlServer> aidlServer = new AidlServer(thisId, otherId);
+    CHECK(OK == defaultServiceManager()->addService(String16(id2name(thisId).c_str()), aidlServer));
+    android::ProcessState::self()->startThreadPool();
+
+    // HIDL
+    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+    android::hardware::configureRpcThreadpool(1, true /*callerWillJoin*/);
+    sp<IHidlStuff> hidlServer = new HidlServer(thisId, otherId);
+    CHECK(OK == hidlServer->registerAsService(id2name(thisId).c_str()));
+    android::hardware::joinRpcThreadpool();
+
+    return EXIT_FAILURE;
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+    if (fork() == 0) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP);
+        return server(kP1Id, kP2Id);
+    }
+    if (fork() == 0) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP);
+        return server(kP2Id, kP1Id);
+    }
+
+    android::waitForService<IAidlStuff>(String16(id2name(kP1Id).c_str()));
+    android::hardware::details::waitForHwService(IHidlStuff::descriptor, id2name(kP1Id).c_str());
+    android::waitForService<IAidlStuff>(String16(id2name(kP2Id).c_str()));
+    android::hardware::details::waitForHwService(IHidlStuff::descriptor, id2name(kP2Id).c_str());
+
+    return RUN_ALL_TESTS();
+}
