blob: e05b12a15628ec0bfd13a9187f267fafe0c3e6c6 [file] [log] [blame]
Sungtak Leebbe37b62018-08-29 15:15:48 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#define LOG_TAG "BufferPoolConnection"
17
18#include "Accessor.h"
19#include "AccessorImpl.h"
20#include "Connection.h"
21
22namespace android {
23namespace hardware {
24namespace media {
25namespace bufferpool {
26namespace V2_0 {
27namespace implementation {
28
29void ConnectionDeathRecipient::add(
30 int64_t connectionId,
31 const sp<Accessor> &accessor) {
32 std::lock_guard<std::mutex> lock(mLock);
33 if (mAccessors.find(connectionId) == mAccessors.end()) {
34 mAccessors.insert(std::make_pair(connectionId, accessor));
35 }
36}
37
38void ConnectionDeathRecipient::remove(int64_t connectionId) {
39 std::lock_guard<std::mutex> lock(mLock);
40 mAccessors.erase(connectionId);
41 auto it = mConnectionToCookie.find(connectionId);
42 if (it != mConnectionToCookie.end()) {
43 uint64_t cookie = it->second;
44 mConnectionToCookie.erase(it);
45 auto cit = mCookieToConnections.find(cookie);
46 if (cit != mCookieToConnections.end()) {
47 cit->second.erase(connectionId);
48 if (cit->second.size() == 0) {
49 mCookieToConnections.erase(cit);
50 }
51 }
52 }
53}
54
55void ConnectionDeathRecipient::addCookieToConnection(
56 uint64_t cookie,
57 int64_t connectionId) {
58 std::lock_guard<std::mutex> lock(mLock);
59 if (mAccessors.find(connectionId) == mAccessors.end()) {
60 return;
61 }
62 mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
63 auto it = mCookieToConnections.find(cookie);
64 if (it != mCookieToConnections.end()) {
65 it->second.insert(connectionId);
66 } else {
67 mCookieToConnections.insert(std::make_pair(
68 cookie, std::set<int64_t>{connectionId}));
69 }
70}
71
72void ConnectionDeathRecipient::serviceDied(
73 uint64_t cookie,
74 const wp<::android::hidl::base::V1_0::IBase>& /* who */
75 ) {
76 std::map<int64_t, const wp<Accessor>> connectionsToClose;
77 {
78 std::lock_guard<std::mutex> lock(mLock);
79
80 auto it = mCookieToConnections.find(cookie);
81 if (it != mCookieToConnections.end()) {
82 for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
83 auto accessorIt = mAccessors.find(*conIt);
84 if (accessorIt != mAccessors.end()) {
85 connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
86 mAccessors.erase(accessorIt);
87 }
88 mConnectionToCookie.erase(*conIt);
89 }
90 mCookieToConnections.erase(it);
91 }
92 }
93
94 if (connectionsToClose.size() > 0) {
95 sp<Accessor> accessor;
96 for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
97 accessor = it->second.promote();
98
99 if (accessor) {
100 accessor->close(it->first);
101 ALOGD("connection %lld closed on death", (long long)it->first);
102 }
103 }
104 }
105}
106
107namespace {
108static sp<ConnectionDeathRecipient> sConnectionDeathRecipient =
109 new ConnectionDeathRecipient();
110}
111
112sp<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
113 return sConnectionDeathRecipient;
114}
115
Sungtak Leed3128382018-11-07 17:30:37 -0800116void Accessor::createInvalidator() {
117 Accessor::Impl::createInvalidator();
118}
119
Sungtak Lee7651a272020-04-27 00:16:50 -0700120void Accessor::createEvictor() {
121 Accessor::Impl::createEvictor();
122}
123
Sungtak Leebbe37b62018-08-29 15:15:48 -0700124// Methods from ::android::hardware::media::bufferpool::V2_0::IAccessor follow.
Sungtak Leed491f1f2018-10-05 15:56:56 -0700125Return<void> Accessor::connect(
126 const sp<::android::hardware::media::bufferpool::V2_0::IObserver>& observer,
127 connect_cb _hidl_cb) {
Sungtak Leebbe37b62018-08-29 15:15:48 -0700128 sp<Connection> connection;
129 ConnectionId connectionId;
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700130 uint32_t msgId;
Sungtak Lee1cb0ccb2018-09-05 14:47:36 -0700131 const StatusDescriptor* fmqDesc;
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700132 const InvalidationDescriptor* invDesc;
Sungtak Leebbe37b62018-08-29 15:15:48 -0700133
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700134 ResultStatus status = connect(
135 observer, false, &connection, &connectionId, &msgId, &fmqDesc, &invDesc);
Sungtak Leebbe37b62018-08-29 15:15:48 -0700136 if (status == ResultStatus::OK) {
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700137 _hidl_cb(status, connection, connectionId, msgId, *fmqDesc, *invDesc);
Sungtak Leebbe37b62018-08-29 15:15:48 -0700138 } else {
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700139 _hidl_cb(status, nullptr, -1LL, 0,
Sungtak Leebbe37b62018-08-29 15:15:48 -0700140 android::hardware::MQDescriptorSync<BufferStatusMessage>(
141 std::vector<android::hardware::GrantorDescriptor>(),
Sungtak Lee1cb0ccb2018-09-05 14:47:36 -0700142 nullptr /* nhandle */, 0 /* size */),
Sungtak Leeae729462018-09-28 13:15:48 -0700143 android::hardware::MQDescriptorUnsync<BufferInvalidationMessage>(
Sungtak Lee1cb0ccb2018-09-05 14:47:36 -0700144 std::vector<android::hardware::GrantorDescriptor>(),
Sungtak Leebbe37b62018-08-29 15:15:48 -0700145 nullptr /* nhandle */, 0 /* size */));
146 }
147 return Void();
148}
149
150Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
151 : mImpl(new Impl(allocator)) {}
152
153Accessor::~Accessor() {
154}
155
156bool Accessor::isValid() {
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700157 return (bool)mImpl && mImpl->isValid();
158}
159
160ResultStatus Accessor::flush() {
161 if (mImpl) {
162 mImpl->flush();
163 return ResultStatus::OK;
164 }
165 return ResultStatus::CRITICAL_ERROR;
Sungtak Leebbe37b62018-08-29 15:15:48 -0700166}
167
168ResultStatus Accessor::allocate(
169 ConnectionId connectionId,
170 const std::vector<uint8_t> &params,
171 BufferId *bufferId, const native_handle_t** handle) {
172 if (mImpl) {
173 return mImpl->allocate(connectionId, params, bufferId, handle);
174 }
175 return ResultStatus::CRITICAL_ERROR;
176}
177
178ResultStatus Accessor::fetch(
179 ConnectionId connectionId, TransactionId transactionId,
180 BufferId bufferId, const native_handle_t** handle) {
181 if (mImpl) {
182 return mImpl->fetch(connectionId, transactionId, bufferId, handle);
183 }
184 return ResultStatus::CRITICAL_ERROR;
185}
186
187ResultStatus Accessor::connect(
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700188 const sp<IObserver> &observer, bool local,
Sungtak Leebbe37b62018-08-29 15:15:48 -0700189 sp<Connection> *connection, ConnectionId *pConnectionId,
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700190 uint32_t *pMsgId,
191 const StatusDescriptor** statusDescPtr,
192 const InvalidationDescriptor** invDescPtr) {
Sungtak Leebbe37b62018-08-29 15:15:48 -0700193 if (mImpl) {
Sungtak Leec7f9e2c2018-09-14 16:23:40 -0700194 ResultStatus status = mImpl->connect(
195 this, observer, connection, pConnectionId, pMsgId,
196 statusDescPtr, invDescPtr);
Sungtak Leebbe37b62018-08-29 15:15:48 -0700197 if (!local && status == ResultStatus::OK) {
198 sp<Accessor> accessor(this);
199 sConnectionDeathRecipient->add(*pConnectionId, accessor);
200 }
201 return status;
202 }
203 return ResultStatus::CRITICAL_ERROR;
204}
205
206ResultStatus Accessor::close(ConnectionId connectionId) {
207 if (mImpl) {
208 ResultStatus status = mImpl->close(connectionId);
209 sConnectionDeathRecipient->remove(connectionId);
210 return status;
211 }
212 return ResultStatus::CRITICAL_ERROR;
213}
214
215void Accessor::cleanUp(bool clearCache) {
216 if (mImpl) {
217 mImpl->cleanUp(clearCache);
218 }
219}
220
221//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
222// return new Accessor();
223//}
224
225} // namespace implementation
226} // namespace V2_0
227} // namespace bufferpool
228} // namespace media
229} // namespace hardware
230} // namespace android