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