blob: 311f5c6ab401f582d94d1cbae7aabf9ad8a2b240 [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
Corey Tabakacd52dd92017-04-07 18:03:57 -070011using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080012using android::pdx::BorrowedHandle;
13using android::pdx::Channel;
14using 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),
25 handled_(true),
26 ignored_(false),
27 producer_(producer) {
28 GetProducer()->AddConsumer(this);
29}
30
31ConsumerChannel::~ConsumerChannel() {
Corey Tabaka3079cb72017-01-19 15:07:26 -080032 ALOGD_IF(TRACE,
33 "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
34 channel_id(), buffer_id());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035
36 if (auto producer = GetProducer()) {
37 if (!handled_) // Producer is waiting for our Release.
38 producer->OnConsumerIgnored();
39 producer->RemoveConsumer(this);
40 }
41}
42
43BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
44 BufferHubChannel::BufferInfo info;
45 if (auto producer = GetProducer()) {
46 // If producer has not hung up, copy most buffer info from the producer.
47 info = producer->GetBufferInfo();
48 }
49 info.id = buffer_id();
50 return info;
51}
52
53std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
54 return std::static_pointer_cast<ProducerChannel>(producer_.lock());
55}
56
57void ConsumerChannel::HandleImpulse(Message& message) {
58 ATRACE_NAME("ConsumerChannel::HandleImpulse");
59 switch (message.GetOp()) {
60 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>(
75 *producer, &ProducerChannel::OnGetBuffer, message);
76 return true;
77
78 case BufferHubRPC::GetBuffers::Opcode:
79 DispatchRemoteMethod<BufferHubRPC::GetBuffers>(
80 *producer, &ProducerChannel::OnGetBuffers, message);
81 return true;
82
83 case BufferHubRPC::NewConsumer::Opcode:
84 DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
85 *producer, &ProducerChannel::OnNewConsumer, message);
86 return true;
87
88 case BufferHubRPC::ConsumerAcquire::Opcode:
89 DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
90 *this, &ConsumerChannel::OnConsumerAcquire, message);
91 return true;
92
93 case BufferHubRPC::ConsumerRelease::Opcode:
94 DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
95 *this, &ConsumerChannel::OnConsumerRelease, message);
96 return true;
97
98 case BufferHubRPC::ConsumerSetIgnore::Opcode:
99 DispatchRemoteMethod<BufferHubRPC::ConsumerSetIgnore>(
100 *this, &ConsumerChannel::OnConsumerSetIgnore, message);
101 return true;
102
103 default:
104 return false;
105 }
106}
107
Corey Tabakacd52dd92017-04-07 18:03:57 -0700108Status<std::pair<BorrowedFence, ConsumerChannel::MetaData>>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800109ConsumerChannel::OnConsumerAcquire(Message& message,
110 std::size_t metadata_size) {
111 ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
112 auto producer = GetProducer();
113 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700114 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800115
116 if (ignored_ || handled_) {
117 ALOGE(
118 "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
119 "ignored=%d handled=%d channel_id=%d buffer_id=%d",
120 ignored_, handled_, message.GetChannelId(), producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700121 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800122 } else {
123 ClearAvailable();
124 return producer->OnConsumerAcquire(message, metadata_size);
125 }
126}
127
Corey Tabakacd52dd92017-04-07 18:03:57 -0700128Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
129 LocalFence release_fence) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800130 ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
131 auto producer = GetProducer();
132 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700133 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800134
135 if (ignored_ || handled_) {
136 ALOGE(
137 "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
138 "ignored=%d handled=%d channel_id=%d buffer_id=%d",
139 ignored_, handled_, message.GetChannelId(), producer->buffer_id());
Corey Tabakacd52dd92017-04-07 18:03:57 -0700140 return ErrorStatus(EBUSY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800141 } else {
142 ClearAvailable();
Corey Tabakacd52dd92017-04-07 18:03:57 -0700143 auto status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800144 producer->OnConsumerRelease(message, std::move(release_fence));
Corey Tabakacd52dd92017-04-07 18:03:57 -0700145 handled_ = !!status;
146 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800147 }
148}
149
Corey Tabakacd52dd92017-04-07 18:03:57 -0700150Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800151 ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
152 auto producer = GetProducer();
153 if (!producer)
Corey Tabakacd52dd92017-04-07 18:03:57 -0700154 return ErrorStatus(EPIPE);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800155
156 ignored_ = ignored;
157 if (ignored_ && !handled_) {
158 // Update the producer if ignore is set after the consumer acquires the
159 // buffer.
160 ClearAvailable();
161 producer->OnConsumerIgnored();
162 handled_ = false;
163 }
164
Corey Tabakacd52dd92017-04-07 18:03:57 -0700165 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166}
167
168bool ConsumerChannel::OnProducerPosted() {
169 if (ignored_) {
170 handled_ = true;
171 return false;
172 } else {
173 handled_ = false;
174 SignalAvailable();
175 return true;
176 }
177}
178
179void ConsumerChannel::OnProducerClosed() {
180 producer_.reset();
181 Hangup();
182}
183
184} // namespace dvr
185} // namespace android