/* * Copyright (C) 2017 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 <hidl/HidlBinderSupport.h> #include <hidl/HidlTransportSupport.h> #include <hidl/Static.h> #include <android-base/logging.h> #include <android/hidl/manager/1.0/IServiceManager.h> namespace android { namespace hardware { using ::android::hidl::base::V1_0::IBase; void configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) { // TODO(b/32756130) this should be transport-dependent configureBinderRpcThreadpool(maxThreads, callerWillJoin); } void joinRpcThreadpool() { // TODO(b/32756130) this should be transport-dependent joinBinderRpcThreadpool(); } int setupTransportPolling() { return setupBinderPolling(); } status_t handleTransportPoll(int /*fd*/) { return handleBinderPoll(); } // TODO(b/122472540): only store one data item per object template <typename V> static void pruneMapLocked(ConcurrentMap<wp<IBase>, V>& map) { std::vector<wp<IBase>> toDelete; for (const auto& kv : map) { if (kv.first.promote() == nullptr) { toDelete.push_back(kv.first); } } for (const auto& k : toDelete) { map.eraseLocked(k); } } bool setMinSchedulerPolicy(const sp<IBase>& service, int policy, int priority) { if (service->isRemote()) { LOG(ERROR) << "Can't set scheduler policy on remote service."; return false; } switch (policy) { case SCHED_NORMAL: { if (priority < -20 || priority > 19) { LOG(ERROR) << "Invalid priority for SCHED_NORMAL: " << priority; return false; } } break; case SCHED_RR: case SCHED_FIFO: { if (priority < 1 || priority > 99) { LOG(ERROR) << "Invalid priority for " << policy << " policy: " << priority; return false; } } break; default: { LOG(ERROR) << "Invalid scheduler policy " << policy; return false; } } // Due to ABI considerations, IBase cannot have a destructor to clean this up. // So, because this API is so infrequently used, (expected to be usually only // one time for a process, but it can be more), we are cleaning it up here. std::unique_lock<std::mutex> lock = details::gServicePrioMap->lock(); pruneMapLocked(details::gServicePrioMap.get()); details::gServicePrioMap->setLocked(service, {policy, priority}); return true; } bool setRequestingSid(const sp<IBase>& service, bool requesting) { if (service->isRemote()) { LOG(ERROR) << "Can't set requesting sid on remote service."; return false; } // Due to ABI considerations, IBase cannot have a destructor to clean this up. // So, because this API is so infrequently used, (expected to be usually only // one time for a process, but it can be more), we are cleaning it up here. std::unique_lock<std::mutex> lock = details::gServiceSidMap->lock(); pruneMapLocked(details::gServiceSidMap.get()); details::gServiceSidMap->setLocked(service, requesting); return true; } bool interfacesEqual(const sp<IBase>& left, const sp<IBase>& right) { if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) { return left == right; } return getOrCreateCachedBinder(left.get()) == getOrCreateCachedBinder(right.get()); } namespace details { int32_t getPidIfSharable() { #if LIBHIDL_TARGET_DEBUGGABLE return getpid(); #else using android::hidl::manager::V1_0::IServiceManager; return static_cast<int32_t>(IServiceManager::PidConstant::NO_PID); #endif } } // namespace details } // namespace hardware } // namespace android