blob: 138790d650d25ecb75f92ff4ac19fbfaf59d1858 [file] [log] [blame]
Sungtak Lee97e1dfb2022-12-07 07:45:45 +00001/*
Sungtak Lee8878a132022-12-07 11:42:03 +00002 * Copyright (C) 2022 The Android Open Source Project
Sungtak Lee97e1dfb2022-12-07 07:45:45 +00003 *
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 Lee8878a132022-12-07 11:42:03 +000016#define LOG_TAG "AidlBufferPoolMgr"
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000017//#define LOG_NDEBUG 0
18
Sungtak Lee8878a132022-12-07 11:42:03 +000019#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
20#include <bufferpool2/ClientManager.h>
21
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000022#include <sys/types.h>
Sungtak Lee8878a132022-12-07 11:42:03 +000023#include <utils/SystemClock.h>
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000024#include <unistd.h>
25#include <utils/Log.h>
Sungtak Lee8878a132022-12-07 11:42:03 +000026
27#include <chrono>
28
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000029#include "BufferPoolClient.h"
30#include "Observer.h"
31#include "Accessor.h"
32
Sungtak Lee8878a132022-12-07 11:42:03 +000033namespace aidl::android::hardware::media::bufferpool2::implementation {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000034
Sungtak Lee8878a132022-12-07 11:42:03 +000035using namespace std::chrono_literals;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000036
Sungtak Lee8878a132022-12-07 11:42:03 +000037using Registration = aidl::android::hardware::media::bufferpool2::IClientManager::Registration;
38using aidl::android::hardware::media::bufferpool2::ResultStatus;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000039
Sungtak Lee8878a132022-12-07 11:42:03 +000040static constexpr int64_t kRegisterTimeoutMs = 500; // 0.5 sec
41static constexpr int64_t kCleanUpDurationMs = 1000; // TODO: 1 sec tune
42static constexpr int64_t kClientTimeoutMs = 5000; // TODO: 5 secs tune
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000043
44class ClientManager::Impl {
45public:
46 Impl();
47
48 // BnRegisterSender
Sungtak Lee8878a132022-12-07 11:42:03 +000049 BufferPoolStatus registerSender(const std::shared_ptr<IAccessor> &accessor,
50 Registration *pRegistration);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000051
52 // BpRegisterSender
Sungtak Lee8878a132022-12-07 11:42:03 +000053 BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000054 ConnectionId senderId,
Sungtak Lee8878a132022-12-07 11:42:03 +000055 ConnectionId *receiverId,
56 bool *isNew);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000057
Sungtak Lee8878a132022-12-07 11:42:03 +000058 BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000059 ConnectionId *pConnectionId);
60
Sungtak Lee8878a132022-12-07 11:42:03 +000061 BufferPoolStatus close(ConnectionId connectionId);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000062
Sungtak Lee8878a132022-12-07 11:42:03 +000063 BufferPoolStatus flush(ConnectionId connectionId);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000064
Sungtak Lee8878a132022-12-07 11:42:03 +000065 BufferPoolStatus allocate(ConnectionId connectionId,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000066 const std::vector<uint8_t> &params,
67 native_handle_t **handle,
68 std::shared_ptr<BufferPoolData> *buffer);
69
Sungtak Lee8878a132022-12-07 11:42:03 +000070 BufferPoolStatus receive(ConnectionId connectionId,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000071 TransactionId transactionId,
72 BufferId bufferId,
Sungtak Lee8878a132022-12-07 11:42:03 +000073 int64_t timestampMs,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000074 native_handle_t **handle,
75 std::shared_ptr<BufferPoolData> *buffer);
76
Sungtak Lee8878a132022-12-07 11:42:03 +000077 BufferPoolStatus postSend(ConnectionId receiverId,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000078 const std::shared_ptr<BufferPoolData> &buffer,
79 TransactionId *transactionId,
Sungtak Lee8878a132022-12-07 11:42:03 +000080 int64_t *timestampMs);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000081
Sungtak Lee8878a132022-12-07 11:42:03 +000082 BufferPoolStatus getAccessor(ConnectionId connectionId,
83 std::shared_ptr<IAccessor> *accessor);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000084
85 void cleanUp(bool clearCache = false);
86
87private:
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 Lee8878a132022-12-07 11:42:03 +000094 std::list<std::pair<const std::weak_ptr<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000095 mClients;
96 std::condition_variable mConnectCv;
97 bool mConnecting;
Sungtak Lee8878a132022-12-07 11:42:03 +000098 int64_t mLastCleanUpMs;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000099
Sungtak Lee8878a132022-12-07 11:42:03 +0000100 ClientCache() : mConnecting(false), mLastCleanUpMs(::android::elapsedRealtime()) {}
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000101 } 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 Lee8878a132022-12-07 11:42:03 +0000112 std::shared_ptr<Observer> mObserver;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000113};
114
115ClientManager::Impl::Impl()
Sungtak Lee8878a132022-12-07 11:42:03 +0000116 : mObserver(::ndk::SharedRefBase::make<Observer>()) {}
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000117
Sungtak Lee8878a132022-12-07 11:42:03 +0000118BufferPoolStatus ClientManager::Impl::registerSender(
119 const std::shared_ptr<IAccessor> &accessor, Registration *pRegistration) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000120 cleanUp();
Sungtak Lee8878a132022-12-07 11:42:03 +0000121 int64_t timeoutMs = ::android::elapsedRealtime() + kRegisterTimeoutMs;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000122 do {
123 std::unique_lock<std::mutex> lock(mCache.mMutex);
124 for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000125 std::shared_ptr<IAccessor> sAccessor = it->first.lock();
126 if (sAccessor && sAccessor.get() == accessor.get()) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000127 const std::shared_ptr<BufferPoolClient> client = it->second.lock();
128 if (client) {
129 std::lock_guard<std::mutex> lock(mActive.mMutex);
Sungtak Lee8878a132022-12-07 11:42:03 +0000130 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 Lee97e1dfb2022-12-07 07:45:45 +0000137 }
138 }
139 mCache.mClients.erase(it);
140 break;
141 }
142 }
143 if (!mCache.mConnecting) {
144 mCache.mConnecting = true;
145 lock.unlock();
Sungtak Lee8878a132022-12-07 11:42:03 +0000146 BufferPoolStatus result = ResultStatus::OK;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000147 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 Lee8878a132022-12-07 11:42:03 +0000165 pRegistration->connectionId = conId;
166 pRegistration->isNew = true;
167 ALOGV("register new connection %lld", (long long)conId);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000168 }
169 mCache.mConnecting = false;
170 lock.unlock();
171 mCache.mConnectCv.notify_all();
172 return result;
173 }
Sungtak Lee8878a132022-12-07 11:42:03 +0000174 mCache.mConnectCv.wait_for(lock, kRegisterTimeoutMs*1ms);
175 } while (::android::elapsedRealtime() < timeoutMs);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000176 // TODO: return timeout error
177 return ResultStatus::CRITICAL_ERROR;
178}
179
Sungtak Lee8878a132022-12-07 11:42:03 +0000180BufferPoolStatus ClientManager::Impl::registerSender(
181 const std::shared_ptr<IClientManager> &receiver,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000182 ConnectionId senderId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000183 ConnectionId *receiverId,
184 bool *isNew) {
185 std::shared_ptr<IAccessor> accessor;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000186 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 Lee97e1dfb2022-12-07 07:45:45 +0000196 if (accessor) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000197 Registration registration;
198 ::ndk::ScopedAStatus status = receiver->registerSender(accessor, &registration);
199 if (!status.isOk()) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000200 return ResultStatus::CRITICAL_ERROR;
Sungtak Lee8878a132022-12-07 11:42:03 +0000201 } else if (local) {
202 std::shared_ptr<ConnectionDeathRecipient> recipient =
203 Accessor::getConnectionDeathRecipient();
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000204 if (recipient) {
205 ALOGV("client death recipient registered %lld", (long long)*receiverId);
Sungtak Lee8878a132022-12-07 11:42:03 +0000206 recipient->addCookieToConnection(receiver->asBinder().get(), *receiverId);
207 AIBinder_linkToDeath(receiver->asBinder().get(), recipient->getRecipient(),
208 receiver->asBinder().get());
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000209 }
210 }
Sungtak Lee8878a132022-12-07 11:42:03 +0000211 *receiverId = registration.connectionId;
212 *isNew = registration.isNew;
213 return ResultStatus::OK;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000214 }
Sungtak Lee8878a132022-12-07 11:42:03 +0000215 return ResultStatus::CRITICAL_ERROR;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000216}
217
Sungtak Lee8878a132022-12-07 11:42:03 +0000218BufferPoolStatus ClientManager::Impl::create(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000219 const std::shared_ptr<BufferPoolAllocator> &allocator,
220 ConnectionId *pConnectionId) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000221 std::shared_ptr<Accessor> accessor = ::ndk::SharedRefBase::make<Accessor>(allocator);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000222 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 Lee8878a132022-12-07 11:42:03 +0000251BufferPoolStatus ClientManager::Impl::close(ConnectionId connectionId) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000252 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 Lee8878a132022-12-07 11:42:03 +0000256 std::shared_ptr<IAccessor> accessor;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000257 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 Lee8878a132022-12-07 11:42:03 +0000262 std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
263 if (!cAccessor || (accessor && cAccessor.get() == accessor.get())) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000264 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 Lee8878a132022-12-07 11:42:03 +0000277BufferPoolStatus ClientManager::Impl::flush(ConnectionId connectionId) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000278 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 Lee8878a132022-12-07 11:42:03 +0000290BufferPoolStatus ClientManager::Impl::allocate(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000291 ConnectionId connectionId, const std::vector<uint8_t> &params,
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 Lee8878a132022-12-07 11:42:03 +0000304 BufferPoolStatus res = client->allocate(params, &origHandle, buffer);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000305 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 Lee8878a132022-12-07 11:42:03 +0000319BufferPoolStatus ClientManager::Impl::receive(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000320 ConnectionId connectionId, TransactionId transactionId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000321 BufferId bufferId, int64_t timestampMs,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000322 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 Lee8878a132022-12-07 11:42:03 +0000334 BufferPoolStatus res = client->receive(
335 transactionId, bufferId, timestampMs, &origHandle, buffer);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000336 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 Lee8878a132022-12-07 11:42:03 +0000346 return client->receive(transactionId, bufferId, timestampMs, handle, buffer);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000347#endif
348}
349
Sungtak Lee8878a132022-12-07 11:42:03 +0000350BufferPoolStatus ClientManager::Impl::postSend(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000351 ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
Sungtak Lee8878a132022-12-07 11:42:03 +0000352 TransactionId *transactionId, int64_t *timestampMs) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000353 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 Lee8878a132022-12-07 11:42:03 +0000363 return client->postSend(receiverId, buffer, transactionId, timestampMs);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000364}
365
Sungtak Lee8878a132022-12-07 11:42:03 +0000366BufferPoolStatus ClientManager::Impl::getAccessor(
367 ConnectionId connectionId, std::shared_ptr<IAccessor> *accessor) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000368 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
380void ClientManager::Impl::cleanUp(bool clearCache) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000381 int64_t now = ::android::elapsedRealtime();
382 int64_t lastTransactionMs;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000383 std::lock_guard<std::mutex> lock1(mCache.mMutex);
Sungtak Lee8878a132022-12-07 11:42:03 +0000384 if (clearCache || mCache.mLastCleanUpMs + kCleanUpDurationMs < now) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000385 std::lock_guard<std::mutex> lock2(mActive.mMutex);
386 int cleaned = 0;
387 for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000388 if (!it->second->isActive(&lastTransactionMs, clearCache)) {
389 if (lastTransactionMs + kClientTimeoutMs < now) {
390 std::shared_ptr<IAccessor> accessor;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000391 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 Lee8878a132022-12-07 11:42:03 +0000401 std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000402 if (!cAccessor) {
403 cit = mCache.mClients.erase(cit);
404 } else {
405 ++cit;
406 }
407 }
408 ALOGV("# of cleaned connections: %d", cleaned);
Sungtak Lee8878a132022-12-07 11:42:03 +0000409 mCache.mLastCleanUpMs = now;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000410 }
411}
412
Sungtak Lee8878a132022-12-07 11:42:03 +0000413::ndk::ScopedAStatus ClientManager::registerSender(
414 const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
415 BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000416 if (mImpl) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000417 status = mImpl->registerSender(in_bufferPool, _aidl_return);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000418 }
Sungtak Lee8878a132022-12-07 11:42:03 +0000419 if (status != ResultStatus::OK) {
420 return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
421 }
422 return ::ndk::ScopedAStatus::ok();
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000423}
424
Sungtak Leeae009082024-01-17 21:35:23 +0000425::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 Lee97e1dfb2022-12-07 07:45:45 +0000433// Methods for local use.
Sungtak Lee8878a132022-12-07 11:42:03 +0000434std::shared_ptr<ClientManager> ClientManager::sInstance;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000435std::mutex ClientManager::sInstanceLock;
436
Sungtak Lee8878a132022-12-07 11:42:03 +0000437std::shared_ptr<ClientManager> ClientManager::getInstance() {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000438 std::lock_guard<std::mutex> lock(sInstanceLock);
439 if (!sInstance) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000440 sInstance = ::ndk::SharedRefBase::make<ClientManager>();
441 // TODO: configure thread count for threadpool properly
442 // after b/261652496 is resolved.
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000443 }
444 Accessor::createInvalidator();
445 Accessor::createEvictor();
446 return sInstance;
447}
448
449ClientManager::ClientManager() : mImpl(new Impl()) {}
450
451ClientManager::~ClientManager() {
452}
453
Sungtak Lee8878a132022-12-07 11:42:03 +0000454BufferPoolStatus ClientManager::create(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000455 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 Lee8878a132022-12-07 11:42:03 +0000463BufferPoolStatus ClientManager::registerSender(
464 const std::shared_ptr<IClientManager> &receiver,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000465 ConnectionId senderId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000466 ConnectionId *receiverId,
467 bool *isNew) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000468 if (mImpl) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000469 return mImpl->registerSender(receiver, senderId, receiverId, isNew);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000470 }
471 return ResultStatus::CRITICAL_ERROR;
472}
473
Sungtak Lee8878a132022-12-07 11:42:03 +0000474BufferPoolStatus ClientManager::close(ConnectionId connectionId) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000475 if (mImpl) {
476 return mImpl->close(connectionId);
477 }
478 return ResultStatus::CRITICAL_ERROR;
479}
480
Sungtak Lee8878a132022-12-07 11:42:03 +0000481BufferPoolStatus ClientManager::flush(ConnectionId connectionId) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000482 if (mImpl) {
483 return mImpl->flush(connectionId);
484 }
485 return ResultStatus::CRITICAL_ERROR;
486}
487
Sungtak Lee8878a132022-12-07 11:42:03 +0000488BufferPoolStatus ClientManager::allocate(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000489 ConnectionId connectionId, const std::vector<uint8_t> &params,
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 Lee8878a132022-12-07 11:42:03 +0000497BufferPoolStatus ClientManager::receive(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000498 ConnectionId connectionId, TransactionId transactionId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000499 BufferId bufferId, int64_t timestampMs,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000500 native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
501 if (mImpl) {
502 return mImpl->receive(connectionId, transactionId, bufferId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000503 timestampMs, handle, buffer);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000504 }
505 return ResultStatus::CRITICAL_ERROR;
506}
507
Sungtak Lee8878a132022-12-07 11:42:03 +0000508BufferPoolStatus ClientManager::postSend(
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000509 ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
Sungtak Lee8878a132022-12-07 11:42:03 +0000510 TransactionId *transactionId, int64_t* timestampMs) {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000511 if (mImpl && buffer) {
Sungtak Lee8878a132022-12-07 11:42:03 +0000512 return mImpl->postSend(receiverId, buffer, transactionId, timestampMs);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000513 }
514 return ResultStatus::CRITICAL_ERROR;
515}
516
517void ClientManager::cleanUp() {
518 if (mImpl) {
519 mImpl->cleanUp(true);
520 }
521}
522
Sungtak Lee8878a132022-12-07 11:42:03 +0000523} // namespace ::aidl::android::hardware::media::bufferpool2::implementation