Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 1 | /* |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 2 | * Copyright (C) 2022 The Android Open Source Project |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 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 | */ |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 16 | #define LOG_TAG "AidlBufferPoolMgr" |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 17 | //#define LOG_NDEBUG 0 |
| 18 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 19 | #include <aidl/android/hardware/media/bufferpool2/ResultStatus.h> |
| 20 | #include <bufferpool2/ClientManager.h> |
| 21 | |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 22 | #include <sys/types.h> |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 23 | #include <utils/SystemClock.h> |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 24 | #include <unistd.h> |
| 25 | #include <utils/Log.h> |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 26 | |
| 27 | #include <chrono> |
| 28 | |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 29 | #include "BufferPoolClient.h" |
| 30 | #include "Observer.h" |
| 31 | #include "Accessor.h" |
| 32 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 33 | namespace aidl::android::hardware::media::bufferpool2::implementation { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 34 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 35 | using namespace std::chrono_literals; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 36 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 37 | using Registration = aidl::android::hardware::media::bufferpool2::IClientManager::Registration; |
| 38 | using aidl::android::hardware::media::bufferpool2::ResultStatus; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 39 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 40 | static constexpr int64_t kRegisterTimeoutMs = 500; // 0.5 sec |
| 41 | static constexpr int64_t kCleanUpDurationMs = 1000; // TODO: 1 sec tune |
| 42 | static constexpr int64_t kClientTimeoutMs = 5000; // TODO: 5 secs tune |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 43 | |
| 44 | class ClientManager::Impl { |
| 45 | public: |
| 46 | Impl(); |
| 47 | |
| 48 | // BnRegisterSender |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 49 | BufferPoolStatus registerSender(const std::shared_ptr<IAccessor> &accessor, |
| 50 | Registration *pRegistration); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 51 | |
| 52 | // BpRegisterSender |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 53 | BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 54 | ConnectionId senderId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 55 | ConnectionId *receiverId, |
| 56 | bool *isNew); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 57 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 58 | BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 59 | ConnectionId *pConnectionId); |
| 60 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 61 | BufferPoolStatus close(ConnectionId connectionId); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 62 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 63 | BufferPoolStatus flush(ConnectionId connectionId); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 64 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 65 | BufferPoolStatus allocate(ConnectionId connectionId, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 66 | const std::vector<uint8_t> ¶ms, |
| 67 | native_handle_t **handle, |
| 68 | std::shared_ptr<BufferPoolData> *buffer); |
| 69 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 70 | BufferPoolStatus receive(ConnectionId connectionId, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 71 | TransactionId transactionId, |
| 72 | BufferId bufferId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 73 | int64_t timestampMs, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 74 | native_handle_t **handle, |
| 75 | std::shared_ptr<BufferPoolData> *buffer); |
| 76 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 77 | BufferPoolStatus postSend(ConnectionId receiverId, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 78 | const std::shared_ptr<BufferPoolData> &buffer, |
| 79 | TransactionId *transactionId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 80 | int64_t *timestampMs); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 81 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 82 | BufferPoolStatus getAccessor(ConnectionId connectionId, |
| 83 | std::shared_ptr<IAccessor> *accessor); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 84 | |
| 85 | void cleanUp(bool clearCache = false); |
| 86 | |
| 87 | private: |
| 88 | // In order to prevent deadlock between multiple locks, |
| 89 | // always lock ClientCache.lock before locking ActiveClients.lock. |
| 90 | struct ClientCache { |
| 91 | // This lock is held for brief duration. |
| 92 | // Blocking operation is not performed while holding the lock. |
| 93 | std::mutex mMutex; |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 94 | std::list<std::pair<const std::weak_ptr<IAccessor>, const std::weak_ptr<BufferPoolClient>>> |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 95 | mClients; |
| 96 | std::condition_variable mConnectCv; |
| 97 | bool mConnecting; |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 98 | int64_t mLastCleanUpMs; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 99 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 100 | ClientCache() : mConnecting(false), mLastCleanUpMs(::android::elapsedRealtime()) {} |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 101 | } mCache; |
| 102 | |
| 103 | // Active clients which can be retrieved via ConnectionId |
| 104 | struct ActiveClients { |
| 105 | // This lock is held for brief duration. |
| 106 | // Blocking operation is not performed holding the lock. |
| 107 | std::mutex mMutex; |
| 108 | std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>> |
| 109 | mClients; |
| 110 | } mActive; |
| 111 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 112 | std::shared_ptr<Observer> mObserver; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 113 | }; |
| 114 | |
| 115 | ClientManager::Impl::Impl() |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 116 | : mObserver(::ndk::SharedRefBase::make<Observer>()) {} |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 117 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 118 | BufferPoolStatus ClientManager::Impl::registerSender( |
| 119 | const std::shared_ptr<IAccessor> &accessor, Registration *pRegistration) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 120 | cleanUp(); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 121 | int64_t timeoutMs = ::android::elapsedRealtime() + kRegisterTimeoutMs; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 122 | do { |
| 123 | std::unique_lock<std::mutex> lock(mCache.mMutex); |
| 124 | for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 125 | std::shared_ptr<IAccessor> sAccessor = it->first.lock(); |
| 126 | if (sAccessor && sAccessor.get() == accessor.get()) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 127 | const std::shared_ptr<BufferPoolClient> client = it->second.lock(); |
| 128 | if (client) { |
| 129 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 130 | pRegistration->connectionId = client->getConnectionId(); |
| 131 | if (mActive.mClients.find(pRegistration->connectionId) |
| 132 | != mActive.mClients.end()) { |
| 133 | ALOGV("register existing connection %lld", |
| 134 | (long long)pRegistration->connectionId); |
| 135 | pRegistration->isNew = false; |
| 136 | return ResultStatus::OK; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 137 | } |
| 138 | } |
| 139 | mCache.mClients.erase(it); |
| 140 | break; |
| 141 | } |
| 142 | } |
| 143 | if (!mCache.mConnecting) { |
| 144 | mCache.mConnecting = true; |
| 145 | lock.unlock(); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 146 | BufferPoolStatus result = ResultStatus::OK; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 147 | const std::shared_ptr<BufferPoolClient> client = |
| 148 | std::make_shared<BufferPoolClient>(accessor, mObserver); |
| 149 | lock.lock(); |
| 150 | if (!client) { |
| 151 | result = ResultStatus::NO_MEMORY; |
| 152 | } else if (!client->isValid()) { |
| 153 | result = ResultStatus::CRITICAL_ERROR; |
| 154 | } |
| 155 | if (result == ResultStatus::OK) { |
| 156 | // TODO: handle insert fail. (malloc fail) |
| 157 | const std::weak_ptr<BufferPoolClient> wclient = client; |
| 158 | mCache.mClients.push_back(std::make_pair(accessor, wclient)); |
| 159 | ConnectionId conId = client->getConnectionId(); |
| 160 | mObserver->addClient(conId, wclient); |
| 161 | { |
| 162 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 163 | mActive.mClients.insert(std::make_pair(conId, client)); |
| 164 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 165 | pRegistration->connectionId = conId; |
| 166 | pRegistration->isNew = true; |
| 167 | ALOGV("register new connection %lld", (long long)conId); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 168 | } |
| 169 | mCache.mConnecting = false; |
| 170 | lock.unlock(); |
| 171 | mCache.mConnectCv.notify_all(); |
| 172 | return result; |
| 173 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 174 | mCache.mConnectCv.wait_for(lock, kRegisterTimeoutMs*1ms); |
| 175 | } while (::android::elapsedRealtime() < timeoutMs); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 176 | // TODO: return timeout error |
| 177 | return ResultStatus::CRITICAL_ERROR; |
| 178 | } |
| 179 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 180 | BufferPoolStatus ClientManager::Impl::registerSender( |
| 181 | const std::shared_ptr<IClientManager> &receiver, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 182 | ConnectionId senderId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 183 | ConnectionId *receiverId, |
| 184 | bool *isNew) { |
| 185 | std::shared_ptr<IAccessor> accessor; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 186 | bool local = false; |
| 187 | { |
| 188 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 189 | auto it = mActive.mClients.find(senderId); |
| 190 | if (it == mActive.mClients.end()) { |
| 191 | return ResultStatus::NOT_FOUND; |
| 192 | } |
| 193 | it->second->getAccessor(&accessor); |
| 194 | local = it->second->isLocal(); |
| 195 | } |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 196 | if (accessor) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 197 | Registration registration; |
| 198 | ::ndk::ScopedAStatus status = receiver->registerSender(accessor, ®istration); |
| 199 | if (!status.isOk()) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 200 | return ResultStatus::CRITICAL_ERROR; |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 201 | } else if (local) { |
| 202 | std::shared_ptr<ConnectionDeathRecipient> recipient = |
| 203 | Accessor::getConnectionDeathRecipient(); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 204 | if (recipient) { |
| 205 | ALOGV("client death recipient registered %lld", (long long)*receiverId); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 206 | recipient->addCookieToConnection(receiver->asBinder().get(), *receiverId); |
| 207 | AIBinder_linkToDeath(receiver->asBinder().get(), recipient->getRecipient(), |
| 208 | receiver->asBinder().get()); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 209 | } |
| 210 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 211 | *receiverId = registration.connectionId; |
| 212 | *isNew = registration.isNew; |
| 213 | return ResultStatus::OK; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 214 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 215 | return ResultStatus::CRITICAL_ERROR; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 216 | } |
| 217 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 218 | BufferPoolStatus ClientManager::Impl::create( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 219 | const std::shared_ptr<BufferPoolAllocator> &allocator, |
| 220 | ConnectionId *pConnectionId) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 221 | std::shared_ptr<Accessor> accessor = ::ndk::SharedRefBase::make<Accessor>(allocator); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 222 | if (!accessor || !accessor->isValid()) { |
| 223 | return ResultStatus::CRITICAL_ERROR; |
| 224 | } |
| 225 | // TODO: observer is local. use direct call instead of hidl call. |
| 226 | std::shared_ptr<BufferPoolClient> client = |
| 227 | std::make_shared<BufferPoolClient>(accessor, mObserver); |
| 228 | if (!client || !client->isValid()) { |
| 229 | return ResultStatus::CRITICAL_ERROR; |
| 230 | } |
| 231 | // Since a new bufferpool is created, evict memories which are used by |
| 232 | // existing bufferpools and clients. |
| 233 | cleanUp(true); |
| 234 | { |
| 235 | // TODO: handle insert fail. (malloc fail) |
| 236 | std::lock_guard<std::mutex> lock(mCache.mMutex); |
| 237 | const std::weak_ptr<BufferPoolClient> wclient = client; |
| 238 | mCache.mClients.push_back(std::make_pair(accessor, wclient)); |
| 239 | ConnectionId conId = client->getConnectionId(); |
| 240 | mObserver->addClient(conId, wclient); |
| 241 | { |
| 242 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 243 | mActive.mClients.insert(std::make_pair(conId, client)); |
| 244 | } |
| 245 | *pConnectionId = conId; |
| 246 | ALOGV("create new connection %lld", (long long)*pConnectionId); |
| 247 | } |
| 248 | return ResultStatus::OK; |
| 249 | } |
| 250 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 251 | BufferPoolStatus ClientManager::Impl::close(ConnectionId connectionId) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 252 | std::unique_lock<std::mutex> lock1(mCache.mMutex); |
| 253 | std::unique_lock<std::mutex> lock2(mActive.mMutex); |
| 254 | auto it = mActive.mClients.find(connectionId); |
| 255 | if (it != mActive.mClients.end()) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 256 | std::shared_ptr<IAccessor> accessor; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 257 | it->second->getAccessor(&accessor); |
| 258 | std::shared_ptr<BufferPoolClient> closing = it->second; |
| 259 | mActive.mClients.erase(connectionId); |
| 260 | for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) { |
| 261 | // clean up dead client caches |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 262 | std::shared_ptr<IAccessor> cAccessor = cit->first.lock(); |
| 263 | if (!cAccessor || (accessor && cAccessor.get() == accessor.get())) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 264 | cit = mCache.mClients.erase(cit); |
| 265 | } else { |
| 266 | cit++; |
| 267 | } |
| 268 | } |
| 269 | lock2.unlock(); |
| 270 | lock1.unlock(); |
| 271 | closing->flush(); |
| 272 | return ResultStatus::OK; |
| 273 | } |
| 274 | return ResultStatus::NOT_FOUND; |
| 275 | } |
| 276 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 277 | BufferPoolStatus ClientManager::Impl::flush(ConnectionId connectionId) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 278 | std::shared_ptr<BufferPoolClient> client; |
| 279 | { |
| 280 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 281 | auto it = mActive.mClients.find(connectionId); |
| 282 | if (it == mActive.mClients.end()) { |
| 283 | return ResultStatus::NOT_FOUND; |
| 284 | } |
| 285 | client = it->second; |
| 286 | } |
| 287 | return client->flush(); |
| 288 | } |
| 289 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 290 | BufferPoolStatus ClientManager::Impl::allocate( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 291 | ConnectionId connectionId, const std::vector<uint8_t> ¶ms, |
| 292 | native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) { |
| 293 | std::shared_ptr<BufferPoolClient> client; |
| 294 | { |
| 295 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 296 | auto it = mActive.mClients.find(connectionId); |
| 297 | if (it == mActive.mClients.end()) { |
| 298 | return ResultStatus::NOT_FOUND; |
| 299 | } |
| 300 | client = it->second; |
| 301 | } |
| 302 | #ifdef BUFFERPOOL_CLONE_HANDLES |
| 303 | native_handle_t *origHandle; |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 304 | BufferPoolStatus res = client->allocate(params, &origHandle, buffer); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 305 | if (res != ResultStatus::OK) { |
| 306 | return res; |
| 307 | } |
| 308 | *handle = native_handle_clone(origHandle); |
| 309 | if (handle == NULL) { |
| 310 | buffer->reset(); |
| 311 | return ResultStatus::NO_MEMORY; |
| 312 | } |
| 313 | return ResultStatus::OK; |
| 314 | #else |
| 315 | return client->allocate(params, handle, buffer); |
| 316 | #endif |
| 317 | } |
| 318 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 319 | BufferPoolStatus ClientManager::Impl::receive( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 320 | ConnectionId connectionId, TransactionId transactionId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 321 | BufferId bufferId, int64_t timestampMs, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 322 | native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) { |
| 323 | std::shared_ptr<BufferPoolClient> client; |
| 324 | { |
| 325 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 326 | auto it = mActive.mClients.find(connectionId); |
| 327 | if (it == mActive.mClients.end()) { |
| 328 | return ResultStatus::NOT_FOUND; |
| 329 | } |
| 330 | client = it->second; |
| 331 | } |
| 332 | #ifdef BUFFERPOOL_CLONE_HANDLES |
| 333 | native_handle_t *origHandle; |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 334 | BufferPoolStatus res = client->receive( |
| 335 | transactionId, bufferId, timestampMs, &origHandle, buffer); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 336 | if (res != ResultStatus::OK) { |
| 337 | return res; |
| 338 | } |
| 339 | *handle = native_handle_clone(origHandle); |
| 340 | if (handle == NULL) { |
| 341 | buffer->reset(); |
| 342 | return ResultStatus::NO_MEMORY; |
| 343 | } |
| 344 | return ResultStatus::OK; |
| 345 | #else |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 346 | return client->receive(transactionId, bufferId, timestampMs, handle, buffer); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 347 | #endif |
| 348 | } |
| 349 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 350 | BufferPoolStatus ClientManager::Impl::postSend( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 351 | ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 352 | TransactionId *transactionId, int64_t *timestampMs) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 353 | ConnectionId connectionId = buffer->mConnectionId; |
| 354 | std::shared_ptr<BufferPoolClient> client; |
| 355 | { |
| 356 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 357 | auto it = mActive.mClients.find(connectionId); |
| 358 | if (it == mActive.mClients.end()) { |
| 359 | return ResultStatus::NOT_FOUND; |
| 360 | } |
| 361 | client = it->second; |
| 362 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 363 | return client->postSend(receiverId, buffer, transactionId, timestampMs); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 364 | } |
| 365 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 366 | BufferPoolStatus ClientManager::Impl::getAccessor( |
| 367 | ConnectionId connectionId, std::shared_ptr<IAccessor> *accessor) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 368 | std::shared_ptr<BufferPoolClient> client; |
| 369 | { |
| 370 | std::lock_guard<std::mutex> lock(mActive.mMutex); |
| 371 | auto it = mActive.mClients.find(connectionId); |
| 372 | if (it == mActive.mClients.end()) { |
| 373 | return ResultStatus::NOT_FOUND; |
| 374 | } |
| 375 | client = it->second; |
| 376 | } |
| 377 | return client->getAccessor(accessor); |
| 378 | } |
| 379 | |
| 380 | void ClientManager::Impl::cleanUp(bool clearCache) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 381 | int64_t now = ::android::elapsedRealtime(); |
| 382 | int64_t lastTransactionMs; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 383 | std::lock_guard<std::mutex> lock1(mCache.mMutex); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 384 | if (clearCache || mCache.mLastCleanUpMs + kCleanUpDurationMs < now) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 385 | std::lock_guard<std::mutex> lock2(mActive.mMutex); |
| 386 | int cleaned = 0; |
| 387 | for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 388 | if (!it->second->isActive(&lastTransactionMs, clearCache)) { |
| 389 | if (lastTransactionMs + kClientTimeoutMs < now) { |
| 390 | std::shared_ptr<IAccessor> accessor; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 391 | it->second->getAccessor(&accessor); |
| 392 | it = mActive.mClients.erase(it); |
| 393 | ++cleaned; |
| 394 | continue; |
| 395 | } |
| 396 | } |
| 397 | ++it; |
| 398 | } |
| 399 | for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) { |
| 400 | // clean up dead client caches |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 401 | std::shared_ptr<IAccessor> cAccessor = cit->first.lock(); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 402 | if (!cAccessor) { |
| 403 | cit = mCache.mClients.erase(cit); |
| 404 | } else { |
| 405 | ++cit; |
| 406 | } |
| 407 | } |
| 408 | ALOGV("# of cleaned connections: %d", cleaned); |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 409 | mCache.mLastCleanUpMs = now; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 410 | } |
| 411 | } |
| 412 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 413 | ::ndk::ScopedAStatus ClientManager::registerSender( |
| 414 | const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) { |
| 415 | BufferPoolStatus status = ResultStatus::CRITICAL_ERROR; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 416 | if (mImpl) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 417 | status = mImpl->registerSender(in_bufferPool, _aidl_return); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 418 | } |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 419 | if (status != ResultStatus::OK) { |
| 420 | return ::ndk::ScopedAStatus::fromServiceSpecificError(status); |
| 421 | } |
| 422 | return ::ndk::ScopedAStatus::ok(); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 423 | } |
| 424 | |
Sungtak Lee | ae00908 | 2024-01-17 21:35:23 +0000 | [diff] [blame] | 425 | ::ndk::ScopedAStatus ClientManager::registerPassiveSender( |
| 426 | const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) { |
| 427 | // TODO |
| 428 | (void) in_bufferPool; |
| 429 | (void) _aidl_return; |
| 430 | return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::NOT_FOUND); |
| 431 | } |
| 432 | |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 433 | // Methods for local use. |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 434 | std::shared_ptr<ClientManager> ClientManager::sInstance; |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 435 | std::mutex ClientManager::sInstanceLock; |
| 436 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 437 | std::shared_ptr<ClientManager> ClientManager::getInstance() { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 438 | std::lock_guard<std::mutex> lock(sInstanceLock); |
| 439 | if (!sInstance) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 440 | sInstance = ::ndk::SharedRefBase::make<ClientManager>(); |
| 441 | // TODO: configure thread count for threadpool properly |
| 442 | // after b/261652496 is resolved. |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 443 | } |
| 444 | Accessor::createInvalidator(); |
| 445 | Accessor::createEvictor(); |
| 446 | return sInstance; |
| 447 | } |
| 448 | |
| 449 | ClientManager::ClientManager() : mImpl(new Impl()) {} |
| 450 | |
| 451 | ClientManager::~ClientManager() { |
| 452 | } |
| 453 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 454 | BufferPoolStatus ClientManager::create( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 455 | const std::shared_ptr<BufferPoolAllocator> &allocator, |
| 456 | ConnectionId *pConnectionId) { |
| 457 | if (mImpl) { |
| 458 | return mImpl->create(allocator, pConnectionId); |
| 459 | } |
| 460 | return ResultStatus::CRITICAL_ERROR; |
| 461 | } |
| 462 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 463 | BufferPoolStatus ClientManager::registerSender( |
| 464 | const std::shared_ptr<IClientManager> &receiver, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 465 | ConnectionId senderId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 466 | ConnectionId *receiverId, |
| 467 | bool *isNew) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 468 | if (mImpl) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 469 | return mImpl->registerSender(receiver, senderId, receiverId, isNew); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 470 | } |
| 471 | return ResultStatus::CRITICAL_ERROR; |
| 472 | } |
| 473 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 474 | BufferPoolStatus ClientManager::close(ConnectionId connectionId) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 475 | if (mImpl) { |
| 476 | return mImpl->close(connectionId); |
| 477 | } |
| 478 | return ResultStatus::CRITICAL_ERROR; |
| 479 | } |
| 480 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 481 | BufferPoolStatus ClientManager::flush(ConnectionId connectionId) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 482 | if (mImpl) { |
| 483 | return mImpl->flush(connectionId); |
| 484 | } |
| 485 | return ResultStatus::CRITICAL_ERROR; |
| 486 | } |
| 487 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 488 | BufferPoolStatus ClientManager::allocate( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 489 | ConnectionId connectionId, const std::vector<uint8_t> ¶ms, |
| 490 | native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) { |
| 491 | if (mImpl) { |
| 492 | return mImpl->allocate(connectionId, params, handle, buffer); |
| 493 | } |
| 494 | return ResultStatus::CRITICAL_ERROR; |
| 495 | } |
| 496 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 497 | BufferPoolStatus ClientManager::receive( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 498 | ConnectionId connectionId, TransactionId transactionId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 499 | BufferId bufferId, int64_t timestampMs, |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 500 | native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) { |
| 501 | if (mImpl) { |
| 502 | return mImpl->receive(connectionId, transactionId, bufferId, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 503 | timestampMs, handle, buffer); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 504 | } |
| 505 | return ResultStatus::CRITICAL_ERROR; |
| 506 | } |
| 507 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 508 | BufferPoolStatus ClientManager::postSend( |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 509 | ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer, |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 510 | TransactionId *transactionId, int64_t* timestampMs) { |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 511 | if (mImpl && buffer) { |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 512 | return mImpl->postSend(receiverId, buffer, transactionId, timestampMs); |
Sungtak Lee | 97e1dfb | 2022-12-07 07:45:45 +0000 | [diff] [blame] | 513 | } |
| 514 | return ResultStatus::CRITICAL_ERROR; |
| 515 | } |
| 516 | |
| 517 | void ClientManager::cleanUp() { |
| 518 | if (mImpl) { |
| 519 | mImpl->cleanUp(true); |
| 520 | } |
| 521 | } |
| 522 | |
Sungtak Lee | 8878a13 | 2022-12-07 11:42:03 +0000 | [diff] [blame] | 523 | } // namespace ::aidl::android::hardware::media::bufferpool2::implementation |