consumer_channel.cpp revision d53870c58cbb3671c2efdae3cc53850b962aa9dc
1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "consumer_channel.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <utils/Trace.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <thread> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/bufferhub_rpc.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "producer_channel.h" 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedHandle; 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Channel; 13d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabakausing android::pdx::ErrorStatus; 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Message; 15cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabakausing android::pdx::Status; 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::rpc::DispatchRemoteMethod; 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id, 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id, 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<Channel> producer) 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BufferHubChannel(service, buffer_id, channel_id, kConsumerType), 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer_(producer) { 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko GetProducer()->AddConsumer(this); 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoConsumerChannel::~ConsumerChannel() { 303079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka ALOGD_IF(TRACE, 313079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d", 323079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka channel_id(), buffer_id()); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto producer = GetProducer()) { 35d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (!released_) // Producer is waiting for our Release. 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->OnConsumerIgnored(); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->RemoveConsumer(this); 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const { 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubChannel::BufferInfo info; 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto producer = GetProducer()) { 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If producer has not hung up, copy most buffer info from the producer. 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info = producer->GetBufferInfo(); 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.id = buffer_id(); 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return info; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const { 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::static_pointer_cast<ProducerChannel>(producer_.lock()); 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ConsumerChannel::HandleImpulse(Message& message) { 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::HandleImpulse"); 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerRelease::Opcode: 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko OnConsumerRelease(message, {}); 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ConsumerChannel::HandleMessage(Message& message) { 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::HandleMessage"); 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko REPLY_ERROR_RETURN(message, EPIPE, true); 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::GetBuffer::Opcode: 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::GetBuffer>( 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *producer, &ProducerChannel::OnGetBuffer, message); 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::NewConsumer::Opcode: 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::NewConsumer>( 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *producer, &ProducerChannel::OnNewConsumer, message); 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerAcquire::Opcode: 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>( 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerAcquire, message); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerRelease::Opcode: 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>( 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerRelease, message); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerSetIgnore::Opcode: 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>( 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerSetIgnore, message); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko default: 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<std::pair<BorrowedFence, ConsumerChannel::MetaData>> 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoConsumerChannel::OnConsumerAcquire(Message& message, 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::size_t metadata_size) { 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerAcquire"); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 107cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 109d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (acquired_ || released_) { 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: " 112d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d", 113d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ignored_, acquired_, released_, message.GetChannelId(), 114d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka producer->buffer_id()); 115cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EBUSY); 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 117d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka auto status = producer->OnConsumerAcquire(message, metadata_size); 118d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (status) { 119d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ClearAvailable(); 120d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = true; 121d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka } 122d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka return status; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 126cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<void> ConsumerChannel::OnConsumerRelease(Message& message, 127cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka LocalFence release_fence) { 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerRelease"); 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 131cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 133d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (!acquired_ || released_) { 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "ConsumerChannel::OnConsumerRelease: Release when not acquired: " 136d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d", 137d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ignored_, acquired_, released_, message.GetChannelId(), 138d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka producer->buffer_id()); 139cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EBUSY); 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 141cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka auto status = 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->OnConsumerRelease(message, std::move(release_fence)); 143d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (status) { 144d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ClearAvailable(); 145d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 146d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 147d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka } 148cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return status; 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 152cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) { 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore"); 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 156cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ignored_ = ignored; 159d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (ignored_ && acquired_) { 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Update the producer if ignore is set after the consumer acquires the 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer. 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ClearAvailable(); 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->OnConsumerIgnored(); 164d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 165d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 168cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return {}; 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ConsumerChannel::OnProducerPosted() { 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ignored_) { 173d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 174d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 177d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 178d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = false; 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SignalAvailable(); 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ConsumerChannel::OnProducerClosed() { 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer_.reset(); 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Hangup(); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 191