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 29 BufferHubService::BufferHubService() 30 : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {} 31 32 BufferHubService::~BufferHubService() {} 33 34 bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); } 35 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 218 void BufferHubService::HandleImpulse(Message& message) { 219 ATRACE_NAME("BufferHubService::HandleImpulse"); 220 if (auto channel = message.GetChannel<BufferHubChannel>()) 221 channel->HandleImpulse(message); 222 } 223 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 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 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 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 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 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