1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <hidl/HidlTransportSupport.h> 17 18 #include <hidl/HidlBinderSupport.h> 19 #include "InternalStatic.h" 20 21 #include <android-base/logging.h> 22 #include <android/hidl/manager/1.0/IServiceManager.h> 23 24 #include <linux/sched.h> 25 26 namespace android { 27 namespace hardware { 28 29 using ::android::hidl::base::V1_0::IBase; 30 31 void configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) { 32 // TODO(b/32756130) this should be transport-dependent 33 configureBinderRpcThreadpool(maxThreads, callerWillJoin); 34 } 35 void joinRpcThreadpool() { 36 // TODO(b/32756130) this should be transport-dependent 37 joinBinderRpcThreadpool(); 38 } 39 40 int setupTransportPolling() { 41 return setupBinderPolling(); 42 } 43 44 status_t handleTransportPoll(int /*fd*/) { 45 return handleBinderPoll(); 46 } 47 48 // TODO(b/122472540): only store one data item per object 49 template <typename V> 50 static void pruneMapLocked(ConcurrentMap<wp<IBase>, V>& map) { 51 std::vector<wp<IBase>> toDelete; 52 for (const auto& kv : map) { 53 if (kv.first.promote() == nullptr) { 54 toDelete.push_back(kv.first); 55 } 56 } 57 for (const auto& k : toDelete) { 58 map.eraseLocked(k); 59 } 60 } 61 62 bool setMinSchedulerPolicy(const sp<IBase>& service, int policy, int priority) { 63 if (service->isRemote()) { 64 LOG(ERROR) << "Can't set scheduler policy on remote service."; 65 return false; 66 } 67 68 switch (policy) { 69 case SCHED_NORMAL: { 70 if (priority < -20 || priority > 19) { 71 LOG(ERROR) << "Invalid priority for SCHED_NORMAL: " << priority; 72 return false; 73 } 74 } break; 75 case SCHED_RR: 76 case SCHED_FIFO: { 77 if (priority < 1 || priority > 99) { 78 LOG(ERROR) << "Invalid priority for " << policy << " policy: " << priority; 79 return false; 80 } 81 } break; 82 default: { 83 LOG(ERROR) << "Invalid scheduler policy " << policy; 84 return false; 85 } 86 } 87 88 // Due to ABI considerations, IBase cannot have a destructor to clean this up. 89 // So, because this API is so infrequently used, (expected to be usually only 90 // one time for a process, but it can be more), we are cleaning it up here. 91 std::unique_lock<std::mutex> lock = details::gServicePrioMap->lock(); 92 pruneMapLocked(details::gServicePrioMap.get()); 93 details::gServicePrioMap->setLocked(service, {policy, priority}); 94 95 return true; 96 } 97 98 SchedPrio getMinSchedulerPolicy(const sp<IBase>& service) { 99 return details::gServicePrioMap->get(service, {SCHED_NORMAL, 0}); 100 } 101 102 bool setRequestingSid(const sp<IBase>& service, bool requesting) { 103 if (service->isRemote()) { 104 LOG(ERROR) << "Can't set requesting sid on remote service."; 105 return false; 106 } 107 108 // Due to ABI considerations, IBase cannot have a destructor to clean this up. 109 // So, because this API is so infrequently used, (expected to be usually only 110 // one time for a process, but it can be more), we are cleaning it up here. 111 std::unique_lock<std::mutex> lock = details::gServiceSidMap->lock(); 112 pruneMapLocked(details::gServiceSidMap.get()); 113 details::gServiceSidMap->setLocked(service, requesting); 114 115 return true; 116 } 117 118 bool getRequestingSid(const sp<IBase>& service) { 119 return details::gServiceSidMap->get(service.get(), false); 120 } 121 122 bool interfacesEqual(const sp<IBase>& left, const sp<IBase>& right) { 123 if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) { 124 return left == right; 125 } 126 return getOrCreateCachedBinder(left.get()) == getOrCreateCachedBinder(right.get()); 127 } 128 129 namespace details { 130 int32_t getPidIfSharable() { 131 #if LIBHIDL_TARGET_DEBUGGABLE 132 return getpid(); 133 #else 134 using android::hidl::manager::V1_0::IServiceManager; 135 return static_cast<int32_t>(IServiceManager::PidConstant::NO_PID); 136 #endif 137 } 138 } // namespace details 139 140 } // namespace hardware 141 } // namespace android 142