blob: ac6896ae84d90a6872245fb77ba4ee9acc91fbdb [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,
22 int channel_id,
23 const std::shared_ptr<Channel> producer)
24 : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080025 producer_(producer) {
26 GetProducer()->AddConsumer(this);
27}
28
29ConsumerChannel::~ConsumerChannel() {
Corey Tabaka3079cb72017-01-19 15:07:26 -080030 ALOGD_IF(TRACE,
31 "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
32 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080033
34 if (auto producer = GetProducer()) {
Corey Tabakad53870c2017-07-06 18:04:27 -070035 if (!released_) // Producer is waiting for our Release.
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036 producer->OnConsumerIgnored();
37 producer->RemoveConsumer(this);
38 }
39}
40
41BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
42 BufferHubChannel::BufferInfo info;
43 if (auto producer = GetProducer()) {
44 // If producer has not hung up, copy most buffer info from the producer.
45 info = producer->GetBufferInfo();
46 }
47 info.id = buffer_id();
48 return info;
49}
50
51std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
52 return std::static_pointer_cast<ProducerChannel>(producer_.lock());
53}
54
55void ConsumerChannel::HandleImpulse(Message& message) {
56 ATRACE_NAME("ConsumerChannel::HandleImpulse");
57 switch (message.GetOp()) {
58 case BufferHubRPC::ConsumerRelease::Opcode:
59 OnConsumerRelease(message, {});
60 break;
61 }
62}
63
64bool ConsumerChannel::HandleMessage(Message& message) {
65 ATRACE_NAME("ConsumerChannel::HandleMessage");
66 auto producer = GetProducer();
67 if (!producer)
68 REPLY_ERROR_RETURN(message, EPIPE, true);
69
70 switch (message.GetOp()) {
71 case BufferHubRPC::GetBuffer::Opcode:
72 DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
73 *producer, &ProducerChannel::OnGetBuffer, message);
74 return true;
75
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080076 case BufferHubRPC::NewConsumer::Opcode:
77 DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
78 *producer, &ProducerChannel::OnNewConsumer, message);
79 return true;
80
81 case BufferHubRPC::ConsumerAcquire::Opcode:
82 DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
83 *this, &ConsumerChannel::OnConsumerAcquire, message);
84 return true;
85
86 case BufferHubRPC::ConsumerRelease::Opcode:
87 DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
88 *this, &ConsumerChannel::OnConsumerRelease, message);
89 return true;
90
91 case BufferHubRPC::ConsumerSetIgnore::Opcode:
92 DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>(
93 *this, &ConsumerChannel::OnConsumerSetIgnore, message);
94 return true;
95
96 default:
97 return false;
98 }
99}
100
Corey Tabakacd52dd92017-04-07 18:03:57 -0700101Status<std::pair<BorrowedFence, ConsumerChannel::MetaData>>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800102ConsumerChannel::OnConsumerAcquire(Message& message,
103 std::size_t metadata_size) {
104 ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
105 auto producer = GetProducer();
106 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700107 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800108
Corey Tabakad53870c2017-07-06 18:04:27 -0700109 if (acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800110 ALOGE(
111 "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700112 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
113 ignored_, acquired_, released_, message.GetChannelId(),
114 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700115 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800116 } else {
Corey Tabakad53870c2017-07-06 18:04:27 -0700117 auto status = producer->OnConsumerAcquire(message, metadata_size);
118 if (status) {
119 ClearAvailable();
120 acquired_ = true;
121 }
122 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800123 }
124}
125
Corey Tabakacd52dd92017-04-07 18:03:57 -0700126Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
127 LocalFence release_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800128 ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
129 auto producer = GetProducer();
130 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700131 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800132
Corey Tabakad53870c2017-07-06 18:04:27 -0700133 if (!acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800134 ALOGE(
135 "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700136 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
137 ignored_, acquired_, released_, message.GetChannelId(),
138 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700139 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800140 } else {
Corey Tabakacd52dd92017-04-07 18:03:57 -0700141 auto status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800142 producer->OnConsumerRelease(message, std::move(release_fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700143 if (status) {
144 ClearAvailable();
145 acquired_ = false;
146 released_ = true;
147 }
Corey Tabakacd52dd92017-04-07 18:03:57 -0700148 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800149 }
150}
151
Corey Tabakacd52dd92017-04-07 18:03:57 -0700152Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800153 ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
154 auto producer = GetProducer();
155 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700156 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800157
158 ignored_ = ignored;
Corey Tabakad53870c2017-07-06 18:04:27 -0700159 if (ignored_ && acquired_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800160 // Update the producer if ignore is set after the consumer acquires the
161 // buffer.
162 ClearAvailable();
163 producer->OnConsumerIgnored();
Corey Tabakad53870c2017-07-06 18:04:27 -0700164 acquired_ = false;
165 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166 }
167
Corey Tabakacd52dd92017-04-07 18:03:57 -0700168 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800169}
170
171bool ConsumerChannel::OnProducerPosted() {
172 if (ignored_) {
Corey Tabakad53870c2017-07-06 18:04:27 -0700173 acquired_ = false;
174 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800175 return false;
176 } else {
Corey Tabakad53870c2017-07-06 18:04:27 -0700177 acquired_ = false;
178 released_ = false;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800179 SignalAvailable();
180 return true;
181 }
182}
183
184void ConsumerChannel::OnProducerClosed() {
185 producer_.reset();
186 Hangup();
187}
188
189} // namespace dvr
190} // namespace android