diff options
-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(); |