blob: 623c9d65069fceb2ebb7606d29790410c08e7c23 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <thread>
2
Fan Xu74df4902018-09-20 16:40:51 -07003#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08004#include <private/dvr/bufferhub_rpc.h>
Fan Xu74df4902018-09-20 16:40:51 -07005#include <private/dvr/consumer_channel.h>
6#include <private/dvr/producer_channel.h>
7#include <utils/Trace.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08008
9using android::pdx::BorrowedHandle;
10using android::pdx::Channel;
Corey Tabakad53870c2017-07-06 18:04:27 -070011using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080012using android::pdx::Message;
Corey Tabakacd52dd92017-04-07 18:03:57 -070013using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080014using android::pdx::rpc::DispatchRemoteMethod;
15
16namespace android {
17namespace dvr {
18
19ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
Corey Tabaka52ea25c2017-09-13 18:02:48 -070020 int channel_id, uint64_t consumer_state_bit,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080021 const std::shared_ptr<Channel> producer)
22 : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
Corey Tabaka52ea25c2017-09-13 18:02:48 -070023 consumer_state_bit_(consumer_state_bit),
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024 producer_(producer) {
25 GetProducer()->AddConsumer(this);
26}
27
28ConsumerChannel::~ConsumerChannel() {
Corey Tabaka3079cb72017-01-19 15:07:26 -080029 ALOGD_IF(TRACE,
30 "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
31 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080032
33 if (auto producer = GetProducer()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034 producer->RemoveConsumer(this);
35 }
36}
37
38BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
39 BufferHubChannel::BufferInfo info;
40 if (auto producer = GetProducer()) {
41 // If producer has not hung up, copy most buffer info from the producer.
42 info = producer->GetBufferInfo();
Corey Tabaka52ea25c2017-09-13 18:02:48 -070043 } else {
44 info.signaled_mask = consumer_state_bit();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080045 }
46 info.id = buffer_id();
47 return info;
48}
49
50std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
51 return std::static_pointer_cast<ProducerChannel>(producer_.lock());
52}
53
54void ConsumerChannel::HandleImpulse(Message& message) {
55 ATRACE_NAME("ConsumerChannel::HandleImpulse");
56 switch (message.GetOp()) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -070057 case BufferHubRPC::ConsumerAcquire::Opcode:
58 OnConsumerAcquire(message);
59 break;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080060 case BufferHubRPC::ConsumerRelease::Opcode:
61 OnConsumerRelease(message, {});
62 break;
63 }
64}
65
66bool ConsumerChannel::HandleMessage(Message& message) {
67 ATRACE_NAME("ConsumerChannel::HandleMessage");
68 auto producer = GetProducer();
69 if (!producer)
70 REPLY_ERROR_RETURN(message, EPIPE, true);
71
72 switch (message.GetOp()) {
73 case BufferHubRPC::GetBuffer::Opcode:
74 DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
Corey Tabaka52ea25c2017-09-13 18:02:48 -070075 *this, &ConsumerChannel::OnGetBuffer, message);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080076 return true;
77
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080078 case BufferHubRPC::NewConsumer::Opcode:
79 DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
80 *producer, &ProducerChannel::OnNewConsumer, message);
81 return true;
82
83 case BufferHubRPC::ConsumerAcquire::Opcode:
84 DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
85 *this, &ConsumerChannel::OnConsumerAcquire, message);
86 return true;
87
88 case BufferHubRPC::ConsumerRelease::Opcode:
89 DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
90 *this, &ConsumerChannel::OnConsumerRelease, message);
91 return true;
92
93 case BufferHubRPC::ConsumerSetIgnore::Opcode:
94 DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>(
95 *this, &ConsumerChannel::OnConsumerSetIgnore, message);
96 return true;
97
98 default:
99 return false;
100 }
101}
102
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700103Status<BufferDescription<BorrowedHandle>> ConsumerChannel::OnGetBuffer(
104 Message& /*message*/) {
105 ATRACE_NAME("ConsumerChannel::OnGetBuffer");
106 ALOGD_IF(TRACE, "ConsumerChannel::OnGetBuffer: buffer=%d", buffer_id());
107 if (auto producer = GetProducer()) {
108 return {producer->GetBuffer(consumer_state_bit_)};
109 } else {
110 return ErrorStatus(EPIPE);
111 }
112}
113
114Status<LocalFence> ConsumerChannel::OnConsumerAcquire(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800115 ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
116 auto producer = GetProducer();
117 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700118 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800119
Corey Tabakad53870c2017-07-06 18:04:27 -0700120 if (acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800121 ALOGE(
122 "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700123 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
124 ignored_, acquired_, released_, message.GetChannelId(),
125 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700126 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800127 } else {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700128 auto status = producer->OnConsumerAcquire(message);
Corey Tabakad53870c2017-07-06 18:04:27 -0700129 if (status) {
130 ClearAvailable();
131 acquired_ = true;
132 }
133 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800134 }
135}
136
Corey Tabakacd52dd92017-04-07 18:03:57 -0700137Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
138 LocalFence release_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800139 ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
140 auto producer = GetProducer();
141 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700142 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800143
Corey Tabakad53870c2017-07-06 18:04:27 -0700144 if (!acquired_ || released_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800145 ALOGE(
146 "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
Corey Tabakad53870c2017-07-06 18:04:27 -0700147 "ignored=%d acquired=%d released=%d channel_id=%d buffer_id=%d",
148 ignored_, acquired_, released_, message.GetChannelId(),
149 producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700150 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800151 } else {
Corey Tabakacd52dd92017-04-07 18:03:57 -0700152 auto status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800153 producer->OnConsumerRelease(message, std::move(release_fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700154 if (status) {
155 ClearAvailable();
156 acquired_ = false;
157 released_ = true;
158 }
Corey Tabakacd52dd92017-04-07 18:03:57 -0700159 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800160 }
161}
162
Corey Tabakacd52dd92017-04-07 18:03:57 -0700163Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800164 ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
165 auto producer = GetProducer();
166 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700167 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800168
169 ignored_ = ignored;
Corey Tabakad53870c2017-07-06 18:04:27 -0700170 if (ignored_ && acquired_) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800171 // Update the producer if ignore is set after the consumer acquires the
172 // buffer.
173 ClearAvailable();
174 producer->OnConsumerIgnored();
Corey Tabakad53870c2017-07-06 18:04:27 -0700175 acquired_ = false;
176 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800177 }
178
Corey Tabakacd52dd92017-04-07 18:03:57 -0700179 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800180}
181
182bool ConsumerChannel::OnProducerPosted() {
183 if (ignored_) {
Corey Tabakad53870c2017-07-06 18:04:27 -0700184 acquired_ = false;
185 released_ = true;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800186 return false;
187 } else {
Corey Tabakad53870c2017-07-06 18:04:27 -0700188 acquired_ = false;
189 released_ = false;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800190 SignalAvailable();
191 return true;
192 }
193}
194
195void ConsumerChannel::OnProducerClosed() {
196 producer_.reset();
197 Hangup();
198}
199
200} // namespace dvr
201} // namespace android