blob: cdb1f91795c826bfa94863950a9b7506c14b42e1 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "buffer_hub.h"
2
Corey Tabakacd52dd92017-04-07 18:03:57 -07003#include <inttypes.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -08004#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#include <poll.h>
6#include <utils/Trace.h>
7
8#include <iomanip>
9#include <sstream>
10#include <string>
11#include <thread>
12
13#include <pdx/default_transport/service_endpoint.h>
14#include <private/dvr/bufferhub_rpc.h>
15#include "consumer_channel.h"
16#include "producer_channel.h"
17#include "producer_queue_channel.h"
18
19using android::pdx::Channel;
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070020using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080021using android::pdx::Message;
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070022using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080023using android::pdx::default_transport::Endpoint;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070024using android::pdx::rpc::DispatchRemoteMethod;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080025
26namespace android {
27namespace dvr {
28
29BufferHubService::BufferHubService()
30 : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
31
32BufferHubService::~BufferHubService() {}
33
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070034bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035
36std::string BufferHubService::DumpState(size_t /*max_length*/) {
37 std::ostringstream stream;
38 auto channels = GetChannels<BufferHubChannel>();
39
40 std::sort(channels.begin(), channels.end(),
41 [](const std::shared_ptr<BufferHubChannel>& a,
42 const std::shared_ptr<BufferHubChannel>& b) {
43 return a->buffer_id() < b->buffer_id();
44 });
45
46 stream << "Active Producer Buffers:\n";
47 stream << std::right;
48 stream << std::setw(6) << "Id";
49 stream << " ";
50 stream << std::setw(9) << "Consumers";
51 stream << " ";
52 stream << std::setw(14) << "Geometry";
53 stream << " ";
54 stream << std::setw(6) << "Format";
55 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070056 stream << std::setw(10) << "Usage";
57 stream << " ";
58 stream << std::setw(9) << "Pending";
59 stream << " ";
60 stream << std::setw(18) << "State";
61 stream << " ";
62 stream << std::setw(18) << "Signaled";
63 stream << " ";
64 stream << std::setw(10) << "Index";
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080065 stream << " ";
66 stream << "Name";
67 stream << std::endl;
68
69 for (const auto& channel : channels) {
70 if (channel->channel_type() == BufferHubChannel::kProducerType) {
71 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
72
73 stream << std::right;
74 stream << std::setw(6) << info.id;
75 stream << " ";
76 stream << std::setw(9) << info.consumer_count;
77 stream << " ";
78 if (info.format == HAL_PIXEL_FORMAT_BLOB) {
79 std::string size = std::to_string(info.width) + " B";
80 stream << std::setw(14) << size;
81 } else {
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070082 std::string dimensions = std::to_string(info.width) + "x" +
83 std::to_string(info.height) + "x" +
84 std::to_string(info.layer_count);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085 stream << std::setw(14) << dimensions;
86 }
87 stream << " ";
88 stream << std::setw(6) << info.format;
89 stream << " ";
90 stream << "0x" << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -070091 stream << std::setw(8) << info.usage;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092 stream << std::dec << std::setfill(' ');
93 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070094 stream << std::setw(9) << info.pending_count;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080095 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070096 stream << "0x" << std::hex << std::setfill('0');
97 stream << std::setw(16) << info.state;
98 stream << " ";
99 stream << "0x" << std::setw(16) << info.signaled_mask;
100 stream << std::dec << std::setfill(' ');
101 stream << " ";
102 stream << std::setw(8) << info.index;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800103 stream << " ";
104 stream << info.name;
105 stream << std::endl;
106 }
107 }
108
109 stream << std::endl;
110 stream << "Active Producer Queues:\n";
111 stream << std::right << std::setw(6) << "Id";
Corey Tabaka8a4e6a92017-04-20 13:42:02 -0700112 stream << std::right << std::setw(12) << " Capacity";
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800113 stream << std::right << std::setw(12) << " Consumers";
114 stream << " UsageSetMask";
115 stream << " UsageClearMask";
116 stream << " UsageDenySetMask";
117 stream << " UsageDenyClearMask";
118 stream << " ";
119 stream << std::endl;
120
121 for (const auto& channel : channels) {
122 if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
123 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
124
125 stream << std::dec << std::setfill(' ');
126 stream << std::right << std::setw(6) << info.id;
127 stream << std::right << std::setw(12) << info.capacity;
128 stream << std::right << std::setw(12) << info.consumer_count;
129 stream << std::setw(5) << std::setfill(' ') << "0x";
130 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700131 stream << std::setw(8) << info.usage_policy.usage_set_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800132 stream << std::setw(7) << std::setfill(' ') << "0x";
133 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700134 stream << std::setw(8) << info.usage_policy.usage_clear_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800135 stream << std::setw(9) << std::setfill(' ') << "0x";
136 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700137 stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800138 stream << std::setw(11) << std::setfill(' ') << "0x";
139 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700140 stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700141 stream << std::hex << std::setfill('0');
142 stream << std::endl;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800143 }
144 }
145
146 stream << std::endl;
147 stream << "Active Consumer Queues:\n";
148 stream << std::dec << std::setfill(' ');
149 stream << std::right << std::setw(6) << "Id";
150 stream << std::right << std::setw(12) << " Imported";
151 stream << " ";
152 stream << std::endl;
153
154 for (const auto& channel : channels) {
155 if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
156 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
157
158 stream << std::right << std::setw(6) << info.id;
159 stream << std::right << std::setw(12) << info.capacity;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700160 stream << std::endl;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800161 }
162 }
163
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700164 stream << std::endl;
165 stream << "Orphaned Consumer Buffers:\n";
166 stream << std::right;
167 stream << std::setw(6) << "Id";
168 stream << " ";
169 stream << std::setw(14) << "Geometry";
170 stream << " ";
171 stream << "Name";
172 stream << std::endl;
173
174 for (const auto& channel : channels) {
175 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
176 // consumer_count is tracked by producer. When it's zero, producer must have
177 // already hung up and the consumer is orphaned.
178 if (channel->channel_type() == BufferHubChannel::kConsumerType &&
179 info.consumer_count == 0) {
180 stream << std::right;
181 stream << std::setw(6) << info.id;
182 stream << " ";
183
184 stream << std::setw(14) << "Orphaned.";
185 stream << (" channel_id=" + std::to_string(channel->channel_id()));
186 stream << std::endl;
187 }
188 }
189
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800190 return stream.str();
191}
192
193void BufferHubService::HandleImpulse(Message& message) {
194 ATRACE_NAME("BufferHubService::HandleImpulse");
195 if (auto channel = message.GetChannel<BufferHubChannel>())
196 channel->HandleImpulse(message);
197}
198
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700199pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800200 ATRACE_NAME("BufferHubService::HandleMessage");
201 auto channel = message.GetChannel<BufferHubChannel>();
202
203 ALOGD_IF(
204 TRACE,
205 "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
206 channel.get(), message.GetChannelId(), message.GetOp());
207
208 // If the channel is already set up, let it handle the message.
209 if (channel && !channel->HandleMessage(message))
210 return DefaultHandleMessage(message);
211
212 // This channel has not been set up yet, the following are valid operations.
213 switch (message.GetOp()) {
214 case BufferHubRPC::CreateBuffer::Opcode:
215 DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
216 *this, &BufferHubService::OnCreateBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700217 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800218
219 case BufferHubRPC::CreatePersistentBuffer::Opcode:
220 DispatchRemoteMethod<BufferHubRPC::CreatePersistentBuffer>(
221 *this, &BufferHubService::OnCreatePersistentBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700222 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800223
224 case BufferHubRPC::GetPersistentBuffer::Opcode:
225 DispatchRemoteMethod<BufferHubRPC::GetPersistentBuffer>(
226 *this, &BufferHubService::OnGetPersistentBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700227 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800228
229 case BufferHubRPC::CreateProducerQueue::Opcode:
230 DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
231 *this, &BufferHubService::OnCreateProducerQueue, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700232 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800233
234 default:
235 return DefaultHandleMessage(message);
236 }
237}
238
239void BufferHubService::OnChannelClose(Message&,
240 const std::shared_ptr<Channel>& channel) {
241 if (auto buffer = std::static_pointer_cast<BufferHubChannel>(channel))
242 buffer->Detach();
243}
244
Corey Tabakacd52dd92017-04-07 18:03:57 -0700245Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
246 uint32_t height, uint32_t format,
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700247 uint64_t usage,
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700248 size_t meta_size_bytes) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800249 // Use the producer channel id as the global buffer id.
250 const int buffer_id = message.GetChannelId();
251 ALOGD_IF(TRACE,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700252 "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700253 "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
254 buffer_id, width, height, format, usage, meta_size_bytes);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800255
256 // See if this channel is already attached to a buffer.
257 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
258 ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
259 buffer_id);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700260 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800261 }
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700262 const uint32_t kDefaultLayerCount = 1;
263 auto status = ProducerChannel::Create(this, buffer_id, width, height,
264 kDefaultLayerCount, format, usage,
265 meta_size_bytes);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700266 if (status) {
267 message.SetChannel(status.take());
268 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800269 } else {
Corey Tabakacd52dd92017-04-07 18:03:57 -0700270 ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
271 status.GetErrorMessage().c_str());
272 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800273 }
274}
275
Corey Tabakacd52dd92017-04-07 18:03:57 -0700276Status<void> BufferHubService::OnCreatePersistentBuffer(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800277 Message& message, const std::string& name, int user_id, int group_id,
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700278 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700279 size_t meta_size_bytes) {
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700280 const uint32_t kDefaultLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800281 const int channel_id = message.GetChannelId();
282 ALOGD_IF(TRACE,
283 "BufferHubService::OnCreatePersistentBuffer: channel_id=%d name=%s "
Corey Tabakacd52dd92017-04-07 18:03:57 -0700284 "user_id=%d group_id=%d width=%u height=%u format=%u "
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700285 "usage=%" PRIx64 " meta_size_bytes=%zu",
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800286 channel_id, name.c_str(), user_id, group_id, width, height, format,
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700287 usage, meta_size_bytes);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800288
289 // See if this channel is already attached to a buffer.
290 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
291 ALOGE(
292 "BufferHubService::OnCreatePersistentBuffer: Channel already attached "
293 "to buffer: channel_id=%d buffer_id=%d",
294 channel_id, channel->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700295 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800296 }
297
298 const int euid = message.GetEffectiveUserId();
299 const int egid = message.GetEffectiveGroupId();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800300
301 if (auto buffer = GetNamedBuffer(name)) {
302 if (!buffer->CheckAccess(euid, egid)) {
303 ALOGE(
304 "BufferHubService::OnCreatePersistentBuffer: Requesting process does "
305 "not have permission to access named buffer: name=%s euid=%d egid=%d",
306 name.c_str(), euid, euid);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700307 return ErrorStatus(EPERM);
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700308 } else if (!buffer->CheckParameters(width, height, kDefaultLayerCount,
309 format, usage, meta_size_bytes)) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800310 ALOGE(
311 "BufferHubService::OnCreatePersistentBuffer: Requested an existing "
312 "buffer with different parameters: name=%s",
313 name.c_str());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700314 return ErrorStatus(EINVAL);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800315 } else if (!buffer->IsDetached()) {
316 ALOGE(
317 "BufferHubService::OnCreatePersistentBuffer: Requesting a persistent "
318 "buffer that is already attached to a channel: name=%s",
319 name.c_str());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700320 return ErrorStatus(EINVAL);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800321 } else {
322 buffer->Attach(channel_id);
323 message.SetChannel(buffer);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700324 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800325 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800326 } else {
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700327 auto status = ProducerChannel::Create(this, channel_id, width, height,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700328 kDefaultLayerCount, format, usage,
329 meta_size_bytes);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700330 if (!status) {
331 ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
332 return status.error_status();
333 }
334 auto persistent_buffer = status.take();
335 auto make_persistent_status = persistent_buffer->OnProducerMakePersistent(
336 message, name, user_id, group_id);
337 if (make_persistent_status)
338 message.SetChannel(persistent_buffer);
339 return make_persistent_status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800340 }
341}
342
Corey Tabakacd52dd92017-04-07 18:03:57 -0700343Status<void> BufferHubService::OnGetPersistentBuffer(Message& message,
344 const std::string& name) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800345 const int channel_id = message.GetChannelId();
346 ALOGD_IF(TRACE,
347 "BufferHubService::OnGetPersistentBuffer: channel_id=%d name=%s",
348 channel_id, name.c_str());
349
350 // See if this channel is already attached to a buffer.
351 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
352 ALOGE(
353 "BufferHubService::OnGetPersistentBuffer: Channel already attached to "
354 "buffer: channel_id=%d buffer_id=%d",
355 channel_id, channel->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700356 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800357 }
358
359 const int euid = message.GetEffectiveUserId();
360 const int egid = message.GetEffectiveGroupId();
361
362 if (auto buffer = GetNamedBuffer(name)) {
363 if (!buffer->CheckAccess(euid, egid)) {
364 ALOGE(
365 "BufferHubService::OnGetPersistentBuffer: Requesting process does "
366 "not have permission to access named buffer: name=%s euid=%d egid=%d",
367 name.c_str(), euid, egid);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700368 return ErrorStatus(EPERM);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800369 } else if (!buffer->IsDetached()) {
370 ALOGE(
371 "BufferHubService::OnGetPersistentBuffer: Requesting a persistent "
372 "buffer that is already attached to a channel: name=%s",
373 name.c_str());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700374 return ErrorStatus(EINVAL);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800375 } else {
376 buffer->Attach(channel_id);
377 message.SetChannel(buffer);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700378 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800379 }
380 } else {
381 ALOGE("BufferHubService::OnGetPersistentBuffer: Buffer \"%s\" not found!",
382 name.c_str());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700383 return ErrorStatus(ENOENT);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800384 }
385}
386
Corey Tabaka1db8a5d2017-03-22 02:12:52 -0700387Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700388 pdx::Message& message, const ProducerQueueConfig& producer_config,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700389 const UsagePolicy& usage_policy) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800390 // Use the producer channel id as the global queue id.
391 const int queue_id = message.GetChannelId();
392 ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
393 queue_id);
394
395 // See if this channel is already attached to another object.
396 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
397 ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
398 queue_id);
Corey Tabaka1db8a5d2017-03-22 02:12:52 -0700399 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800400 }
401
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700402 auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700403 usage_policy);
404 if (status) {
405 message.SetChannel(status.take());
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700406 return {{producer_config, queue_id}};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800407 } else {
408 ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
Corey Tabakacd52dd92017-04-07 18:03:57 -0700409 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800410 }
411}
412
413bool BufferHubService::AddNamedBuffer(
414 const std::string& name, const std::shared_ptr<ProducerChannel>& buffer) {
415 auto search = named_buffers_.find(name);
416 if (search == named_buffers_.end()) {
417 named_buffers_.emplace(name, buffer);
418 return true;
419 } else {
420 return false;
421 }
422}
423
424std::shared_ptr<ProducerChannel> BufferHubService::GetNamedBuffer(
425 const std::string& name) {
426 auto search = named_buffers_.find(name);
427 if (search != named_buffers_.end())
428 return search->second;
429 else
430 return nullptr;
431}
432
433bool BufferHubService::RemoveNamedBuffer(const ProducerChannel& buffer) {
434 for (auto it = named_buffers_.begin(); it != named_buffers_.end();) {
435 if (it->second.get() == &buffer) {
436 named_buffers_.erase(it);
437 return true;
438 }
439 ++it;
440 }
441 return false;
442}
443
444void BufferHubChannel::SignalAvailable() {
445 ATRACE_NAME("BufferHubChannel::SignalAvailable");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800446 ALOGD_IF(TRACE,
447 "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
448 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800449 if (!IsDetached()) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700450 signaled_ = true;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700451 const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
452 ALOGE_IF(!status,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800453 "BufferHubChannel::SignalAvailable: failed to signal availability "
454 "channel_id=%d: %s",
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700455 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800456 } else {
457 ALOGD_IF(TRACE, "BufferHubChannel::SignalAvailable: detached buffer.");
458 }
459}
460
461void BufferHubChannel::ClearAvailable() {
462 ATRACE_NAME("BufferHubChannel::ClearAvailable");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800463 ALOGD_IF(TRACE,
464 "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
465 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800466 if (!IsDetached()) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700467 signaled_ = false;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700468 const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
469 ALOGE_IF(!status,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800470 "BufferHubChannel::ClearAvailable: failed to clear availability "
471 "channel_id=%d: %s",
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700472 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800473 } else {
474 ALOGD_IF(TRACE, "BufferHubChannel::ClearAvailable: detached buffer.");
475 }
476}
477
478void BufferHubChannel::Hangup() {
479 ATRACE_NAME("BufferHubChannel::Hangup");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800480 ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
481 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800482 if (!IsDetached()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700483 const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800484 ALOGE_IF(
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700485 !status,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800486 "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700487 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800488 } else {
489 ALOGD_IF(TRACE, "BufferHubChannel::Hangup: detached buffer.");
490 }
491}
492
493} // namespace dvr
494} // namespace android