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, 2252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int channel_id, uint64_t consumer_state_bit, 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<Channel> producer) 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BufferHubChannel(service, buffer_id, channel_id, kConsumerType), 2552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka consumer_state_bit_(consumer_state_bit), 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer_(producer) { 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko GetProducer()->AddConsumer(this); 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoConsumerChannel::~ConsumerChannel() { 313079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka ALOGD_IF(TRACE, 323079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d", 333079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka channel_id(), buffer_id()); 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto producer = GetProducer()) { 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->RemoveConsumer(this); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoBufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const { 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubChannel::BufferInfo info; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto producer = GetProducer()) { 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If producer has not hung up, copy most buffer info from the producer. 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info = producer->GetBufferInfo(); 4552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } else { 4652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka info.signaled_mask = consumer_state_bit(); 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.id = buffer_id(); 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return info; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const { 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::static_pointer_cast<ProducerChannel>(producer_.lock()); 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ConsumerChannel::HandleImpulse(Message& message) { 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::HandleImpulse"); 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 5952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka case BufferHubRPC::ConsumerAcquire::Opcode: 6052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka OnConsumerAcquire(message); 6152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka break; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerRelease::Opcode: 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko OnConsumerRelease(message, {}); 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ConsumerChannel::HandleMessage(Message& message) { 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::HandleMessage"); 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko REPLY_ERROR_RETURN(message, EPIPE, true); 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::GetBuffer::Opcode: 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::GetBuffer>( 7752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka *this, &ConsumerChannel::OnGetBuffer, message); 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::NewConsumer::Opcode: 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::NewConsumer>( 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *producer, &ProducerChannel::OnNewConsumer, message); 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerAcquire::Opcode: 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>( 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerAcquire, message); 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerRelease::Opcode: 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>( 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerRelease, message); 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case BufferHubRPC::ConsumerSetIgnore::Opcode: 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>( 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *this, &ConsumerChannel::OnConsumerSetIgnore, message); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko default: 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10552ea25cf06cef250ec73052611b48556b3fce4d5Corey TabakaStatus<BufferDescription<BorrowedHandle>> ConsumerChannel::OnGetBuffer( 10652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka Message& /*message*/) { 10752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ATRACE_NAME("ConsumerChannel::OnGetBuffer"); 10852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ALOGD_IF(TRACE, "ConsumerChannel::OnGetBuffer: buffer=%d", buffer_id()); 10952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka if (auto producer = GetProducer()) { 11052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return {producer->GetBuffer(consumer_state_bit_)}; 11152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } else { 11252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return ErrorStatus(EPIPE); 11352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 11452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka} 11552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 11652ea25cf06cef250ec73052611b48556b3fce4d5Corey TabakaStatus<LocalFence> ConsumerChannel::OnConsumerAcquire(Message& message) { 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerAcquire"); 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 120cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 122d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (acquired_ || released_) { 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: " 125d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d", 126d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ignored_, acquired_, released_, message.GetChannelId(), 127d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka producer->buffer_id()); 128cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EBUSY); 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 13052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto status = producer->OnConsumerAcquire(message); 131d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (status) { 132d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ClearAvailable(); 133d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = true; 134d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka } 135d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka return status; 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 139cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<void> ConsumerChannel::OnConsumerRelease(Message& message, 140cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka LocalFence release_fence) { 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerRelease"); 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 144cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 146d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (!acquired_ || released_) { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "ConsumerChannel::OnConsumerRelease: Release when not acquired: " 149d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d", 150d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ignored_, acquired_, released_, message.GetChannelId(), 151d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka producer->buffer_id()); 152cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EBUSY); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 154cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka auto status = 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->OnConsumerRelease(message, std::move(release_fence)); 156d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (status) { 157d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka ClearAvailable(); 158d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 159d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 160d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka } 161cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return status; 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 165cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey TabakaStatus<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) { 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore"); 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto producer = GetProducer(); 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!producer) 169cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return ErrorStatus(EPIPE); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ignored_ = ignored; 172d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka if (ignored_ && acquired_) { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Update the producer if ignore is set after the consumer acquires the 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer. 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ClearAvailable(); 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer->OnConsumerIgnored(); 177d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 178d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 181cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka return {}; 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ConsumerChannel::OnProducerPosted() { 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ignored_) { 186d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 187d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = true; 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 190d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka acquired_ = false; 191d53870c58cbb3671c2efdae3cc53850b962aa9dcCorey Tabaka released_ = false; 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko SignalAvailable(); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ConsumerChannel::OnProducerClosed() { 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko producer_.reset(); 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Hangup(); 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 204