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 };
29
30 class BpProducerListener : public BpInterface<IProducerListener>
31 {
32 public:
BpProducerListener(const sp<IBinder> & impl)33 explicit BpProducerListener(const sp<IBinder>& impl)
34 : BpInterface<IProducerListener>(impl) {}
35
36 virtual ~BpProducerListener();
37
onBufferReleased()38 virtual void onBufferReleased() {
39 Parcel data, reply;
40 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
41 remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
42 }
43
needsReleaseNotify()44 virtual bool needsReleaseNotify() {
45 bool result;
46 Parcel data, reply;
47 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
48 status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply);
49 if (err != NO_ERROR) {
50 ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed");
51 return true;
52 }
53 err = reply.readBool(&result);
54 if (err != NO_ERROR) {
55 ALOGE("IProducerListener: malformed binder reply");
56 return true;
57 }
58 return result;
59 }
60
onBuffersDiscarded(const std::vector<int> & discardedSlots)61 virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) {
62 Parcel data, reply;
63 data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
64 data.writeInt32Vector(discardedSlots);
65 remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY);
66 }
67 };
68
69 // Out-of-line virtual method definition to trigger vtable emission in this
70 // translation unit (see clang warning -Wweak-vtables)
~BpProducerListener()71 BpProducerListener::~BpProducerListener() {}
72
73 class HpProducerListener : public HpInterface<
74 BpProducerListener,
75 hardware::graphics::bufferqueue::V1_0::utils::H2BProducerListener,
76 hardware::graphics::bufferqueue::V2_0::utils::H2BProducerListener> {
77 public:
HpProducerListener(const sp<IBinder> & base)78 explicit HpProducerListener(const sp<IBinder>& base) : PBase{base} {}
79
onBufferReleased()80 virtual void onBufferReleased() override {
81 mBase->onBufferReleased();
82 }
83
needsReleaseNotify()84 virtual bool needsReleaseNotify() override {
85 return mBase->needsReleaseNotify();
86 }
87
onBuffersDiscarded(const std::vector<int32_t> & discardedSlots)88 virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override {
89 return mBase->onBuffersDiscarded(discardedSlots);
90 }
91 };
92
93 IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener,
94 "android.gui.IProducerListener")
95
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)96 status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
97 Parcel* reply, uint32_t flags) {
98 switch (code) {
99 case ON_BUFFER_RELEASED:
100 CHECK_INTERFACE(IProducerListener, data, reply);
101 onBufferReleased();
102 return NO_ERROR;
103 case NEEDS_RELEASE_NOTIFY:
104 CHECK_INTERFACE(IProducerListener, data, reply);
105 reply->writeBool(needsReleaseNotify());
106 return NO_ERROR;
107 case ON_BUFFERS_DISCARDED: {
108 CHECK_INTERFACE(IProducerListener, data, reply);
109 std::vector<int32_t> discardedSlots;
110 status_t result = data.readInt32Vector(&discardedSlots);
111 if (result != NO_ERROR) {
112 ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result);
113 return result;
114 }
115 onBuffersDiscarded(discardedSlots);
116 return NO_ERROR;
117 }
118 }
119 return BBinder::onTransact(code, data, reply, flags);
120 }
121
122 StubProducerListener::~StubProducerListener() = default;
123
needsReleaseNotify()124 bool BnProducerListener::needsReleaseNotify() {
125 return true;
126 }
127
onBuffersDiscarded(const std::vector<int32_t> &)128 void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) {
129 }
130
131 } // namespace android
132