blob: a6d2dbb60c2b2921be2206a2120149cfd11ed95c [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "consumer_channel.h"
2
Alex Vakulenko4fe60582017-02-02 11:35:59 -08003#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08004#include <utils/Trace.h>
5
6#include <thread>
7
8#include <private/dvr/bufferhub_rpc.h>
9#include "producer_channel.h"
10
11using android::pdx::BorrowedHandle;
12using android::pdx::Channel;
Corey Tabakad53870c2017-07-06 18:04:27 -070013using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080014using android::pdx::Message;
Corey Tabakacd52dd92017-04-07 18:03:57 -070015using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080016using android::pdx::rpc::DispatchRemoteMethod;
17
18namespace android {
19namespace dvr {
20
21ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
Corey Tabaka52ea25c2017-09-13 18:02:48 -070022 int channel_id, uint64_t consumer_state_bit,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080023 const std::shared_ptr<Channel> producer)
24 : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
Corey Tabaka52ea25c2017-09-13 18:02:48 -070025 consumer_state_bit_(consumer_state_bit),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080026 producer_(producer) {
27 GetProducer()->AddConsumer(this);
28}
29
30ConsumerChannel::~ConsumerChannel() {
Corey Tabaka3079cb72017-01-19 15:07:26 -080031 ALOGD_IF(TRACE,
32 "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
33 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034
35 if (auto producer = GetProducer()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036 producer->RemoveConsumer(this);
37 }
38}
39
40BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
41 BufferHubChannel::BufferInfo info;
42 if (auto producer = GetProducer()) {
43 // If producer has not hung up, copy most buffer info from the producer.
44 info = producer->GetBufferInfo();
Corey Tabaka52ea25c2017-09-13 18:02:48 -070045 } else {
46 info.signaled_mask = consumer_state_bit();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080047 }
48 info.id = buffer_id();
49 return info;
50}
51
52std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
53 return std::static_pointer_cast<ProducerChannel>(producer_.lock());
54}
55
56void ConsumerChannel::HandleImpulse(Message& message) {
57 ATRACE_NAME("ConsumerChannel::HandleImpulse");
58 switch (message.GetOp()) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -070059 case BufferHubRPC::ConsumerAcquire::Opcode:
60 OnConsumerAcquire(message);
61 break;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 case BufferHubRPC::ConsumerRelease::Opcode:
63 OnConsumerRelease(message, {});
64 break;
65 }
66}
67
68bool ConsumerChannel::HandleMessage(Message& message) {
69 ATRACE_NAME("ConsumerChannel::HandleMessage");
70 auto producer = GetProducer();
71 if (!producer)
72 REPLY_ERROR_RETURN(message, EPIPE, true);
73
74 switch (message.GetOp()) {
75 case BufferHubRPC::GetBuffer::Opcode:
76 DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
Corey Tabaka52ea25c2017-09-13 18:02:48 -070077 *this, &ConsumerChannel::OnGetBuffer, message);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080078 return true;
79
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080080 case BufferHubRPC::NewConsumer::Opcode:
81 DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
82 *producer, &ProducerChannel::OnNewConsumer, message);
83 return true;
84
85 case BufferHubRPC::ConsumerAcquire::Opcode:
86 DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
87 *this, &ConsumerChannel::OnConsumerAcquire, message);
88 return true;
89
90 case BufferHubRPC::ConsumerRelease::Opcode:
91 DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
92 *this, &ConsumerChannel::OnConsumerRelease, message);
93 return true;
94
95 case BufferHubRPC::ConsumerSetIgnore::Opcode:
96 DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>(
97 *this, &ConsumerChannel::OnConsumerSetIgnore, message);
98 return true;
99
100 default:
101 return false;
102 }
103}
104
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700105Status<BufferDescription<BorrowedHandle>> ConsumerChannel::OnGetBuffer(
106 Message& /*message*/) {
107 ATRACE_NAME("ConsumerChannel::OnGetBuffer");
108 ALOGD_IF(TRACE, "ConsumerChannel::OnGetBuffer: buffer=%d", buffer_id());
109 if (auto producer = GetProducer()) {
110 return {producer->GetBuffer(consumer_state_bit_)};
111 } else {
112 return ErrorStatus(EPIPE);
113 }
114}
115
116Status<LocalFence> ConsumerChannel::OnConsumerAcquire(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800117 ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
118 auto producer = GetProducer();
119 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700120 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800121
Corey Tabakad53870c2017-07-06 18:04:27 -0700122 if (acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800123 ALOGE(
124 "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700125 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
126 ignored_, acquired_, released_, message.GetChannelId(),
127 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700128 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800129 } else {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700130 auto status = producer->OnConsumerAcquire(message);
Corey Tabakad53870c2017-07-06 18:04:27 -0700131 if (status) {
132 ClearAvailable();
133 acquired_ = true;
134 }
135 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800136 }
137}
138
Corey Tabakacd52dd92017-04-07 18:03:57 -0700139Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
140 LocalFence release_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800141 ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
142 auto producer = GetProducer();
143 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700144 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800145
Corey Tabakad53870c2017-07-06 18:04:27 -0700146 if (!acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800147 ALOGE(
148 "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700149 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
150 ignored_, acquired_, released_, message.GetChannelId(),
151 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700152 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800153 } else {
Corey Tabakacd52dd92017-04-07 18:03:57 -0700154 auto status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800155 producer->OnConsumerRelease(message, std::move(release_fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700156 if (status) {
157 ClearAvailable();
158 acquired_ = false;
159 released_ = true;
160 }
Corey Tabakacd52dd92017-04-07 18:03:57 -0700161 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800162 }
163}
164
Corey Tabakacd52dd92017-04-07 18:03:57 -0700165Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166 ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
167 auto producer = GetProducer();
168 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700169 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800170
171 ignored_ = ignored;
Corey Tabakad53870c2017-07-06 18:04:27 -0700172 if (ignored_ && acquired_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800173 // Update the producer if ignore is set after the consumer acquires the
174 // buffer.
175 ClearAvailable();
176 producer->OnConsumerIgnored();
Corey Tabakad53870c2017-07-06 18:04:27 -0700177 acquired_ = false;
178 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800179 }
180
Corey Tabakacd52dd92017-04-07 18:03:57 -0700181 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800182}
183
184bool ConsumerChannel::OnProducerPosted() {
185 if (ignored_) {
Corey Tabakad53870c2017-07-06 18:04:27 -0700186 acquired_ = false;
187 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800188 return false;
189 } else {
Corey Tabakad53870c2017-07-06 18:04:27 -0700190 acquired_ = false;
191 released_ = false;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800192 SignalAvailable();
193 return true;
194 }
195}
196
197void ConsumerChannel::OnProducerClosed() {
198 producer_.reset();
199 Hangup();
200}
201
202} // namespace dvr
203} // namespace android