1 #include <inttypes.h>
2 #include <poll.h>
3 
4 #include <iomanip>
5 #include <memory>
6 #include <sstream>
7 #include <string>
8 #include <thread>
9 
10 #include <log/log.h>
11 #include <pdx/default_transport/service_endpoint.h>
12 #include <private/dvr/bufferhub_rpc.h>
13 #include <private/dvr/buffer_hub.h>
14 #include <private/dvr/consumer_channel.h>
15 #include <private/dvr/producer_channel.h>
16 #include <private/dvr/producer_queue_channel.h>
17 #include <utils/Trace.h>
18 
19 using android::pdx::Channel;
20 using android::pdx::ErrorStatus;
21 using android::pdx::Message;
22 using android::pdx::Status;
23 using android::pdx::default_transport::Endpoint;
24 using android::pdx::rpc::DispatchRemoteMethod;
25 
26 namespace android {
27 namespace dvr {
28 
BufferHubService()29 BufferHubService::BufferHubService()
30     : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
31 
~BufferHubService()32 BufferHubService::~BufferHubService() {}
33 
IsInitialized() const34 bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
35 
DumpState(size_t)36 std::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 << " ";
56   stream << std::setw(10) << "Usage";
57   stream << " ";
58   stream << std::setw(18) << "State";
59   stream << " ";
60   stream << std::setw(18) << "Signaled";
61   stream << " ";
62   stream << std::setw(10) << "Index";
63   stream << std::endl;
64 
65   for (const auto& channel : channels) {
66     if (channel->channel_type() == BufferHubChannel::kProducerType) {
67       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
68 
69       stream << std::right;
70       stream << std::setw(6) << info.id;
71       stream << " ";
72       stream << std::setw(9) << info.consumer_count;
73       stream << " ";
74       if (info.format == HAL_PIXEL_FORMAT_BLOB) {
75         std::string size = std::to_string(info.width) + " B";
76         stream << std::setw(14) << size;
77       } else {
78         std::string dimensions = std::to_string(info.width) + "x" +
79                                  std::to_string(info.height) + "x" +
80                                  std::to_string(info.layer_count);
81         stream << std::setw(14) << dimensions;
82       }
83       stream << " ";
84       stream << std::setw(6) << info.format;
85       stream << " ";
86       stream << "0x" << std::hex << std::setfill('0');
87       stream << std::setw(8) << info.usage;
88       stream << std::dec << std::setfill(' ');
89       stream << " ";
90       stream << "0x" << std::hex << std::setfill('0');
91       stream << std::setw(16) << info.state;
92       stream << " ";
93       stream << "0x" << std::setw(16) << info.signaled_mask;
94       stream << std::dec << std::setfill(' ');
95       stream << " ";
96       stream << std::setw(8) << info.index;
97       stream << std::endl;
98     }
99 
100     if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
101       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
102 
103       stream << std::right;
104       stream << std::setw(6) << info.id;
105       stream << " ";
106       stream << std::setw(9) << "N/A";
107       stream << " ";
108       if (info.format == HAL_PIXEL_FORMAT_BLOB) {
109         std::string size = std::to_string(info.width) + " B";
110         stream << std::setw(14) << size;
111       } else {
112         std::string dimensions = std::to_string(info.width) + "x" +
113                                  std::to_string(info.height) + "x" +
114                                  std::to_string(info.layer_count);
115         stream << std::setw(14) << dimensions;
116       }
117       stream << " ";
118       stream << std::setw(6) << info.format;
119       stream << " ";
120       stream << "0x" << std::hex << std::setfill('0');
121       stream << std::setw(8) << info.usage;
122       stream << std::dec << std::setfill(' ');
123       stream << " ";
124       stream << std::setw(9) << "N/A";
125       stream << " ";
126       stream << std::hex << std::setfill(' ');
127       stream << std::setw(18) << "Detached";
128       stream << " ";
129       stream << std::setw(18) << "N/A";
130       stream << " ";
131       stream << std::setw(10) << "N/A";
132       stream << std::endl;
133     }
134   }
135 
136   stream << std::endl;
137   stream << "Active Producer Queues:\n";
138   stream << std::right << std::setw(6) << "Id";
139   stream << std::right << std::setw(12) << " Capacity";
140   stream << std::right << std::setw(12) << " Consumers";
141   stream << " UsageSetMask";
142   stream << " UsageClearMask";
143   stream << " UsageDenySetMask";
144   stream << " UsageDenyClearMask";
145   stream << " ";
146   stream << std::endl;
147 
148   for (const auto& channel : channels) {
149     if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
150       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
151 
152       stream << std::dec << std::setfill(' ');
153       stream << std::right << std::setw(6) << info.id;
154       stream << std::right << std::setw(12) << info.capacity;
155       stream << std::right << std::setw(12) << info.consumer_count;
156       stream << std::setw(5) << std::setfill(' ') << "0x";
157       stream << std::hex << std::setfill('0');
158       stream << std::setw(8) << info.usage_policy.usage_set_mask;
159       stream << std::setw(7) << std::setfill(' ') << "0x";
160       stream << std::hex << std::setfill('0');
161       stream << std::setw(8) << info.usage_policy.usage_clear_mask;
162       stream << std::setw(9) << std::setfill(' ') << "0x";
163       stream << std::hex << std::setfill('0');
164       stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
165       stream << std::setw(11) << std::setfill(' ') << "0x";
166       stream << std::hex << std::setfill('0');
167       stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
168       stream << std::hex << std::setfill('0');
169       stream << std::endl;
170     }
171   }
172 
173   stream << std::endl;
174   stream << "Active Consumer Queues:\n";
175   stream << std::dec << std::setfill(' ');
176   stream << std::right << std::setw(6) << "Id";
177   stream << std::right << std::setw(12) << " Imported";
178   stream << " ";
179   stream << std::endl;
180 
181   for (const auto& channel : channels) {
182     if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
183       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
184 
185       stream << std::right << std::setw(6) << info.id;
186       stream << std::right << std::setw(12) << info.capacity;
187       stream << std::endl;
188     }
189   }
190 
191   stream << std::endl;
192   stream << "Orphaned Consumer Buffers:\n";
193   stream << std::right;
194   stream << std::setw(6) << "Id";
195   stream << " ";
196   stream << std::setw(14) << "Info";
197   stream << std::endl;
198 
199   for (const auto& channel : channels) {
200     BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
201     // consumer_count is tracked by producer. When it's zero, producer must have
202     // already hung up and the consumer is orphaned.
203     if (channel->channel_type() == BufferHubChannel::kConsumerType &&
204         info.consumer_count == 0) {
205       stream << std::right;
206       stream << std::setw(6) << info.id;
207       stream << " ";
208 
209       stream << std::setw(14) << "Orphaned.";
210       stream << (" channel_id=" + std::to_string(channel->channel_id()));
211       stream << std::endl;
212     }
213   }
214 
215   return stream.str();
216 }
217 
HandleImpulse(Message & message)218 void BufferHubService::HandleImpulse(Message& message) {
219   ATRACE_NAME("BufferHubService::HandleImpulse");
220   if (auto channel = message.GetChannel<BufferHubChannel>())
221     channel->HandleImpulse(message);
222 }
223 
HandleMessage(Message & message)224 pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
225   ATRACE_NAME("BufferHubService::HandleMessage");
226   auto channel = message.GetChannel<BufferHubChannel>();
227 
228   ALOGD_IF(
229       TRACE,
230       "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
231       channel.get(), message.GetChannelId(), message.GetOp());
232 
233   // If the channel is already set up, let it handle the message.
234   if (channel && !channel->HandleMessage(message))
235     return DefaultHandleMessage(message);
236 
237   // This channel has not been set up yet, the following are valid operations.
238   switch (message.GetOp()) {
239     case BufferHubRPC::CreateBuffer::Opcode:
240       DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
241           *this, &BufferHubService::OnCreateBuffer, message);
242       return {};
243 
244     case BufferHubRPC::CreateProducerQueue::Opcode:
245       DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
246           *this, &BufferHubService::OnCreateProducerQueue, message);
247       return {};
248 
249     default:
250       return DefaultHandleMessage(message);
251   }
252 }
253 
OnCreateBuffer(Message & message,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,size_t meta_size_bytes)254 Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
255                                               uint32_t height, uint32_t format,
256                                               uint64_t usage,
257                                               size_t meta_size_bytes) {
258   // Use the producer channel id as the global buffer id.
259   const int buffer_id = message.GetChannelId();
260   ALOGD_IF(TRACE,
261            "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
262            "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
263            buffer_id, width, height, format, usage, meta_size_bytes);
264 
265   // See if this channel is already attached to a buffer.
266   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
267     ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
268           buffer_id);
269     return ErrorStatus(EALREADY);
270   }
271   const uint32_t kDefaultLayerCount = 1;
272   auto status = ProducerChannel::Create(this, buffer_id, width, height,
273                                         kDefaultLayerCount, format, usage,
274                                         meta_size_bytes);
275   if (status) {
276     message.SetChannel(status.take());
277     return {};
278   } else {
279     ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
280           status.GetErrorMessage().c_str());
281     return status.error_status();
282   }
283 }
284 
OnCreateProducerQueue(pdx::Message & message,const ProducerQueueConfig & producer_config,const UsagePolicy & usage_policy)285 Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
286     pdx::Message& message, const ProducerQueueConfig& producer_config,
287     const UsagePolicy& usage_policy) {
288   // Use the producer channel id as the global queue id.
289   const int queue_id = message.GetChannelId();
290   ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
291            queue_id);
292 
293   // See if this channel is already attached to another object.
294   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
295     ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
296           queue_id);
297     return ErrorStatus(EALREADY);
298   }
299 
300   auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
301                                              usage_policy);
302   if (status) {
303     message.SetChannel(status.take());
304     return {{producer_config, queue_id}};
305   } else {
306     ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
307     return status.error_status();
308   }
309 }
310 
SignalAvailable()311 void BufferHubChannel::SignalAvailable() {
312   ATRACE_NAME("BufferHubChannel::SignalAvailable");
313   ALOGD_IF(TRACE,
314            "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
315            channel_id(), buffer_id());
316   signaled_ = true;
317   const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
318   ALOGE_IF(!status,
319            "BufferHubChannel::SignalAvailable: failed to signal availability "
320            "channel_id=%d: %s",
321            channel_id_, status.GetErrorMessage().c_str());
322 }
323 
ClearAvailable()324 void BufferHubChannel::ClearAvailable() {
325   ATRACE_NAME("BufferHubChannel::ClearAvailable");
326   ALOGD_IF(TRACE,
327            "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
328            channel_id(), buffer_id());
329   signaled_ = false;
330   const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
331   ALOGE_IF(!status,
332            "BufferHubChannel::ClearAvailable: failed to clear availability "
333            "channel_id=%d: %s",
334            channel_id_, status.GetErrorMessage().c_str());
335 }
336 
Hangup()337 void BufferHubChannel::Hangup() {
338   ATRACE_NAME("BufferHubChannel::Hangup");
339   ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
340            channel_id(), buffer_id());
341   const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
342   ALOGE_IF(
343       !status,
344       "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
345       channel_id_, status.GetErrorMessage().c_str());
346 }
347 
348 }  // namespace dvr
349 }  // namespace android
350