consumer_channel.cpp revision 4d3590f3fd0fd65f4e8758d3228de9f55cf135d0
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "consumer_channel.h" 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <log/log.h> 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <utils/Trace.h> 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <thread> 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <private/dvr/bufferhub_rpc.h> 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "producer_channel.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::ErrorStatus; 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::BorrowedHandle; 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::Channel; 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::Message; 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::Status; 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing android::pdx::rpc::DispatchRemoteMethod; 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.comnamespace android { 1961a237e319a63b7ed6d38c2f3cd9b597816c3a46fmalitanamespace dvr { 2061a237e319a63b7ed6d38c2f3cd9b597816c3a46fmalita 214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.comConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id, 224e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com int channel_id, 234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const std::shared_ptr<Channel> producer) 244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com : BufferHubChannel(service, buffer_id, channel_id, kConsumerType), 254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com handled_(true), 264200dfe9c1a2c0e99a7155a63fbffb01e9d1fd28bungeman@google.com ignored_(false), 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com producer_(producer) { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com GetProducer()->AddConsumer(this); 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comConsumerChannel::~ConsumerChannel() { 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ALOGD_IF(TRACE, 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d", 34f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org channel_id(), buffer_id()); 3546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (auto producer = GetProducer()) { 37a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com if (!handled_) // Producer is waiting for our Release. 38971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com producer->OnConsumerIgnored(); 39a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com producer->RemoveConsumer(this); 40971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 41a9baa652bb329b5a286e1638938f63433701efcakkinnunen} 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comBufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const { 444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com BufferHubChannel::BufferInfo info; 454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com if (auto producer = GetProducer()) { 46971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com // If producer has not hung up, copy most buffer info from the producer. 47971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com info = producer->GetBufferInfo(); 484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 49971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com info.id = buffer_id(); 5015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com return info; 5115e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com} 5215e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstd::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const { 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return std::static_pointer_cast<ProducerChannel>(producer_.lock()); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 56 57void ConsumerChannel::HandleImpulse(Message& message) { 58 ATRACE_NAME("ConsumerChannel::HandleImpulse"); 59 switch (message.GetOp()) { 60 case BufferHubRPC::ConsumerRelease::Opcode: 61 OnConsumerRelease(message, {}); 62 break; 63 } 64} 65 66bool ConsumerChannel::HandleMessage(Message& message) { 67 ATRACE_NAME("ConsumerChannel::HandleMessage"); 68 auto producer = GetProducer(); 69 if (!producer) 70 REPLY_ERROR_RETURN(message, EPIPE, true); 71 72 switch (message.GetOp()) { 73 case BufferHubRPC::GetBuffer::Opcode: 74 DispatchRemoteMethod<BufferHubRPC::GetBuffer>( 75 *producer, &ProducerChannel::OnGetBuffer, message); 76 return true; 77 78 case BufferHubRPC::NewConsumer::Opcode: 79 DispatchRemoteMethod<BufferHubRPC::NewConsumer>( 80 *producer, &ProducerChannel::OnNewConsumer, message); 81 return true; 82 83 case BufferHubRPC::ConsumerAcquire::Opcode: 84 DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>( 85 *this, &ConsumerChannel::OnConsumerAcquire, message); 86 return true; 87 88 case BufferHubRPC::ConsumerRelease::Opcode: 89 DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>( 90 *this, &ConsumerChannel::OnConsumerRelease, message); 91 return true; 92 93 case BufferHubRPC::ConsumerSetIgnore::Opcode: 94 DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>( 95 *this, &ConsumerChannel::OnConsumerSetIgnore, message); 96 return true; 97 98 default: 99 return false; 100 } 101} 102 103Status<std::pair<BorrowedFence, ConsumerChannel::MetaData>> 104ConsumerChannel::OnConsumerAcquire(Message& message, 105 std::size_t metadata_size) { 106 ATRACE_NAME("ConsumerChannel::OnConsumerAcquire"); 107 auto producer = GetProducer(); 108 if (!producer) 109 return ErrorStatus(EPIPE); 110 111 if (ignored_ || handled_) { 112 ALOGE( 113 "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: " 114 "ignored=%d handled=%d channel_id=%d buffer_id=%d", 115 ignored_, handled_, message.GetChannelId(), producer->buffer_id()); 116 return ErrorStatus(EBUSY); 117 } else { 118 ClearAvailable(); 119 return producer->OnConsumerAcquire(message, metadata_size); 120 } 121} 122 123Status<void> ConsumerChannel::OnConsumerRelease(Message& message, 124 LocalFence release_fence) { 125 ATRACE_NAME("ConsumerChannel::OnConsumerRelease"); 126 auto producer = GetProducer(); 127 if (!producer) 128 return ErrorStatus(EPIPE); 129 130 if (ignored_ || handled_) { 131 ALOGE( 132 "ConsumerChannel::OnConsumerRelease: Release when not acquired: " 133 "ignored=%d handled=%d channel_id=%d buffer_id=%d", 134 ignored_, handled_, message.GetChannelId(), producer->buffer_id()); 135 return ErrorStatus(EBUSY); 136 } else { 137 ClearAvailable(); 138 auto status = 139 producer->OnConsumerRelease(message, std::move(release_fence)); 140 handled_ = !!status; 141 return status; 142 } 143} 144 145Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) { 146 ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore"); 147 auto producer = GetProducer(); 148 if (!producer) 149 return ErrorStatus(EPIPE); 150 151 ignored_ = ignored; 152 if (ignored_ && !handled_) { 153 // Update the producer if ignore is set after the consumer acquires the 154 // buffer. 155 ClearAvailable(); 156 producer->OnConsumerIgnored(); 157 handled_ = false; 158 } 159 160 return {}; 161} 162 163bool ConsumerChannel::OnProducerPosted() { 164 if (ignored_) { 165 handled_ = true; 166 return false; 167 } else { 168 handled_ = false; 169 SignalAvailable(); 170 return true; 171 } 172} 173 174void ConsumerChannel::OnProducerClosed() { 175 producer_.reset(); 176 Hangup(); 177} 178 179} // namespace dvr 180} // namespace android 181