diff options
author | 2020-01-31 14:56:45 -0800 | |
---|---|---|
committer | 2020-02-05 10:15:39 -0800 | |
commit | 39d887d308c0430a5046d7dfaec87dfaaea1a7aa (patch) | |
tree | ec5075cd89a63c7f73cfafe411bd0d2c1289406e | |
parent | c02c9230ea8ac7cd9916053f6d49075989c1260a (diff) |
Remove need for libbinderthreadstate.
Instead of having this library, libbinder/libhwbinder can keep track of
stack pointers so that when they recurse, we know which one was visited
most recently.
As with the original implementation of libbinderthreadstate, this is
somewhat of a hack. An explanation of why this is and what to do instead
is added in CallerUtils.h.
Bug: 148692216
Test: libbinderthreadstateutils_test
Change-Id: Ief28663728fb8786b06bf9e72238052b9af81d87
Merged-In: Ief28663728fb8786b06bf9e72238052b9af81d87
-rw-r--r-- | PREUPLOAD.cfg | 1 | ||||
-rw-r--r-- | libs/binder/Android.bp | 1 | ||||
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 15 | ||||
-rw-r--r-- | libs/binder/TEST_MAPPING | 3 | ||||
-rw-r--r-- | libs/binder/include/binder/IPCThreadState.h | 33 | ||||
-rw-r--r-- | libs/binderthreadstate/1.0/Android.bp | 14 | ||||
-rw-r--r-- | libs/binderthreadstate/1.0/IHidlStuff.hal | 22 | ||||
-rw-r--r-- | libs/binderthreadstate/Android.bp | 73 | ||||
-rw-r--r-- | libs/binderthreadstate/IAidlStuff.aidl | 21 | ||||
-rw-r--r-- | libs/binderthreadstate/IPCThreadStateBase.cpp | 89 | ||||
-rw-r--r-- | libs/binderthreadstate/TEST_MAPPING | 7 | ||||
-rw-r--r-- | libs/binderthreadstate/include/binderthreadstate/CallerUtils.h | 50 | ||||
-rw-r--r-- | libs/binderthreadstate/include/binderthreadstate/IPCThreadStateBase.h | 44 | ||||
-rw-r--r-- | libs/binderthreadstate/test.cpp | 195 | ||||
-rw-r--r-- | libs/gui/Android.bp | 4 | ||||
-rw-r--r-- | libs/gui/BufferQueueThreadState.cpp | 5 |
16 files changed, 384 insertions, 193 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index db297a0a2e..e048a19145 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -7,6 +7,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp cmds/idlcli/ include/input/ libs/binder/ndk/ + libs/binderthreadstate/ libs/graphicsenv/ libs/gui/ libs/input/ diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index 1ee385334e..5f9d4004f4 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -138,7 +138,6 @@ cc_library { "liblog", "libcutils", "libutils", - "libbinderthreadstate", ], header_libs: [ diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 4981d7a111..4dcd07a776 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "IPCThreadState" #include <binder/IPCThreadState.h> -#include <binderthreadstate/IPCThreadStateBase.h> #include <binder/Binder.h> #include <binder/BpBinder.h> @@ -803,6 +802,7 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy) IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), + mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mStrictModePolicy(0), @@ -813,7 +813,6 @@ IPCThreadState::IPCThreadState() clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); - mIPCThreadStateBase = IPCThreadStateBase::self(); } IPCThreadState::~IPCThreadState() @@ -1163,9 +1162,6 @@ status_t IPCThreadState::executeCommand(int32_t cmd) "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; - //Record the fact that we're in a binder call. - mIPCThreadStateBase->pushCurrentState( - IPCThreadStateBase::CallState::BINDER); Parcel buffer; buffer.ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), @@ -1173,6 +1169,9 @@ status_t IPCThreadState::executeCommand(int32_t cmd) reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), freeBuffer, this); + const void* origServingStackPointer = mServingStackPointer; + mServingStackPointer = &origServingStackPointer; // anything on the stack + const pid_t origPid = mCallingPid; const char* origSid = mCallingSid; const uid_t origUid = mCallingUid; @@ -1223,7 +1222,6 @@ status_t IPCThreadState::executeCommand(int32_t cmd) error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } - mIPCThreadStateBase->popCurrentState(); //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n", // mCallingPid, origPid, (origSid ? origSid : "<N/A>"), origUid); @@ -1235,6 +1233,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); } + mServingStackPointer = origServingStackPointer; mCallingPid = origPid; mCallingSid = origSid; mCallingUid = origUid; @@ -1290,8 +1289,8 @@ status_t IPCThreadState::executeCommand(int32_t cmd) return result; } -bool IPCThreadState::isServingCall() const { - return mIPCThreadStateBase->getCurrentBinderCallState() == IPCThreadStateBase::CallState::BINDER; +const void* IPCThreadState::getServingStackPointer() const { + return mServingStackPointer; } void IPCThreadState::threadDestructor(void *st) diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING index 7489afae29..9aa76512c8 100644 --- a/libs/binder/TEST_MAPPING +++ b/libs/binder/TEST_MAPPING @@ -26,6 +26,9 @@ }, { "name": "aidl_lazy_test" + }, + { + "name": "libbinderthreadstateutils_test" } ] } diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index ff9244e08a..4818889436 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -29,8 +29,6 @@ typedef int uid_t; // --------------------------------------------------------------------------- namespace android { -class IPCThreadStateBase; - class IPCThreadState { public: @@ -113,31 +111,12 @@ public: // Service manager registration void setTheContextObject(sp<BBinder> obj); - // Is this thread currently serving a binder call. This method - // returns true if while traversing backwards from the function call - // stack for this thread, we encounter a function serving a binder - // call before encountering a hwbinder call / hitting the end of the - // call stack. - // Eg: If thread T1 went through the following call pattern - // 1) T1 receives and executes hwbinder call H1. - // 2) While handling H1, T1 makes binder call B1. - // 3) The handler of B1, calls into T1 with a callback B2. - // If isServingCall() is called during H1 before 3), this method - // will return false, else true. - // - // ---- - // | B2 | ---> While callback B2 is being handled, during 3). - // ---- - // | H1 | ---> While H1 is being handled. - // ---- - // Fig: Thread Call stack while handling B2 + // WARNING: DO NOT USE THIS API // - // This is since after 3), while traversing the thread call stack, - // we hit a binder call before a hwbinder call / end of stack. This - // method may be typically used to determine whether to use - // hardware::IPCThreadState methods or IPCThreadState methods to - // infer information about thread state. - bool isServingCall() const; + // Returns a pointer to the stack from the last time a transaction + // was initiated by the kernel. Used to compare when making nested + // calls between multiple different transports. + const void* getServingStackPointer() const; // The work source represents the UID of the process we should attribute the transaction // to. We use -1 to specify that the work source was not set using #setWorkSource. @@ -181,6 +160,7 @@ private: Parcel mIn; Parcel mOut; status_t mLastError; + const void* mServingStackPointer; pid_t mCallingPid; const char* mCallingSid; uid_t mCallingUid; @@ -191,7 +171,6 @@ private: bool mPropagateWorkSource; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; - IPCThreadStateBase *mIPCThreadStateBase; ProcessState::CallRestriction mCallRestriction; }; diff --git a/libs/binderthreadstate/1.0/Android.bp b/libs/binderthreadstate/1.0/Android.bp new file mode 100644 index 0000000000..ebdc932591 --- /dev/null +++ b/libs/binderthreadstate/1.0/Android.bp @@ -0,0 +1,14 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "binderthreadstateutilstest@1.0", + root: "binderthreadstateutilstest", + system_ext_specific: true, + srcs: [ + "IHidlStuff.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/libs/binderthreadstate/1.0/IHidlStuff.hal b/libs/binderthreadstate/1.0/IHidlStuff.hal new file mode 100644 index 0000000000..ffb64998ce --- /dev/null +++ b/libs/binderthreadstate/1.0/IHidlStuff.hal @@ -0,0 +1,22 @@ +/* + * 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. + */ + +package binderthreadstateutilstest@1.0; + +interface IHidlStuff { + callLocal(); + call(int32_t idx); +}; diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp index ee1a6a4860..4655e1d8f4 100644 --- a/libs/binderthreadstate/Android.bp +++ b/libs/binderthreadstate/Android.bp @@ -12,37 +12,66 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_library { - name: "libbinderthreadstate", - recovery_available: true, - vendor_available: false, - vndk: { - enabled: true, - support_system_process: true, - }, +// DO NOT ADD NEW USAGES OF THIS +// See comments in header file. +cc_library_static { + name: "libbinderthreadstateutils", + double_loadable: true, + vendor_available: true, host_supported: true, - srcs: [ - "IPCThreadStateBase.cpp", - ], - - header_libs: [ - "libbase_headers", - "libutils_headers", - ], - shared_libs: [ - "liblog", + "libbinder", + "libhidlbase", // libhwbinder is in here ], export_include_dirs: ["include"], - sanitize: { - misc_undefined: ["integer"], - }, - cflags: [ "-Wall", "-Werror", ], } + +hidl_package_root { + name: "binderthreadstateutilstest", +} + +aidl_interface { + name: "binderthreadstateutilstest.aidl", + srcs: ["IAidlStuff.aidl"], +} + +cc_test { + name: "libbinderthreadstateutils_test", + srcs: ["test.cpp"], + static_libs: [ + "binderthreadstateutilstest@1.0", + "binderthreadstateutilstest.aidl-cpp", + "libbinderthreadstateutils", + ], + shared_libs: [ + "libbase", + "libbinder", + "libcutils", + "libhidlbase", + "libutils", + "liblog", + ], + test_suites: [ + "general-tests", + ], + require_root: true, +} + +// TODO(b/148692216): remove empty lib +cc_library { + name: "libbinderthreadstate", + recovery_available: true, + vendor_available: false, + vndk: { + enabled: true, + support_system_process: true, + }, + host_supported: true, +} diff --git a/libs/binderthreadstate/IAidlStuff.aidl b/libs/binderthreadstate/IAidlStuff.aidl new file mode 100644 index 0000000000..0c81c42a79 --- /dev/null +++ b/libs/binderthreadstate/IAidlStuff.aidl @@ -0,0 +1,21 @@ +/* + * 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. + */ + + +interface IAidlStuff { + void callLocal(); + void call(int idx); +} diff --git a/libs/binderthreadstate/IPCThreadStateBase.cpp b/libs/binderthreadstate/IPCThreadStateBase.cpp deleted file mode 100644 index fede151774..0000000000 --- a/libs/binderthreadstate/IPCThreadStateBase.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "IPCThreadStateBase" - -#include <binderthreadstate/IPCThreadStateBase.h> -#include <android-base/macros.h> - -#include <utils/Log.h> - -#include <errno.h> -#include <inttypes.h> -#include <pthread.h> - -namespace android { - -static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; -static bool gHaveTLS = false; -static pthread_key_t gTLS = 0; - -IPCThreadStateBase::IPCThreadStateBase() { - pthread_setspecific(gTLS, this); -} - -IPCThreadStateBase* IPCThreadStateBase::self() -{ - if (gHaveTLS) { -restart: - const pthread_key_t k = gTLS; - IPCThreadStateBase* st = (IPCThreadStateBase*)pthread_getspecific(k); - if (st) return st; - return new IPCThreadStateBase; - } - - pthread_mutex_lock(&gTLSMutex); - if (!gHaveTLS) { - int key_create_value = pthread_key_create(&gTLS, threadDestructor); - if (key_create_value != 0) { - pthread_mutex_unlock(&gTLSMutex); - ALOGW("IPCThreadStateBase::self() unable to create TLS key, expect a crash: %s\n", - strerror(key_create_value)); - return nullptr; - } - gHaveTLS = true; - } - pthread_mutex_unlock(&gTLSMutex); - goto restart; -} - -void IPCThreadStateBase::pushCurrentState(CallState callState) { - mCallStateStack.emplace(callState); -} - -IPCThreadStateBase::CallState IPCThreadStateBase::popCurrentState() { - ALOG_ASSERT(mCallStateStack.size > 0); - CallState val = mCallStateStack.top(); - mCallStateStack.pop(); - return val; -} - -IPCThreadStateBase::CallState IPCThreadStateBase::getCurrentBinderCallState() { - if (mCallStateStack.size() > 0) { - return mCallStateStack.top(); - } - return CallState::NONE; -} - -void IPCThreadStateBase::threadDestructor(void *st) -{ - IPCThreadStateBase* const self = static_cast<IPCThreadStateBase*>(st); - if (self) { - delete self; - } -} - -}; // namespace android diff --git a/libs/binderthreadstate/TEST_MAPPING b/libs/binderthreadstate/TEST_MAPPING new file mode 100644 index 0000000000..2bd046339f --- /dev/null +++ b/libs/binderthreadstate/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "libbinderthreadstateutils_test" + } + ] +} diff --git a/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h b/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h new file mode 100644 index 0000000000..a3e5026a07 --- /dev/null +++ b/libs/binderthreadstate/include/binderthreadstate/CallerUtils.h @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#pragma once + +// WARNING: DO NOT USE THIS +// You should: +// - have code know how it is handling things. Pass in caller information rather +// than assuming that code is running in a specific global context +// - use AIDL exclusively in your stack (HIDL is no longer required anywhere) + +#include <binder/IPCThreadState.h> +#include <hwbinder/IPCThreadState.h> + +namespace android { + +enum class BinderCallType { + NONE, + BINDER, + HWBINDER, +}; + +// Based on where we are in recursion of nested binder/hwbinder calls, determine +// which one we are closer to. +inline static BinderCallType getCurrentServingCall() { + const void* hwbinderSp = android::hardware::IPCThreadState::self()->getServingStackPointer(); + const void* binderSp = android::IPCThreadState::self()->getServingStackPointer(); + + if (hwbinderSp == nullptr && binderSp == nullptr) return BinderCallType::NONE; + if (hwbinderSp == nullptr) return BinderCallType::BINDER; + if (binderSp == nullptr) return BinderCallType::HWBINDER; + + if (hwbinderSp < binderSp) return BinderCallType::HWBINDER; + return BinderCallType::BINDER; +} + +} // namespace android diff --git a/libs/binderthreadstate/include/binderthreadstate/IPCThreadStateBase.h b/libs/binderthreadstate/include/binderthreadstate/IPCThreadStateBase.h deleted file mode 100644 index 6fdcc84054..0000000000 --- a/libs/binderthreadstate/include/binderthreadstate/IPCThreadStateBase.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef BINDER_THREADSTATE_IPC_THREADSTATE_BASE_H -#define BINDER_THREADSTATE_IPC_THREADSTATE_BASE_H - -#include <stack> -namespace android { - -class IPCThreadStateBase { -public: - enum CallState { - HWBINDER, - BINDER, - NONE, - }; - static IPCThreadStateBase* self(); - void pushCurrentState(CallState callState); - CallState popCurrentState(); - CallState getCurrentBinderCallState(); - -private: - IPCThreadStateBase(); - static void threadDestructor(void *st); - - std::stack<CallState> mCallStateStack; -}; - -}; // namespace android - -#endif // BINDER_THREADSTATE_IPC_THREADSTATE_BASE_H diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp new file mode 100644 index 0000000000..68cc225057 --- /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(); +} diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 166775b89a..ba3195a38e 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -186,6 +186,10 @@ cc_defaults { "libvndksupport", ], + static_libs: [ + "libbinderthreadstateutils", + ], + header_libs: [ "libgui_headers", "libnativebase_headers", diff --git a/libs/gui/BufferQueueThreadState.cpp b/libs/gui/BufferQueueThreadState.cpp index 3b531ec752..c13030b1ed 100644 --- a/libs/gui/BufferQueueThreadState.cpp +++ b/libs/gui/BufferQueueThreadState.cpp @@ -15,6 +15,7 @@ */ #include <binder/IPCThreadState.h> +#include <binderthreadstate/CallerUtils.h> #include <hwbinder/IPCThreadState.h> #include <private/gui/BufferQueueThreadState.h> #include <unistd.h> @@ -22,14 +23,14 @@ namespace android { uid_t BufferQueueThreadState::getCallingUid() { - if (hardware::IPCThreadState::self()->isServingCall()) { + if (getCurrentServingCall() == BinderCallType::HWBINDER) { return hardware::IPCThreadState::self()->getCallingUid(); } return IPCThreadState::self()->getCallingUid(); } pid_t BufferQueueThreadState::getCallingPid() { - if (hardware::IPCThreadState::self()->isServingCall()) { + if (getCurrentServingCall() == BinderCallType::HWBINDER) { return hardware::IPCThreadState::self()->getCallingPid(); } return IPCThreadState::self()->getCallingPid(); |