xref: /aosp_15_r20/frameworks/native/libs/gui/IProducerListener.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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