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