1 /*
2 * Copyright 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <binder/Parcel.h>
18 #include <gui/bufferqueue/1.0/H2BProducerListener.h>
19 #include <gui/bufferqueue/2.0/H2BProducerListener.h>
20 #include <gui/IProducerListener.h>
21
22 namespace android {
23
24 enum {
25 ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
26 NEEDS_RELEASE_NOTIFY,
27 ON_BUFFERS_DISCARDED,
28 ON_BUFFER_DETACHED,
29 ON_BUFFER_ATTACHED,
30 NEEDS_ATTACH_NOTIFY,
31 };
32
33 class BpProducerListener : public BpInterface<IProducerListener>
34 {
35 public:
BpProducerListener(const sp<IBinder> & impl)36 explicit BpProducerListener(const sp<IBinder>& impl)
37 : BpInterface<IProducerListener>(impl) {}
38
39 virtual ~BpProducerListener();
40
onBufferReleased()41 virtual void onBufferReleased() {
42 Parcel data, reply;
43 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
44 remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
45 }
46
needsReleaseNotify()47 virtual bool needsReleaseNotify() {
48 bool result;
49 Parcel data, reply;
50 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
51 status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply);
52 if (err != NO_ERROR) {
53 ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed");
54 return true;
55 }
56 err = reply.readBool(&result);
57 if (err != NO_ERROR) {
58 ALOGE("IProducerListener: malformed binder reply");
59 return true;
60 }
61 return result;
62 }
63
onBuffersDiscarded(const std::vector<int> & discardedSlots)64 virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) {
65 Parcel data, reply;
66 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
67 data.writeInt32Vector(discardedSlots);
68 remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY);
69 }
70
71 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
onBufferDetached(int slot)72 virtual void onBufferDetached(int slot) {
73 Parcel data, reply;
74 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
75 data.writeInt32(slot);
76 remote()->transact(ON_BUFFER_DETACHED, data, &reply, IBinder::FLAG_ONEWAY);
77 }
78
onBufferAttached()79 virtual void onBufferAttached() {
80 Parcel data, reply;
81 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
82 remote()->transact(ON_BUFFER_ATTACHED, data, &reply, IBinder::FLAG_ONEWAY);
83 }
84
needsAttachNotify()85 virtual bool needsAttachNotify() {
86 bool result;
87 Parcel data, reply;
88 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
89 status_t err = remote()->transact(NEEDS_ATTACH_NOTIFY, data, &reply);
90 if (err != NO_ERROR) {
91 ALOGE("IProducerListener: binder call \'needsAttachNotify\' failed");
92 return true;
93 }
94 err = reply.readBool(&result);
95 if (err != NO_ERROR) {
96 ALOGE("IProducerListener: malformed binder reply");
97 return true;
98 }
99 return result;
100 }
101 #endif
102 };
103
104 // Out-of-line virtual method definition to trigger vtable emission in this
105 // translation unit (see clang warning -Wweak-vtables)
~BpProducerListener()106 BpProducerListener::~BpProducerListener() {}
107
108 class HpProducerListener : public HpInterface<
109 BpProducerListener,
110 hardware::graphics::bufferqueue::V1_0::utils::H2BProducerListener,
111 hardware::graphics::bufferqueue::V2_0::utils::H2BProducerListener> {
112 public:
HpProducerListener(const sp<IBinder> & base)113 explicit HpProducerListener(const sp<IBinder>& base) : PBase{base} {}
114
onBufferReleased()115 virtual void onBufferReleased() override {
116 mBase->onBufferReleased();
117 }
118
needsReleaseNotify()119 virtual bool needsReleaseNotify() override {
120 return mBase->needsReleaseNotify();
121 }
122
onBuffersDiscarded(const std::vector<int32_t> & discardedSlots)123 virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override {
124 return mBase->onBuffersDiscarded(discardedSlots);
125 }
126 };
127
128 IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener,
129 "android.gui.IProducerListener")
130
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)131 status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
132 Parcel* reply, uint32_t flags) {
133 switch (code) {
134 case ON_BUFFER_RELEASED:
135 CHECK_INTERFACE(IProducerListener, data, reply);
136 onBufferReleased();
137 return NO_ERROR;
138 case NEEDS_RELEASE_NOTIFY:
139 CHECK_INTERFACE(IProducerListener, data, reply);
140 reply->writeBool(needsReleaseNotify());
141 return NO_ERROR;
142 case ON_BUFFERS_DISCARDED: {
143 CHECK_INTERFACE(IProducerListener, data, reply);
144 std::vector<int32_t> discardedSlots;
145 status_t result = data.readInt32Vector(&discardedSlots);
146 if (result != NO_ERROR) {
147 ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result);
148 return result;
149 }
150 onBuffersDiscarded(discardedSlots);
151 return NO_ERROR;
152 }
153 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
154 case ON_BUFFER_DETACHED: {
155 CHECK_INTERFACE(IProducerListener, data, reply);
156 int slot;
157 status_t result = data.readInt32(&slot);
158 if (result != NO_ERROR) {
159 ALOGE("ON_BUFFER_DETACHED failed to read slot: %d", result);
160 return result;
161 }
162 onBufferDetached(slot);
163 return NO_ERROR;
164 }
165 case ON_BUFFER_ATTACHED:
166 CHECK_INTERFACE(IProducerListener, data, reply);
167 onBufferAttached();
168 return NO_ERROR;
169 case NEEDS_ATTACH_NOTIFY:
170 CHECK_INTERFACE(IProducerListener, data, reply);
171 reply->writeBool(needsAttachNotify());
172 return NO_ERROR;
173 #endif
174 }
175 return BBinder::onTransact(code, data, reply, flags);
176 }
177
178 StubProducerListener::~StubProducerListener() = default;
179
needsReleaseNotify()180 bool BnProducerListener::needsReleaseNotify() {
181 return true;
182 }
183
onBuffersDiscarded(const std::vector<int32_t> &)184 void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) {
185 }
186
187 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
needsAttachNotify()188 bool BnProducerListener::needsAttachNotify() {
189 return true;
190 }
191 #endif
192
193 } // namespace android
194