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
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "AidlBufferPoolCli"
18*4d7e907cSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*4d7e907cSAndroid Build Coastguard Worker
20*4d7e907cSAndroid Build Coastguard Worker #include <thread>
21*4d7e907cSAndroid Build Coastguard Worker #include <aidlcommonsupport/NativeHandle.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <utils/Log.h>
23*4d7e907cSAndroid Build Coastguard Worker #include "BufferPoolClient.h"
24*4d7e907cSAndroid Build Coastguard Worker #include "Accessor.h"
25*4d7e907cSAndroid Build Coastguard Worker #include "Connection.h"
26*4d7e907cSAndroid Build Coastguard Worker
27*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::media::bufferpool2::implementation {
28*4d7e907cSAndroid Build Coastguard Worker
29*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::media::bufferpool2::IConnection;
30*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::media::bufferpool2::ResultStatus;
31*4d7e907cSAndroid Build Coastguard Worker using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
32*4d7e907cSAndroid Build Coastguard Worker using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
33*4d7e907cSAndroid Build Coastguard Worker
34*4d7e907cSAndroid Build Coastguard Worker static constexpr int64_t kReceiveTimeoutMs = 2000; // 2s
35*4d7e907cSAndroid Build Coastguard Worker static constexpr int kPostMaxRetry = 3;
36*4d7e907cSAndroid Build Coastguard Worker static constexpr int kCacheTtlMs = 1000;
37*4d7e907cSAndroid Build Coastguard Worker static constexpr size_t kMaxCachedBufferCount = 64;
38*4d7e907cSAndroid Build Coastguard Worker static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
39*4d7e907cSAndroid Build Coastguard Worker
40*4d7e907cSAndroid Build Coastguard Worker class BufferPoolClient::Impl
41*4d7e907cSAndroid Build Coastguard Worker : public std::enable_shared_from_this<BufferPoolClient::Impl> {
42*4d7e907cSAndroid Build Coastguard Worker public:
43*4d7e907cSAndroid Build Coastguard Worker explicit Impl(const std::shared_ptr<Accessor> &accessor,
44*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer);
45*4d7e907cSAndroid Build Coastguard Worker
46*4d7e907cSAndroid Build Coastguard Worker explicit Impl(const std::shared_ptr<IAccessor> &accessor,
47*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer);
48*4d7e907cSAndroid Build Coastguard Worker
isValid()49*4d7e907cSAndroid Build Coastguard Worker bool isValid() {
50*4d7e907cSAndroid Build Coastguard Worker return mValid;
51*4d7e907cSAndroid Build Coastguard Worker }
52*4d7e907cSAndroid Build Coastguard Worker
isLocal()53*4d7e907cSAndroid Build Coastguard Worker bool isLocal() {
54*4d7e907cSAndroid Build Coastguard Worker return mValid && mLocal;
55*4d7e907cSAndroid Build Coastguard Worker }
56*4d7e907cSAndroid Build Coastguard Worker
getConnectionId()57*4d7e907cSAndroid Build Coastguard Worker ConnectionId getConnectionId() {
58*4d7e907cSAndroid Build Coastguard Worker return mConnectionId;
59*4d7e907cSAndroid Build Coastguard Worker }
60*4d7e907cSAndroid Build Coastguard Worker
getAccessor()61*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IAccessor> &getAccessor() {
62*4d7e907cSAndroid Build Coastguard Worker return mAccessor;
63*4d7e907cSAndroid Build Coastguard Worker }
64*4d7e907cSAndroid Build Coastguard Worker
65*4d7e907cSAndroid Build Coastguard Worker bool isActive(int64_t *lastTransactionMs, bool clearCache);
66*4d7e907cSAndroid Build Coastguard Worker
67*4d7e907cSAndroid Build Coastguard Worker void receiveInvalidation(uint32_t msgID);
68*4d7e907cSAndroid Build Coastguard Worker
69*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus flush();
70*4d7e907cSAndroid Build Coastguard Worker
71*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus allocate(const std::vector<uint8_t> ¶ms,
72*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle,
73*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> *buffer);
74*4d7e907cSAndroid Build Coastguard Worker
75*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus receive(
76*4d7e907cSAndroid Build Coastguard Worker TransactionId transactionId, BufferId bufferId,
77*4d7e907cSAndroid Build Coastguard Worker int64_t timestampMs,
78*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
79*4d7e907cSAndroid Build Coastguard Worker
80*4d7e907cSAndroid Build Coastguard Worker void postBufferRelease(BufferId bufferId);
81*4d7e907cSAndroid Build Coastguard Worker
82*4d7e907cSAndroid Build Coastguard Worker bool postSend(
83*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, ConnectionId receiver,
84*4d7e907cSAndroid Build Coastguard Worker TransactionId *transactionId, int64_t *timestampMs);
85*4d7e907cSAndroid Build Coastguard Worker private:
86*4d7e907cSAndroid Build Coastguard Worker
87*4d7e907cSAndroid Build Coastguard Worker bool postReceive(
88*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, TransactionId transactionId,
89*4d7e907cSAndroid Build Coastguard Worker int64_t timestampMs);
90*4d7e907cSAndroid Build Coastguard Worker
91*4d7e907cSAndroid Build Coastguard Worker bool postReceiveResult(
92*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
93*4d7e907cSAndroid Build Coastguard Worker
94*4d7e907cSAndroid Build Coastguard Worker void trySyncFromRemote();
95*4d7e907cSAndroid Build Coastguard Worker
96*4d7e907cSAndroid Build Coastguard Worker bool syncReleased(uint32_t msgId = 0);
97*4d7e907cSAndroid Build Coastguard Worker
98*4d7e907cSAndroid Build Coastguard Worker void evictCaches(bool clearCache = false);
99*4d7e907cSAndroid Build Coastguard Worker
100*4d7e907cSAndroid Build Coastguard Worker void invalidateBuffer(BufferId id);
101*4d7e907cSAndroid Build Coastguard Worker
102*4d7e907cSAndroid Build Coastguard Worker void invalidateRange(BufferId from, BufferId to);
103*4d7e907cSAndroid Build Coastguard Worker
104*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus allocateBufferHandle(
105*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& params, BufferId *bufferId,
106*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle);
107*4d7e907cSAndroid Build Coastguard Worker
108*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus fetchBufferHandle(
109*4d7e907cSAndroid Build Coastguard Worker TransactionId transactionId, BufferId bufferId,
110*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle);
111*4d7e907cSAndroid Build Coastguard Worker
112*4d7e907cSAndroid Build Coastguard Worker struct BlockPoolDataDtor;
113*4d7e907cSAndroid Build Coastguard Worker struct ClientBuffer;
114*4d7e907cSAndroid Build Coastguard Worker
115*4d7e907cSAndroid Build Coastguard Worker bool mLocal;
116*4d7e907cSAndroid Build Coastguard Worker bool mValid;
117*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IAccessor> mAccessor;
118*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<Connection> mLocalConnection;
119*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IConnection> mRemoteConnection;
120*4d7e907cSAndroid Build Coastguard Worker uint32_t mSeqId;
121*4d7e907cSAndroid Build Coastguard Worker ConnectionId mConnectionId;
122*4d7e907cSAndroid Build Coastguard Worker int64_t mLastEvictCacheMs;
123*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<BufferInvalidationListener> mInvalidationListener;
124*4d7e907cSAndroid Build Coastguard Worker
125*4d7e907cSAndroid Build Coastguard Worker // CachedBuffers
126*4d7e907cSAndroid Build Coastguard Worker struct BufferCache {
127*4d7e907cSAndroid Build Coastguard Worker std::mutex mLock;
128*4d7e907cSAndroid Build Coastguard Worker bool mCreating;
129*4d7e907cSAndroid Build Coastguard Worker std::condition_variable mCreateCv;
130*4d7e907cSAndroid Build Coastguard Worker std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
131*4d7e907cSAndroid Build Coastguard Worker int mActive;
132*4d7e907cSAndroid Build Coastguard Worker int64_t mLastChangeMs;
133*4d7e907cSAndroid Build Coastguard Worker
BufferCacheaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BufferCache134*4d7e907cSAndroid Build Coastguard Worker BufferCache() : mCreating(false), mActive(0),
135*4d7e907cSAndroid Build Coastguard Worker mLastChangeMs(::android::elapsedRealtime()) {}
136*4d7e907cSAndroid Build Coastguard Worker
incActive_laidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BufferCache137*4d7e907cSAndroid Build Coastguard Worker void incActive_l() {
138*4d7e907cSAndroid Build Coastguard Worker ++mActive;
139*4d7e907cSAndroid Build Coastguard Worker mLastChangeMs = ::android::elapsedRealtime();
140*4d7e907cSAndroid Build Coastguard Worker }
141*4d7e907cSAndroid Build Coastguard Worker
decActive_laidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BufferCache142*4d7e907cSAndroid Build Coastguard Worker void decActive_l() {
143*4d7e907cSAndroid Build Coastguard Worker --mActive;
144*4d7e907cSAndroid Build Coastguard Worker mLastChangeMs = ::android::elapsedRealtime();
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker
cachedBufferCountaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BufferCache147*4d7e907cSAndroid Build Coastguard Worker int cachedBufferCount() const {
148*4d7e907cSAndroid Build Coastguard Worker return mBuffers.size() - mActive;
149*4d7e907cSAndroid Build Coastguard Worker }
150*4d7e907cSAndroid Build Coastguard Worker } mCache;
151*4d7e907cSAndroid Build Coastguard Worker
152*4d7e907cSAndroid Build Coastguard Worker // FMQ - release notifier
153*4d7e907cSAndroid Build Coastguard Worker struct ReleaseCache {
154*4d7e907cSAndroid Build Coastguard Worker std::mutex mLock;
155*4d7e907cSAndroid Build Coastguard Worker std::list<BufferId> mReleasingIds;
156*4d7e907cSAndroid Build Coastguard Worker std::list<BufferId> mReleasedIds;
157*4d7e907cSAndroid Build Coastguard Worker uint32_t mInvalidateId; // TODO: invalidation ACK to bufferpool
158*4d7e907cSAndroid Build Coastguard Worker bool mInvalidateAck;
159*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<BufferStatusChannel> mStatusChannel;
160*4d7e907cSAndroid Build Coastguard Worker
ReleaseCacheaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ReleaseCache161*4d7e907cSAndroid Build Coastguard Worker ReleaseCache() : mInvalidateId(0), mInvalidateAck(true) {}
162*4d7e907cSAndroid Build Coastguard Worker } mReleasing;
163*4d7e907cSAndroid Build Coastguard Worker
164*4d7e907cSAndroid Build Coastguard Worker // This lock is held during synchronization from remote side.
165*4d7e907cSAndroid Build Coastguard Worker // In order to minimize remote calls and locking duration, this lock is held
166*4d7e907cSAndroid Build Coastguard Worker // by best effort approach using try_lock().
167*4d7e907cSAndroid Build Coastguard Worker std::mutex mRemoteSyncLock;
168*4d7e907cSAndroid Build Coastguard Worker };
169*4d7e907cSAndroid Build Coastguard Worker
170*4d7e907cSAndroid Build Coastguard Worker struct BufferPoolClient::Impl::BlockPoolDataDtor {
BlockPoolDataDtoraidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BlockPoolDataDtor171*4d7e907cSAndroid Build Coastguard Worker BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
172*4d7e907cSAndroid Build Coastguard Worker : mImpl(impl) {}
173*4d7e907cSAndroid Build Coastguard Worker
operator ()aidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::BlockPoolDataDtor174*4d7e907cSAndroid Build Coastguard Worker void operator()(BufferPoolData *buffer) {
175*4d7e907cSAndroid Build Coastguard Worker BufferId id = buffer->mId;
176*4d7e907cSAndroid Build Coastguard Worker delete buffer;
177*4d7e907cSAndroid Build Coastguard Worker
178*4d7e907cSAndroid Build Coastguard Worker auto impl = mImpl.lock();
179*4d7e907cSAndroid Build Coastguard Worker if (impl && impl->isValid()) {
180*4d7e907cSAndroid Build Coastguard Worker impl->postBufferRelease(id);
181*4d7e907cSAndroid Build Coastguard Worker }
182*4d7e907cSAndroid Build Coastguard Worker }
183*4d7e907cSAndroid Build Coastguard Worker const std::weak_ptr<BufferPoolClient::Impl> mImpl;
184*4d7e907cSAndroid Build Coastguard Worker };
185*4d7e907cSAndroid Build Coastguard Worker
186*4d7e907cSAndroid Build Coastguard Worker struct BufferPoolClient::Impl::ClientBuffer {
187*4d7e907cSAndroid Build Coastguard Worker private:
188*4d7e907cSAndroid Build Coastguard Worker int64_t mExpireMs;
189*4d7e907cSAndroid Build Coastguard Worker bool mHasCache;
190*4d7e907cSAndroid Build Coastguard Worker ConnectionId mConnectionId;
191*4d7e907cSAndroid Build Coastguard Worker BufferId mId;
192*4d7e907cSAndroid Build Coastguard Worker native_handle_t *mHandle;
193*4d7e907cSAndroid Build Coastguard Worker std::weak_ptr<BufferPoolData> mCache;
194*4d7e907cSAndroid Build Coastguard Worker
updateExpireaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer195*4d7e907cSAndroid Build Coastguard Worker void updateExpire() {
196*4d7e907cSAndroid Build Coastguard Worker mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
197*4d7e907cSAndroid Build Coastguard Worker }
198*4d7e907cSAndroid Build Coastguard Worker
199*4d7e907cSAndroid Build Coastguard Worker public:
ClientBufferaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer200*4d7e907cSAndroid Build Coastguard Worker ClientBuffer(
201*4d7e907cSAndroid Build Coastguard Worker ConnectionId connectionId, BufferId id, native_handle_t *handle)
202*4d7e907cSAndroid Build Coastguard Worker : mHasCache(false), mConnectionId(connectionId),
203*4d7e907cSAndroid Build Coastguard Worker mId(id), mHandle(handle) {
204*4d7e907cSAndroid Build Coastguard Worker mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
205*4d7e907cSAndroid Build Coastguard Worker }
206*4d7e907cSAndroid Build Coastguard Worker
~ClientBufferaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer207*4d7e907cSAndroid Build Coastguard Worker ~ClientBuffer() {
208*4d7e907cSAndroid Build Coastguard Worker if (mHandle) {
209*4d7e907cSAndroid Build Coastguard Worker native_handle_close(mHandle);
210*4d7e907cSAndroid Build Coastguard Worker native_handle_delete(mHandle);
211*4d7e907cSAndroid Build Coastguard Worker }
212*4d7e907cSAndroid Build Coastguard Worker }
213*4d7e907cSAndroid Build Coastguard Worker
idaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer214*4d7e907cSAndroid Build Coastguard Worker BufferId id() const {
215*4d7e907cSAndroid Build Coastguard Worker return mId;
216*4d7e907cSAndroid Build Coastguard Worker }
217*4d7e907cSAndroid Build Coastguard Worker
expireaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer218*4d7e907cSAndroid Build Coastguard Worker bool expire() const {
219*4d7e907cSAndroid Build Coastguard Worker int64_t now = ::android::elapsedRealtime();
220*4d7e907cSAndroid Build Coastguard Worker return now >= mExpireMs;
221*4d7e907cSAndroid Build Coastguard Worker }
222*4d7e907cSAndroid Build Coastguard Worker
hasCacheaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer223*4d7e907cSAndroid Build Coastguard Worker bool hasCache() const {
224*4d7e907cSAndroid Build Coastguard Worker return mHasCache;
225*4d7e907cSAndroid Build Coastguard Worker }
226*4d7e907cSAndroid Build Coastguard Worker
fetchCacheaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer227*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
228*4d7e907cSAndroid Build Coastguard Worker if (mHasCache) {
229*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> cache = mCache.lock();
230*4d7e907cSAndroid Build Coastguard Worker if (cache) {
231*4d7e907cSAndroid Build Coastguard Worker *pHandle = mHandle;
232*4d7e907cSAndroid Build Coastguard Worker }
233*4d7e907cSAndroid Build Coastguard Worker return cache;
234*4d7e907cSAndroid Build Coastguard Worker }
235*4d7e907cSAndroid Build Coastguard Worker return nullptr;
236*4d7e907cSAndroid Build Coastguard Worker }
237*4d7e907cSAndroid Build Coastguard Worker
createCacheaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer238*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> createCache(
239*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<BufferPoolClient::Impl> &impl,
240*4d7e907cSAndroid Build Coastguard Worker native_handle_t **pHandle) {
241*4d7e907cSAndroid Build Coastguard Worker if (!mHasCache) {
242*4d7e907cSAndroid Build Coastguard Worker // Allocates a raw ptr in order to avoid sending #postBufferRelease
243*4d7e907cSAndroid Build Coastguard Worker // from deleter, in case of native_handle_clone failure.
244*4d7e907cSAndroid Build Coastguard Worker BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
245*4d7e907cSAndroid Build Coastguard Worker if (ptr) {
246*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
247*4d7e907cSAndroid Build Coastguard Worker if (cache) {
248*4d7e907cSAndroid Build Coastguard Worker mCache = cache;
249*4d7e907cSAndroid Build Coastguard Worker mHasCache = true;
250*4d7e907cSAndroid Build Coastguard Worker *pHandle = mHandle;
251*4d7e907cSAndroid Build Coastguard Worker return cache;
252*4d7e907cSAndroid Build Coastguard Worker }
253*4d7e907cSAndroid Build Coastguard Worker }
254*4d7e907cSAndroid Build Coastguard Worker if (ptr) {
255*4d7e907cSAndroid Build Coastguard Worker delete ptr;
256*4d7e907cSAndroid Build Coastguard Worker }
257*4d7e907cSAndroid Build Coastguard Worker }
258*4d7e907cSAndroid Build Coastguard Worker return nullptr;
259*4d7e907cSAndroid Build Coastguard Worker }
260*4d7e907cSAndroid Build Coastguard Worker
onCacheReleaseaidl::android::hardware::media::bufferpool2::implementation::BufferPoolClient::Impl::ClientBuffer261*4d7e907cSAndroid Build Coastguard Worker bool onCacheRelease() {
262*4d7e907cSAndroid Build Coastguard Worker if (mHasCache) {
263*4d7e907cSAndroid Build Coastguard Worker // TODO: verify mCache is not valid;
264*4d7e907cSAndroid Build Coastguard Worker updateExpire();
265*4d7e907cSAndroid Build Coastguard Worker mHasCache = false;
266*4d7e907cSAndroid Build Coastguard Worker return true;
267*4d7e907cSAndroid Build Coastguard Worker }
268*4d7e907cSAndroid Build Coastguard Worker return false;
269*4d7e907cSAndroid Build Coastguard Worker }
270*4d7e907cSAndroid Build Coastguard Worker };
271*4d7e907cSAndroid Build Coastguard Worker
Impl(const std::shared_ptr<Accessor> & accessor,const std::shared_ptr<IObserver> & observer)272*4d7e907cSAndroid Build Coastguard Worker BufferPoolClient::Impl::Impl(const std::shared_ptr<Accessor> &accessor,
273*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer)
274*4d7e907cSAndroid Build Coastguard Worker : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
275*4d7e907cSAndroid Build Coastguard Worker mLastEvictCacheMs(::android::elapsedRealtime()) {
276*4d7e907cSAndroid Build Coastguard Worker StatusDescriptor statusDesc;
277*4d7e907cSAndroid Build Coastguard Worker InvalidationDescriptor invDesc;
278*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus status = accessor->connect(
279*4d7e907cSAndroid Build Coastguard Worker observer, true,
280*4d7e907cSAndroid Build Coastguard Worker &mLocalConnection, &mConnectionId, &mReleasing.mInvalidateId,
281*4d7e907cSAndroid Build Coastguard Worker &statusDesc, &invDesc);
282*4d7e907cSAndroid Build Coastguard Worker if (status == ResultStatus::OK) {
283*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel =
284*4d7e907cSAndroid Build Coastguard Worker std::make_unique<BufferStatusChannel>(statusDesc);
285*4d7e907cSAndroid Build Coastguard Worker mInvalidationListener =
286*4d7e907cSAndroid Build Coastguard Worker std::make_unique<BufferInvalidationListener>(invDesc);
287*4d7e907cSAndroid Build Coastguard Worker mValid = mReleasing.mStatusChannel &&
288*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel->isValid() &&
289*4d7e907cSAndroid Build Coastguard Worker mInvalidationListener &&
290*4d7e907cSAndroid Build Coastguard Worker mInvalidationListener->isValid();
291*4d7e907cSAndroid Build Coastguard Worker }
292*4d7e907cSAndroid Build Coastguard Worker }
293*4d7e907cSAndroid Build Coastguard Worker
Impl(const std::shared_ptr<IAccessor> & accessor,const std::shared_ptr<IObserver> & observer)294*4d7e907cSAndroid Build Coastguard Worker BufferPoolClient::Impl::Impl(const std::shared_ptr<IAccessor> &accessor,
295*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer)
296*4d7e907cSAndroid Build Coastguard Worker : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
297*4d7e907cSAndroid Build Coastguard Worker mLastEvictCacheMs(::android::elapsedRealtime()) {
298*4d7e907cSAndroid Build Coastguard Worker IAccessor::ConnectionInfo conInfo;
299*4d7e907cSAndroid Build Coastguard Worker bool valid = false;
300*4d7e907cSAndroid Build Coastguard Worker if (accessor && accessor->connect(observer, &conInfo).isOk()) {
301*4d7e907cSAndroid Build Coastguard Worker auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
302*4d7e907cSAndroid Build Coastguard Worker auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
303*4d7e907cSAndroid Build Coastguard Worker
304*4d7e907cSAndroid Build Coastguard Worker if (channel && channel->isValid()
305*4d7e907cSAndroid Build Coastguard Worker && observer && observer->isValid()) {
306*4d7e907cSAndroid Build Coastguard Worker mRemoteConnection = conInfo.connection;
307*4d7e907cSAndroid Build Coastguard Worker mConnectionId = conInfo.connectionId;
308*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateId = conInfo.msgId;
309*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel = std::move(channel);
310*4d7e907cSAndroid Build Coastguard Worker mInvalidationListener = std::move(observer);
311*4d7e907cSAndroid Build Coastguard Worker valid = true;
312*4d7e907cSAndroid Build Coastguard Worker }
313*4d7e907cSAndroid Build Coastguard Worker }
314*4d7e907cSAndroid Build Coastguard Worker mValid = valid;
315*4d7e907cSAndroid Build Coastguard Worker }
316*4d7e907cSAndroid Build Coastguard Worker
isActive(int64_t * lastTransactionMs,bool clearCache)317*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionMs, bool clearCache) {
318*4d7e907cSAndroid Build Coastguard Worker bool active = false;
319*4d7e907cSAndroid Build Coastguard Worker {
320*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mCache.mLock);
321*4d7e907cSAndroid Build Coastguard Worker syncReleased();
322*4d7e907cSAndroid Build Coastguard Worker evictCaches(clearCache);
323*4d7e907cSAndroid Build Coastguard Worker *lastTransactionMs = mCache.mLastChangeMs;
324*4d7e907cSAndroid Build Coastguard Worker active = mCache.mActive > 0;
325*4d7e907cSAndroid Build Coastguard Worker }
326*4d7e907cSAndroid Build Coastguard Worker if (mValid && mLocal && mLocalConnection) {
327*4d7e907cSAndroid Build Coastguard Worker mLocalConnection->cleanUp(clearCache);
328*4d7e907cSAndroid Build Coastguard Worker return true;
329*4d7e907cSAndroid Build Coastguard Worker }
330*4d7e907cSAndroid Build Coastguard Worker return active;
331*4d7e907cSAndroid Build Coastguard Worker }
332*4d7e907cSAndroid Build Coastguard Worker
receiveInvalidation(uint32_t messageId)333*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::receiveInvalidation(uint32_t messageId) {
334*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mCache.mLock);
335*4d7e907cSAndroid Build Coastguard Worker syncReleased(messageId);
336*4d7e907cSAndroid Build Coastguard Worker // TODO: evict cache required?
337*4d7e907cSAndroid Build Coastguard Worker }
338*4d7e907cSAndroid Build Coastguard Worker
flush()339*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::Impl::flush() {
340*4d7e907cSAndroid Build Coastguard Worker if (!mLocal || !mLocalConnection || !mValid) {
341*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
342*4d7e907cSAndroid Build Coastguard Worker }
343*4d7e907cSAndroid Build Coastguard Worker {
344*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mCache.mLock);
345*4d7e907cSAndroid Build Coastguard Worker syncReleased();
346*4d7e907cSAndroid Build Coastguard Worker evictCaches();
347*4d7e907cSAndroid Build Coastguard Worker return mLocalConnection->flush();
348*4d7e907cSAndroid Build Coastguard Worker }
349*4d7e907cSAndroid Build Coastguard Worker }
350*4d7e907cSAndroid Build Coastguard Worker
allocate(const std::vector<uint8_t> & params,native_handle_t ** pHandle,std::shared_ptr<BufferPoolData> * buffer)351*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::Impl::allocate(
352*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> ¶ms,
353*4d7e907cSAndroid Build Coastguard Worker native_handle_t **pHandle,
354*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> *buffer) {
355*4d7e907cSAndroid Build Coastguard Worker if (!mLocal || !mLocalConnection || !mValid) {
356*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
357*4d7e907cSAndroid Build Coastguard Worker }
358*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId;
359*4d7e907cSAndroid Build Coastguard Worker native_handle_t *handle = nullptr;
360*4d7e907cSAndroid Build Coastguard Worker buffer->reset();
361*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus status = allocateBufferHandle(params, &bufferId, &handle);
362*4d7e907cSAndroid Build Coastguard Worker if (status == ResultStatus::OK) {
363*4d7e907cSAndroid Build Coastguard Worker if (handle) {
364*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mCache.mLock);
365*4d7e907cSAndroid Build Coastguard Worker syncReleased();
366*4d7e907cSAndroid Build Coastguard Worker evictCaches();
367*4d7e907cSAndroid Build Coastguard Worker auto cacheIt = mCache.mBuffers.find(bufferId);
368*4d7e907cSAndroid Build Coastguard Worker if (cacheIt != mCache.mBuffers.end()) {
369*4d7e907cSAndroid Build Coastguard Worker // TODO: verify it is recycled. (not having active ref)
370*4d7e907cSAndroid Build Coastguard Worker mCache.mBuffers.erase(cacheIt);
371*4d7e907cSAndroid Build Coastguard Worker }
372*4d7e907cSAndroid Build Coastguard Worker auto clientBuffer = std::make_unique<ClientBuffer>(
373*4d7e907cSAndroid Build Coastguard Worker mConnectionId, bufferId, handle);
374*4d7e907cSAndroid Build Coastguard Worker if (clientBuffer) {
375*4d7e907cSAndroid Build Coastguard Worker auto result = mCache.mBuffers.insert(std::make_pair(
376*4d7e907cSAndroid Build Coastguard Worker bufferId, std::move(clientBuffer)));
377*4d7e907cSAndroid Build Coastguard Worker if (result.second) {
378*4d7e907cSAndroid Build Coastguard Worker *buffer = result.first->second->createCache(
379*4d7e907cSAndroid Build Coastguard Worker shared_from_this(), pHandle);
380*4d7e907cSAndroid Build Coastguard Worker if (*buffer) {
381*4d7e907cSAndroid Build Coastguard Worker mCache.incActive_l();
382*4d7e907cSAndroid Build Coastguard Worker }
383*4d7e907cSAndroid Build Coastguard Worker }
384*4d7e907cSAndroid Build Coastguard Worker }
385*4d7e907cSAndroid Build Coastguard Worker }
386*4d7e907cSAndroid Build Coastguard Worker if (!*buffer) {
387*4d7e907cSAndroid Build Coastguard Worker ALOGV("client cache creation failure %d: %lld",
388*4d7e907cSAndroid Build Coastguard Worker handle != nullptr, (long long)mConnectionId);
389*4d7e907cSAndroid Build Coastguard Worker status = ResultStatus::NO_MEMORY;
390*4d7e907cSAndroid Build Coastguard Worker postBufferRelease(bufferId);
391*4d7e907cSAndroid Build Coastguard Worker }
392*4d7e907cSAndroid Build Coastguard Worker }
393*4d7e907cSAndroid Build Coastguard Worker return status;
394*4d7e907cSAndroid Build Coastguard Worker }
395*4d7e907cSAndroid Build Coastguard Worker
receive(TransactionId transactionId,BufferId bufferId,int64_t timestampMs,native_handle_t ** pHandle,std::shared_ptr<BufferPoolData> * buffer)396*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::Impl::receive(
397*4d7e907cSAndroid Build Coastguard Worker TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
398*4d7e907cSAndroid Build Coastguard Worker native_handle_t **pHandle,
399*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> *buffer) {
400*4d7e907cSAndroid Build Coastguard Worker if (!mValid) {
401*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
402*4d7e907cSAndroid Build Coastguard Worker }
403*4d7e907cSAndroid Build Coastguard Worker if (timestampMs != 0) {
404*4d7e907cSAndroid Build Coastguard Worker timestampMs += kReceiveTimeoutMs;
405*4d7e907cSAndroid Build Coastguard Worker }
406*4d7e907cSAndroid Build Coastguard Worker if (!postReceive(bufferId, transactionId, timestampMs)) {
407*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
408*4d7e907cSAndroid Build Coastguard Worker }
409*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
410*4d7e907cSAndroid Build Coastguard Worker buffer->reset();
411*4d7e907cSAndroid Build Coastguard Worker while(1) {
412*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mCache.mLock);
413*4d7e907cSAndroid Build Coastguard Worker syncReleased();
414*4d7e907cSAndroid Build Coastguard Worker evictCaches();
415*4d7e907cSAndroid Build Coastguard Worker auto cacheIt = mCache.mBuffers.find(bufferId);
416*4d7e907cSAndroid Build Coastguard Worker if (cacheIt != mCache.mBuffers.end()) {
417*4d7e907cSAndroid Build Coastguard Worker if (cacheIt->second->hasCache()) {
418*4d7e907cSAndroid Build Coastguard Worker *buffer = cacheIt->second->fetchCache(pHandle);
419*4d7e907cSAndroid Build Coastguard Worker if (!*buffer) {
420*4d7e907cSAndroid Build Coastguard Worker // check transfer time_out
421*4d7e907cSAndroid Build Coastguard Worker lock.unlock();
422*4d7e907cSAndroid Build Coastguard Worker std::this_thread::yield();
423*4d7e907cSAndroid Build Coastguard Worker continue;
424*4d7e907cSAndroid Build Coastguard Worker }
425*4d7e907cSAndroid Build Coastguard Worker ALOGV("client receive from reference %lld", (long long)mConnectionId);
426*4d7e907cSAndroid Build Coastguard Worker break;
427*4d7e907cSAndroid Build Coastguard Worker } else {
428*4d7e907cSAndroid Build Coastguard Worker *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
429*4d7e907cSAndroid Build Coastguard Worker if (*buffer) {
430*4d7e907cSAndroid Build Coastguard Worker mCache.incActive_l();
431*4d7e907cSAndroid Build Coastguard Worker }
432*4d7e907cSAndroid Build Coastguard Worker ALOGV("client receive from cache %lld", (long long)mConnectionId);
433*4d7e907cSAndroid Build Coastguard Worker break;
434*4d7e907cSAndroid Build Coastguard Worker }
435*4d7e907cSAndroid Build Coastguard Worker } else {
436*4d7e907cSAndroid Build Coastguard Worker if (!mCache.mCreating) {
437*4d7e907cSAndroid Build Coastguard Worker mCache.mCreating = true;
438*4d7e907cSAndroid Build Coastguard Worker lock.unlock();
439*4d7e907cSAndroid Build Coastguard Worker native_handle_t* handle = nullptr;
440*4d7e907cSAndroid Build Coastguard Worker status = fetchBufferHandle(transactionId, bufferId, &handle);
441*4d7e907cSAndroid Build Coastguard Worker lock.lock();
442*4d7e907cSAndroid Build Coastguard Worker if (status == ResultStatus::OK) {
443*4d7e907cSAndroid Build Coastguard Worker if (handle) {
444*4d7e907cSAndroid Build Coastguard Worker auto clientBuffer = std::make_unique<ClientBuffer>(
445*4d7e907cSAndroid Build Coastguard Worker mConnectionId, bufferId, handle);
446*4d7e907cSAndroid Build Coastguard Worker if (clientBuffer) {
447*4d7e907cSAndroid Build Coastguard Worker auto result = mCache.mBuffers.insert(
448*4d7e907cSAndroid Build Coastguard Worker std::make_pair(bufferId, std::move(
449*4d7e907cSAndroid Build Coastguard Worker clientBuffer)));
450*4d7e907cSAndroid Build Coastguard Worker if (result.second) {
451*4d7e907cSAndroid Build Coastguard Worker *buffer = result.first->second->createCache(
452*4d7e907cSAndroid Build Coastguard Worker shared_from_this(), pHandle);
453*4d7e907cSAndroid Build Coastguard Worker if (*buffer) {
454*4d7e907cSAndroid Build Coastguard Worker mCache.incActive_l();
455*4d7e907cSAndroid Build Coastguard Worker }
456*4d7e907cSAndroid Build Coastguard Worker }
457*4d7e907cSAndroid Build Coastguard Worker }
458*4d7e907cSAndroid Build Coastguard Worker }
459*4d7e907cSAndroid Build Coastguard Worker if (!*buffer) {
460*4d7e907cSAndroid Build Coastguard Worker status = ResultStatus::NO_MEMORY;
461*4d7e907cSAndroid Build Coastguard Worker }
462*4d7e907cSAndroid Build Coastguard Worker }
463*4d7e907cSAndroid Build Coastguard Worker mCache.mCreating = false;
464*4d7e907cSAndroid Build Coastguard Worker lock.unlock();
465*4d7e907cSAndroid Build Coastguard Worker mCache.mCreateCv.notify_all();
466*4d7e907cSAndroid Build Coastguard Worker break;
467*4d7e907cSAndroid Build Coastguard Worker }
468*4d7e907cSAndroid Build Coastguard Worker mCache.mCreateCv.wait(lock);
469*4d7e907cSAndroid Build Coastguard Worker }
470*4d7e907cSAndroid Build Coastguard Worker }
471*4d7e907cSAndroid Build Coastguard Worker bool needsSync = false;
472*4d7e907cSAndroid Build Coastguard Worker bool posted = postReceiveResult(bufferId, transactionId,
473*4d7e907cSAndroid Build Coastguard Worker *buffer ? true : false, &needsSync);
474*4d7e907cSAndroid Build Coastguard Worker ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
475*4d7e907cSAndroid Build Coastguard Worker *buffer ? "ok" : "fail", posted);
476*4d7e907cSAndroid Build Coastguard Worker if (mValid && mLocal && mLocalConnection) {
477*4d7e907cSAndroid Build Coastguard Worker mLocalConnection->cleanUp(false);
478*4d7e907cSAndroid Build Coastguard Worker }
479*4d7e907cSAndroid Build Coastguard Worker if (needsSync && mRemoteConnection) {
480*4d7e907cSAndroid Build Coastguard Worker trySyncFromRemote();
481*4d7e907cSAndroid Build Coastguard Worker }
482*4d7e907cSAndroid Build Coastguard Worker if (*buffer) {
483*4d7e907cSAndroid Build Coastguard Worker if (!posted) {
484*4d7e907cSAndroid Build Coastguard Worker buffer->reset();
485*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
486*4d7e907cSAndroid Build Coastguard Worker }
487*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::OK;
488*4d7e907cSAndroid Build Coastguard Worker }
489*4d7e907cSAndroid Build Coastguard Worker return status;
490*4d7e907cSAndroid Build Coastguard Worker }
491*4d7e907cSAndroid Build Coastguard Worker
492*4d7e907cSAndroid Build Coastguard Worker
postBufferRelease(BufferId bufferId)493*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
494*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
495*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasingIds.push_back(bufferId);
496*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel->postBufferRelease(
497*4d7e907cSAndroid Build Coastguard Worker mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
498*4d7e907cSAndroid Build Coastguard Worker }
499*4d7e907cSAndroid Build Coastguard Worker
500*4d7e907cSAndroid Build Coastguard Worker // TODO: revise ad-hoc posting data structure
postSend(BufferId bufferId,ConnectionId receiver,TransactionId * transactionId,int64_t * timestampMs)501*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::Impl::postSend(
502*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, ConnectionId receiver,
503*4d7e907cSAndroid Build Coastguard Worker TransactionId *transactionId, int64_t *timestampMs) {
504*4d7e907cSAndroid Build Coastguard Worker {
505*4d7e907cSAndroid Build Coastguard Worker // TODO: don't need to call syncReleased every time
506*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mCache.mLock);
507*4d7e907cSAndroid Build Coastguard Worker syncReleased();
508*4d7e907cSAndroid Build Coastguard Worker }
509*4d7e907cSAndroid Build Coastguard Worker bool ret = false;
510*4d7e907cSAndroid Build Coastguard Worker bool needsSync = false;
511*4d7e907cSAndroid Build Coastguard Worker {
512*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
513*4d7e907cSAndroid Build Coastguard Worker *timestampMs = ::android::elapsedRealtime();
514*4d7e907cSAndroid Build Coastguard Worker *transactionId = (mConnectionId << 32) | mSeqId++;
515*4d7e907cSAndroid Build Coastguard Worker // TODO: retry, add timeout, target?
516*4d7e907cSAndroid Build Coastguard Worker ret = mReleasing.mStatusChannel->postBufferStatusMessage(
517*4d7e907cSAndroid Build Coastguard Worker *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
518*4d7e907cSAndroid Build Coastguard Worker receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
519*4d7e907cSAndroid Build Coastguard Worker needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
520*4d7e907cSAndroid Build Coastguard Worker }
521*4d7e907cSAndroid Build Coastguard Worker if (mValid && mLocal && mLocalConnection) {
522*4d7e907cSAndroid Build Coastguard Worker mLocalConnection->cleanUp(false);
523*4d7e907cSAndroid Build Coastguard Worker }
524*4d7e907cSAndroid Build Coastguard Worker if (needsSync && mRemoteConnection) {
525*4d7e907cSAndroid Build Coastguard Worker trySyncFromRemote();
526*4d7e907cSAndroid Build Coastguard Worker }
527*4d7e907cSAndroid Build Coastguard Worker return ret;
528*4d7e907cSAndroid Build Coastguard Worker }
529*4d7e907cSAndroid Build Coastguard Worker
postReceive(BufferId bufferId,TransactionId transactionId,int64_t timestampMs)530*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::Impl::postReceive(
531*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, TransactionId transactionId, int64_t timestampMs) {
532*4d7e907cSAndroid Build Coastguard Worker for (int i = 0; i < kPostMaxRetry; ++i) {
533*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mReleasing.mLock);
534*4d7e907cSAndroid Build Coastguard Worker int64_t now = ::android::elapsedRealtime();
535*4d7e907cSAndroid Build Coastguard Worker if (timestampMs == 0 || now < timestampMs) {
536*4d7e907cSAndroid Build Coastguard Worker bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
537*4d7e907cSAndroid Build Coastguard Worker transactionId, bufferId, BufferStatus::TRANSFER_FROM,
538*4d7e907cSAndroid Build Coastguard Worker mConnectionId, -1, mReleasing.mReleasingIds,
539*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasedIds);
540*4d7e907cSAndroid Build Coastguard Worker if (result) {
541*4d7e907cSAndroid Build Coastguard Worker return true;
542*4d7e907cSAndroid Build Coastguard Worker }
543*4d7e907cSAndroid Build Coastguard Worker lock.unlock();
544*4d7e907cSAndroid Build Coastguard Worker std::this_thread::yield();
545*4d7e907cSAndroid Build Coastguard Worker } else {
546*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel->postBufferStatusMessage(
547*4d7e907cSAndroid Build Coastguard Worker transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
548*4d7e907cSAndroid Build Coastguard Worker mConnectionId, -1, mReleasing.mReleasingIds,
549*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasedIds);
550*4d7e907cSAndroid Build Coastguard Worker return false;
551*4d7e907cSAndroid Build Coastguard Worker }
552*4d7e907cSAndroid Build Coastguard Worker }
553*4d7e907cSAndroid Build Coastguard Worker return false;
554*4d7e907cSAndroid Build Coastguard Worker }
555*4d7e907cSAndroid Build Coastguard Worker
postReceiveResult(BufferId bufferId,TransactionId transactionId,bool result,bool * needsSync)556*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::Impl::postReceiveResult(
557*4d7e907cSAndroid Build Coastguard Worker BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync) {
558*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
559*4d7e907cSAndroid Build Coastguard Worker // TODO: retry, add timeout
560*4d7e907cSAndroid Build Coastguard Worker bool ret = mReleasing.mStatusChannel->postBufferStatusMessage(
561*4d7e907cSAndroid Build Coastguard Worker transactionId, bufferId,
562*4d7e907cSAndroid Build Coastguard Worker result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
563*4d7e907cSAndroid Build Coastguard Worker mConnectionId, -1, mReleasing.mReleasingIds,
564*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasedIds);
565*4d7e907cSAndroid Build Coastguard Worker *needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
566*4d7e907cSAndroid Build Coastguard Worker return ret;
567*4d7e907cSAndroid Build Coastguard Worker }
568*4d7e907cSAndroid Build Coastguard Worker
trySyncFromRemote()569*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::trySyncFromRemote() {
570*4d7e907cSAndroid Build Coastguard Worker if (mRemoteSyncLock.try_lock()) {
571*4d7e907cSAndroid Build Coastguard Worker bool needsSync = false;
572*4d7e907cSAndroid Build Coastguard Worker {
573*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
574*4d7e907cSAndroid Build Coastguard Worker needsSync = mReleasing.mStatusChannel->needsSync();
575*4d7e907cSAndroid Build Coastguard Worker }
576*4d7e907cSAndroid Build Coastguard Worker if (needsSync) {
577*4d7e907cSAndroid Build Coastguard Worker if (!mRemoteConnection->sync().isOk()) {
578*4d7e907cSAndroid Build Coastguard Worker ALOGD("sync from client %lld failed: bufferpool process died.",
579*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId);
580*4d7e907cSAndroid Build Coastguard Worker }
581*4d7e907cSAndroid Build Coastguard Worker }
582*4d7e907cSAndroid Build Coastguard Worker mRemoteSyncLock.unlock();
583*4d7e907cSAndroid Build Coastguard Worker }
584*4d7e907cSAndroid Build Coastguard Worker }
585*4d7e907cSAndroid Build Coastguard Worker
586*4d7e907cSAndroid Build Coastguard Worker // should have mCache.mLock
syncReleased(uint32_t messageId)587*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) {
588*4d7e907cSAndroid Build Coastguard Worker bool cleared = false;
589*4d7e907cSAndroid Build Coastguard Worker {
590*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
591*4d7e907cSAndroid Build Coastguard Worker if (mReleasing.mReleasingIds.size() > 0) {
592*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel->postBufferRelease(
593*4d7e907cSAndroid Build Coastguard Worker mConnectionId, mReleasing.mReleasingIds,
594*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasedIds);
595*4d7e907cSAndroid Build Coastguard Worker }
596*4d7e907cSAndroid Build Coastguard Worker if (mReleasing.mReleasedIds.size() > 0) {
597*4d7e907cSAndroid Build Coastguard Worker for (BufferId& id: mReleasing.mReleasedIds) {
598*4d7e907cSAndroid Build Coastguard Worker ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
599*4d7e907cSAndroid Build Coastguard Worker auto found = mCache.mBuffers.find(id);
600*4d7e907cSAndroid Build Coastguard Worker if (found != mCache.mBuffers.end()) {
601*4d7e907cSAndroid Build Coastguard Worker if (found->second->onCacheRelease()) {
602*4d7e907cSAndroid Build Coastguard Worker mCache.decActive_l();
603*4d7e907cSAndroid Build Coastguard Worker } else {
604*4d7e907cSAndroid Build Coastguard Worker // should not happen!
605*4d7e907cSAndroid Build Coastguard Worker ALOGW("client %lld cache release status inconsistent!",
606*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId);
607*4d7e907cSAndroid Build Coastguard Worker }
608*4d7e907cSAndroid Build Coastguard Worker } else {
609*4d7e907cSAndroid Build Coastguard Worker // should not happen!
610*4d7e907cSAndroid Build Coastguard Worker ALOGW("client %lld cache status inconsistent!", (long long)mConnectionId);
611*4d7e907cSAndroid Build Coastguard Worker }
612*4d7e907cSAndroid Build Coastguard Worker }
613*4d7e907cSAndroid Build Coastguard Worker mReleasing.mReleasedIds.clear();
614*4d7e907cSAndroid Build Coastguard Worker cleared = true;
615*4d7e907cSAndroid Build Coastguard Worker }
616*4d7e907cSAndroid Build Coastguard Worker }
617*4d7e907cSAndroid Build Coastguard Worker std::vector<BufferInvalidationMessage> invalidations;
618*4d7e907cSAndroid Build Coastguard Worker mInvalidationListener->getInvalidations(invalidations);
619*4d7e907cSAndroid Build Coastguard Worker uint32_t lastMsgId = 0;
620*4d7e907cSAndroid Build Coastguard Worker if (invalidations.size() > 0) {
621*4d7e907cSAndroid Build Coastguard Worker for (auto it = invalidations.begin(); it != invalidations.end(); ++it) {
622*4d7e907cSAndroid Build Coastguard Worker if (it->messageId != 0) {
623*4d7e907cSAndroid Build Coastguard Worker lastMsgId = it->messageId;
624*4d7e907cSAndroid Build Coastguard Worker }
625*4d7e907cSAndroid Build Coastguard Worker if (it->fromBufferId == it->toBufferId) {
626*4d7e907cSAndroid Build Coastguard Worker // TODO: handle fromBufferId = UINT32_MAX
627*4d7e907cSAndroid Build Coastguard Worker invalidateBuffer(it->fromBufferId);
628*4d7e907cSAndroid Build Coastguard Worker } else {
629*4d7e907cSAndroid Build Coastguard Worker invalidateRange(it->fromBufferId, it->toBufferId);
630*4d7e907cSAndroid Build Coastguard Worker }
631*4d7e907cSAndroid Build Coastguard Worker }
632*4d7e907cSAndroid Build Coastguard Worker }
633*4d7e907cSAndroid Build Coastguard Worker {
634*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mReleasing.mLock);
635*4d7e907cSAndroid Build Coastguard Worker if (lastMsgId != 0) {
636*4d7e907cSAndroid Build Coastguard Worker if (isMessageLater(lastMsgId, mReleasing.mInvalidateId)) {
637*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateId = lastMsgId;
638*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateAck = false;
639*4d7e907cSAndroid Build Coastguard Worker }
640*4d7e907cSAndroid Build Coastguard Worker } else if (messageId != 0) {
641*4d7e907cSAndroid Build Coastguard Worker // messages are drained.
642*4d7e907cSAndroid Build Coastguard Worker if (isMessageLater(messageId, mReleasing.mInvalidateId)) {
643*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateId = messageId;
644*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateAck = true;
645*4d7e907cSAndroid Build Coastguard Worker }
646*4d7e907cSAndroid Build Coastguard Worker }
647*4d7e907cSAndroid Build Coastguard Worker if (!mReleasing.mInvalidateAck) {
648*4d7e907cSAndroid Build Coastguard Worker // post ACK
649*4d7e907cSAndroid Build Coastguard Worker mReleasing.mStatusChannel->postBufferInvalidateAck(
650*4d7e907cSAndroid Build Coastguard Worker mConnectionId,
651*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateId, &mReleasing.mInvalidateAck);
652*4d7e907cSAndroid Build Coastguard Worker ALOGV("client %lld invalidateion ack (%d) %u",
653*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId,
654*4d7e907cSAndroid Build Coastguard Worker mReleasing.mInvalidateAck, mReleasing.mInvalidateId);
655*4d7e907cSAndroid Build Coastguard Worker }
656*4d7e907cSAndroid Build Coastguard Worker }
657*4d7e907cSAndroid Build Coastguard Worker return cleared;
658*4d7e907cSAndroid Build Coastguard Worker }
659*4d7e907cSAndroid Build Coastguard Worker
660*4d7e907cSAndroid Build Coastguard Worker // should have mCache.mLock
evictCaches(bool clearCache)661*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::evictCaches(bool clearCache) {
662*4d7e907cSAndroid Build Coastguard Worker int64_t now = ::android::elapsedRealtime();
663*4d7e907cSAndroid Build Coastguard Worker if (now >= mLastEvictCacheMs + kCacheTtlMs ||
664*4d7e907cSAndroid Build Coastguard Worker clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
665*4d7e907cSAndroid Build Coastguard Worker size_t evicted = 0;
666*4d7e907cSAndroid Build Coastguard Worker for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
667*4d7e907cSAndroid Build Coastguard Worker if (!it->second->hasCache() && (it->second->expire() ||
668*4d7e907cSAndroid Build Coastguard Worker clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
669*4d7e907cSAndroid Build Coastguard Worker it = mCache.mBuffers.erase(it);
670*4d7e907cSAndroid Build Coastguard Worker ++evicted;
671*4d7e907cSAndroid Build Coastguard Worker } else {
672*4d7e907cSAndroid Build Coastguard Worker ++it;
673*4d7e907cSAndroid Build Coastguard Worker }
674*4d7e907cSAndroid Build Coastguard Worker }
675*4d7e907cSAndroid Build Coastguard Worker ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
676*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
677*4d7e907cSAndroid Build Coastguard Worker mLastEvictCacheMs = now;
678*4d7e907cSAndroid Build Coastguard Worker }
679*4d7e907cSAndroid Build Coastguard Worker }
680*4d7e907cSAndroid Build Coastguard Worker
681*4d7e907cSAndroid Build Coastguard Worker // should have mCache.mLock
invalidateBuffer(BufferId id)682*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::invalidateBuffer(BufferId id) {
683*4d7e907cSAndroid Build Coastguard Worker for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end(); ++it) {
684*4d7e907cSAndroid Build Coastguard Worker if (id == it->second->id()) {
685*4d7e907cSAndroid Build Coastguard Worker if (!it->second->hasCache()) {
686*4d7e907cSAndroid Build Coastguard Worker mCache.mBuffers.erase(it);
687*4d7e907cSAndroid Build Coastguard Worker ALOGV("cache invalidated %lld : buffer %u",
688*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId, id);
689*4d7e907cSAndroid Build Coastguard Worker } else {
690*4d7e907cSAndroid Build Coastguard Worker ALOGW("Inconsistent invalidation %lld : activer buffer!! %u",
691*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId, (unsigned int)id);
692*4d7e907cSAndroid Build Coastguard Worker }
693*4d7e907cSAndroid Build Coastguard Worker break;
694*4d7e907cSAndroid Build Coastguard Worker }
695*4d7e907cSAndroid Build Coastguard Worker }
696*4d7e907cSAndroid Build Coastguard Worker }
697*4d7e907cSAndroid Build Coastguard Worker
698*4d7e907cSAndroid Build Coastguard Worker // should have mCache.mLock
invalidateRange(BufferId from,BufferId to)699*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::Impl::invalidateRange(BufferId from, BufferId to) {
700*4d7e907cSAndroid Build Coastguard Worker size_t invalidated = 0;
701*4d7e907cSAndroid Build Coastguard Worker for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
702*4d7e907cSAndroid Build Coastguard Worker if (!it->second->hasCache()) {
703*4d7e907cSAndroid Build Coastguard Worker BufferId bid = it->second->id();
704*4d7e907cSAndroid Build Coastguard Worker if (from < to) {
705*4d7e907cSAndroid Build Coastguard Worker if (from <= bid && bid < to) {
706*4d7e907cSAndroid Build Coastguard Worker ++invalidated;
707*4d7e907cSAndroid Build Coastguard Worker it = mCache.mBuffers.erase(it);
708*4d7e907cSAndroid Build Coastguard Worker continue;
709*4d7e907cSAndroid Build Coastguard Worker }
710*4d7e907cSAndroid Build Coastguard Worker } else {
711*4d7e907cSAndroid Build Coastguard Worker if (from <= bid || bid < to) {
712*4d7e907cSAndroid Build Coastguard Worker ++invalidated;
713*4d7e907cSAndroid Build Coastguard Worker it = mCache.mBuffers.erase(it);
714*4d7e907cSAndroid Build Coastguard Worker continue;
715*4d7e907cSAndroid Build Coastguard Worker }
716*4d7e907cSAndroid Build Coastguard Worker }
717*4d7e907cSAndroid Build Coastguard Worker }
718*4d7e907cSAndroid Build Coastguard Worker ++it;
719*4d7e907cSAndroid Build Coastguard Worker }
720*4d7e907cSAndroid Build Coastguard Worker ALOGV("cache invalidated %lld : # of invalidated %zu",
721*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId, invalidated);
722*4d7e907cSAndroid Build Coastguard Worker }
723*4d7e907cSAndroid Build Coastguard Worker
allocateBufferHandle(const std::vector<uint8_t> & params,BufferId * bufferId,native_handle_t ** handle)724*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::Impl::allocateBufferHandle(
725*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t>& params, BufferId *bufferId,
726*4d7e907cSAndroid Build Coastguard Worker native_handle_t** handle) {
727*4d7e907cSAndroid Build Coastguard Worker if (mLocalConnection) {
728*4d7e907cSAndroid Build Coastguard Worker const native_handle_t* allocHandle = nullptr;
729*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus status = mLocalConnection->allocate(
730*4d7e907cSAndroid Build Coastguard Worker params, bufferId, &allocHandle);
731*4d7e907cSAndroid Build Coastguard Worker if (status == ResultStatus::OK) {
732*4d7e907cSAndroid Build Coastguard Worker *handle = native_handle_clone(allocHandle);
733*4d7e907cSAndroid Build Coastguard Worker }
734*4d7e907cSAndroid Build Coastguard Worker ALOGV("client allocate result %lld %d : %u clone %p",
735*4d7e907cSAndroid Build Coastguard Worker (long long)mConnectionId, status == ResultStatus::OK,
736*4d7e907cSAndroid Build Coastguard Worker *handle ? *bufferId : 0 , *handle);
737*4d7e907cSAndroid Build Coastguard Worker return status;
738*4d7e907cSAndroid Build Coastguard Worker }
739*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
740*4d7e907cSAndroid Build Coastguard Worker }
741*4d7e907cSAndroid Build Coastguard Worker
fetchBufferHandle(TransactionId transactionId,BufferId bufferId,native_handle_t ** handle)742*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::Impl::fetchBufferHandle(
743*4d7e907cSAndroid Build Coastguard Worker TransactionId transactionId, BufferId bufferId,
744*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle) {
745*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IConnection> connection;
746*4d7e907cSAndroid Build Coastguard Worker if (mLocal) {
747*4d7e907cSAndroid Build Coastguard Worker connection = mLocalConnection;
748*4d7e907cSAndroid Build Coastguard Worker } else {
749*4d7e907cSAndroid Build Coastguard Worker connection = mRemoteConnection;
750*4d7e907cSAndroid Build Coastguard Worker }
751*4d7e907cSAndroid Build Coastguard Worker if (!connection) {
752*4d7e907cSAndroid Build Coastguard Worker ALOGE("connection null: fetchBufferHandle()");
753*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
754*4d7e907cSAndroid Build Coastguard Worker }
755*4d7e907cSAndroid Build Coastguard Worker std::vector<FetchInfo> infos;
756*4d7e907cSAndroid Build Coastguard Worker std::vector<FetchResult> results;
757*4d7e907cSAndroid Build Coastguard Worker infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
758*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus status = connection->fetch(infos, &results);
759*4d7e907cSAndroid Build Coastguard Worker if (!status.isOk()) {
760*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus svcSpecific = status.getServiceSpecificError();
761*4d7e907cSAndroid Build Coastguard Worker return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
762*4d7e907cSAndroid Build Coastguard Worker }
763*4d7e907cSAndroid Build Coastguard Worker if (results[0].getTag() == FetchResult::buffer) {
764*4d7e907cSAndroid Build Coastguard Worker if (results[0].get<FetchResult::buffer>().buffer.has_value()) {
765*4d7e907cSAndroid Build Coastguard Worker *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer.value());
766*4d7e907cSAndroid Build Coastguard Worker } else {
767*4d7e907cSAndroid Build Coastguard Worker // TODO: Support HardwareBuffer
768*4d7e907cSAndroid Build Coastguard Worker ALOGW("handle nullptr");
769*4d7e907cSAndroid Build Coastguard Worker *handle = nullptr;
770*4d7e907cSAndroid Build Coastguard Worker }
771*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::OK;
772*4d7e907cSAndroid Build Coastguard Worker }
773*4d7e907cSAndroid Build Coastguard Worker return results[0].get<FetchResult::failure>();
774*4d7e907cSAndroid Build Coastguard Worker }
775*4d7e907cSAndroid Build Coastguard Worker
776*4d7e907cSAndroid Build Coastguard Worker
BufferPoolClient(const std::shared_ptr<Accessor> & accessor,const std::shared_ptr<IObserver> & observer)777*4d7e907cSAndroid Build Coastguard Worker BufferPoolClient::BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
778*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer) {
779*4d7e907cSAndroid Build Coastguard Worker mImpl = std::make_shared<Impl>(accessor, observer);
780*4d7e907cSAndroid Build Coastguard Worker }
781*4d7e907cSAndroid Build Coastguard Worker
BufferPoolClient(const std::shared_ptr<IAccessor> & accessor,const std::shared_ptr<IObserver> & observer)782*4d7e907cSAndroid Build Coastguard Worker BufferPoolClient::BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
783*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<IObserver> &observer) {
784*4d7e907cSAndroid Build Coastguard Worker mImpl = std::make_shared<Impl>(accessor, observer);
785*4d7e907cSAndroid Build Coastguard Worker }
786*4d7e907cSAndroid Build Coastguard Worker
~BufferPoolClient()787*4d7e907cSAndroid Build Coastguard Worker BufferPoolClient::~BufferPoolClient() {
788*4d7e907cSAndroid Build Coastguard Worker // TODO: how to handle orphaned buffers?
789*4d7e907cSAndroid Build Coastguard Worker }
790*4d7e907cSAndroid Build Coastguard Worker
isValid()791*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::isValid() {
792*4d7e907cSAndroid Build Coastguard Worker return mImpl && mImpl->isValid();
793*4d7e907cSAndroid Build Coastguard Worker }
794*4d7e907cSAndroid Build Coastguard Worker
isLocal()795*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::isLocal() {
796*4d7e907cSAndroid Build Coastguard Worker return mImpl && mImpl->isLocal();
797*4d7e907cSAndroid Build Coastguard Worker }
798*4d7e907cSAndroid Build Coastguard Worker
isActive(int64_t * lastTransactionMs,bool clearCache)799*4d7e907cSAndroid Build Coastguard Worker bool BufferPoolClient::isActive(int64_t *lastTransactionMs, bool clearCache) {
800*4d7e907cSAndroid Build Coastguard Worker if (!isValid()) {
801*4d7e907cSAndroid Build Coastguard Worker *lastTransactionMs = 0;
802*4d7e907cSAndroid Build Coastguard Worker return false;
803*4d7e907cSAndroid Build Coastguard Worker }
804*4d7e907cSAndroid Build Coastguard Worker return mImpl->isActive(lastTransactionMs, clearCache);
805*4d7e907cSAndroid Build Coastguard Worker }
806*4d7e907cSAndroid Build Coastguard Worker
getConnectionId()807*4d7e907cSAndroid Build Coastguard Worker ConnectionId BufferPoolClient::getConnectionId() {
808*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
809*4d7e907cSAndroid Build Coastguard Worker return mImpl->getConnectionId();
810*4d7e907cSAndroid Build Coastguard Worker }
811*4d7e907cSAndroid Build Coastguard Worker return -1;
812*4d7e907cSAndroid Build Coastguard Worker }
813*4d7e907cSAndroid Build Coastguard Worker
getAccessor(std::shared_ptr<IAccessor> * accessor)814*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::getAccessor(std::shared_ptr<IAccessor> *accessor) {
815*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
816*4d7e907cSAndroid Build Coastguard Worker *accessor = mImpl->getAccessor();
817*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::OK;
818*4d7e907cSAndroid Build Coastguard Worker }
819*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
820*4d7e907cSAndroid Build Coastguard Worker }
821*4d7e907cSAndroid Build Coastguard Worker
receiveInvalidation(uint32_t msgId)822*4d7e907cSAndroid Build Coastguard Worker void BufferPoolClient::receiveInvalidation(uint32_t msgId) {
823*4d7e907cSAndroid Build Coastguard Worker ALOGV("bufferpool2 client recv inv %u", msgId);
824*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
825*4d7e907cSAndroid Build Coastguard Worker mImpl->receiveInvalidation(msgId);
826*4d7e907cSAndroid Build Coastguard Worker }
827*4d7e907cSAndroid Build Coastguard Worker }
828*4d7e907cSAndroid Build Coastguard Worker
flush()829*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::flush() {
830*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
831*4d7e907cSAndroid Build Coastguard Worker return mImpl->flush();
832*4d7e907cSAndroid Build Coastguard Worker }
833*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
834*4d7e907cSAndroid Build Coastguard Worker }
835*4d7e907cSAndroid Build Coastguard Worker
allocate(const std::vector<uint8_t> & params,native_handle_t ** handle,std::shared_ptr<BufferPoolData> * buffer)836*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::allocate(
837*4d7e907cSAndroid Build Coastguard Worker const std::vector<uint8_t> ¶ms,
838*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle,
839*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<BufferPoolData> *buffer) {
840*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
841*4d7e907cSAndroid Build Coastguard Worker return mImpl->allocate(params, handle, buffer);
842*4d7e907cSAndroid Build Coastguard Worker }
843*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
844*4d7e907cSAndroid Build Coastguard Worker }
845*4d7e907cSAndroid Build Coastguard Worker
receive(TransactionId transactionId,BufferId bufferId,int64_t timestampMs,native_handle_t ** handle,std::shared_ptr<BufferPoolData> * buffer)846*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::receive(
847*4d7e907cSAndroid Build Coastguard Worker TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
848*4d7e907cSAndroid Build Coastguard Worker native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
849*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
850*4d7e907cSAndroid Build Coastguard Worker return mImpl->receive(transactionId, bufferId, timestampMs, handle, buffer);
851*4d7e907cSAndroid Build Coastguard Worker }
852*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
853*4d7e907cSAndroid Build Coastguard Worker }
854*4d7e907cSAndroid Build Coastguard Worker
postSend(ConnectionId receiverId,const std::shared_ptr<BufferPoolData> & buffer,TransactionId * transactionId,int64_t * timestampMs)855*4d7e907cSAndroid Build Coastguard Worker BufferPoolStatus BufferPoolClient::postSend(
856*4d7e907cSAndroid Build Coastguard Worker ConnectionId receiverId,
857*4d7e907cSAndroid Build Coastguard Worker const std::shared_ptr<BufferPoolData> &buffer,
858*4d7e907cSAndroid Build Coastguard Worker TransactionId *transactionId,
859*4d7e907cSAndroid Build Coastguard Worker int64_t *timestampMs) {
860*4d7e907cSAndroid Build Coastguard Worker if (isValid()) {
861*4d7e907cSAndroid Build Coastguard Worker bool result = mImpl->postSend(
862*4d7e907cSAndroid Build Coastguard Worker buffer->mId, receiverId, transactionId, timestampMs);
863*4d7e907cSAndroid Build Coastguard Worker return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
864*4d7e907cSAndroid Build Coastguard Worker }
865*4d7e907cSAndroid Build Coastguard Worker return ResultStatus::CRITICAL_ERROR;
866*4d7e907cSAndroid Build Coastguard Worker }
867*4d7e907cSAndroid Build Coastguard Worker
868*4d7e907cSAndroid Build Coastguard Worker } // namespace aidl::android::hardware::media::bufferpool2::implementation
869