1 /*
2  * Copyright 2016, 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 #ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_
18 #define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_
19 
20 #include <hidl/MQDescriptor.h>
21 #include <hidl/Status.h>
22 
23 #include <binder/Binder.h>
24 #include <gui/IGraphicBufferProducer.h>
25 #include <gui/IProducerListener.h>
26 #include <gui/bufferqueue/1.0/Conversion.h>
27 #include <gui/bufferqueue/1.0/WProducerListener.h>
28 #include <system/window.h>
29 
30 #include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
31 
32 namespace android {
33 
34 using ::android::hardware::media::V1_0::AnwBuffer;
35 using ::android::hidl::base::V1_0::IBase;
36 using ::android::hardware::hidl_array;
37 using ::android::hardware::hidl_handle;
38 using ::android::hardware::hidl_memory;
39 using ::android::hardware::hidl_string;
40 using ::android::hardware::hidl_vec;
41 using ::android::hardware::Return;
42 using ::android::hardware::Void;
43 using ::android::sp;
44 
45 typedef ::android::hardware::graphics::bufferqueue::V1_0::
46         IGraphicBufferProducer HGraphicBufferProducer;
47 typedef ::android::hardware::graphics::bufferqueue::V1_0::
48         IProducerListener HProducerListener;
49 
50 typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
51 typedef ::android::IProducerListener BProducerListener;
52 
53 #ifndef LOG
54 struct LOG_stub {
55     template <typename T>
56     LOG_stub& operator<<(const T&) {
57         return *this;
58     }
59 };
60 
61 #define LOG(x) LOG_stub()
62 #endif
63 
64 // Instantiate only if HGraphicBufferProducer is base of BASE.
65 template <typename BASE,
66           typename = typename std::enable_if<std::is_base_of<HGraphicBufferProducer, BASE>::value>::type>
67 struct TWGraphicBufferProducer : public BASE {
TWGraphicBufferProducerTWGraphicBufferProducer68     TWGraphicBufferProducer(sp<BGraphicBufferProducer> const& base) : mBase(base) {}
requestBufferTWGraphicBufferProducer69     Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
70         sp<GraphicBuffer> buf;
71         status_t status = mBase->requestBuffer(slot, &buf);
72         AnwBuffer anwBuffer{};
73         if (buf != nullptr) {
74             ::android::conversion::wrapAs(&anwBuffer, *buf);
75         }
76         _hidl_cb(static_cast<int32_t>(status), anwBuffer);
77         return Void();
78     }
79 
setMaxDequeuedBufferCountTWGraphicBufferProducer80     Return<int32_t> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override {
81         return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount(
82                 static_cast<int>(maxDequeuedBuffers)));
83     }
84 
setAsyncModeTWGraphicBufferProducer85     Return<int32_t> setAsyncMode(bool async) override {
86         return static_cast<int32_t>(mBase->setAsyncMode(async));
87     }
88 
dequeueBufferTWGraphicBufferProducer89     Return<void> dequeueBuffer(
90             uint32_t width, uint32_t height,
91             ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
92             bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
93         int slot{};
94         sp<Fence> fence;
95         ::android::FrameEventHistoryDelta outTimestamps;
96         status_t status = mBase->dequeueBuffer(
97             &slot, &fence, width, height,
98             static_cast<::android::PixelFormat>(format), usage, nullptr,
99             getFrameTimestamps ? &outTimestamps : nullptr);
100         hidl_handle tFence{};
101         HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{};
102 
103         native_handle_t* nh = nullptr;
104         if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
105             LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
106                     "Invalid output fence";
107             _hidl_cb(static_cast<int32_t>(status),
108                      static_cast<int32_t>(slot),
109                      tFence,
110                      tOutTimestamps);
111             return Void();
112         }
113         std::vector<std::vector<native_handle_t*> > nhAA;
114         if (getFrameTimestamps && !::android::conversion::wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
115             LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
116                     "Invalid output timestamps";
117             _hidl_cb(static_cast<int32_t>(status),
118                      static_cast<int32_t>(slot),
119                      tFence,
120                      tOutTimestamps);
121             native_handle_delete(nh);
122             return Void();
123         }
124 
125         _hidl_cb(static_cast<int32_t>(status),
126                 static_cast<int32_t>(slot),
127                 tFence,
128                 tOutTimestamps);
129         native_handle_delete(nh);
130         if (getFrameTimestamps) {
131             for (auto& nhA : nhAA) {
132                 for (auto& handle : nhA) {
133                     native_handle_delete(handle);
134                 }
135             }
136         }
137         return Void();
138     }
139 
detachBufferTWGraphicBufferProducer140     Return<int32_t> detachBuffer(int32_t slot) override {
141         return static_cast<int32_t>(mBase->detachBuffer(slot));
142     }
143 
detachNextBufferTWGraphicBufferProducer144     Return<void> detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override {
145         sp<GraphicBuffer> outBuffer;
146         sp<Fence> outFence;
147         status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
148         AnwBuffer tBuffer{};
149         hidl_handle tFence{};
150 
151         if (outBuffer == nullptr) {
152             LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
153                     "Invalid output buffer";
154             _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
155             return Void();
156         }
157         ::android::conversion::wrapAs(&tBuffer, *outBuffer);
158         native_handle_t* nh = nullptr;
159         if ((outFence != nullptr) && !::android::conversion::wrapAs(&tFence, &nh, *outFence)) {
160             LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
161                     "Invalid output fence";
162             _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
163             return Void();
164         }
165 
166         _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
167         native_handle_delete(nh);
168         return Void();
169     }
170 
attachBufferTWGraphicBufferProducer171     Return<void> attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override {
172         int outSlot;
173         sp<GraphicBuffer> lBuffer = new GraphicBuffer();
174         if (!::android::conversion::convertTo(lBuffer.get(), buffer)) {
175             LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - "
176                     "Invalid input native window buffer";
177             _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1);
178             return Void();
179         }
180         status_t status = mBase->attachBuffer(&outSlot, lBuffer);
181 
182         _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot));
183         return Void();
184     }
185 
queueBufferTWGraphicBufferProducer186     Return<void> queueBuffer(
187             int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
188             HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
189         HGraphicBufferProducer::QueueBufferOutput tOutput{};
190         BGraphicBufferProducer::QueueBufferInput lInput(
191                 0, false, HAL_DATASPACE_UNKNOWN,
192                 ::android::Rect(0, 0, 1, 1),
193                 NATIVE_WINDOW_SCALING_MODE_FREEZE,
194                 0, ::android::Fence::NO_FENCE);
195         if (!::android::conversion::convertTo(&lInput, input)) {
196             LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
197                     "Invalid input";
198             _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
199             return Void();
200         }
201         BGraphicBufferProducer::QueueBufferOutput lOutput;
202         status_t status = mBase->queueBuffer(
203                 static_cast<int>(slot), lInput, &lOutput);
204 
205         std::vector<std::vector<native_handle_t*> > nhAA;
206         if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
207             LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
208                     "Invalid output";
209             _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
210             return Void();
211         }
212 
213         _hidl_cb(static_cast<int32_t>(status), tOutput);
214         for (auto& nhA : nhAA) {
215             for (auto& nh : nhA) {
216                 native_handle_delete(nh);
217             }
218         }
219         return Void();
220     }
221 
cancelBufferTWGraphicBufferProducer222     Return<int32_t> cancelBuffer(int32_t slot, const hidl_handle& fence) override {
223         sp<Fence> lFence = new Fence();
224         if (!::android::conversion::convertTo(lFence.get(), fence)) {
225             LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - "
226                     "Invalid input fence";
227             return static_cast<int32_t>(BAD_VALUE);
228         }
229         return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence));
230     }
231 
queryTWGraphicBufferProducer232     Return<void> query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override {
233         int lValue;
234         int lReturn = mBase->query(static_cast<int>(what), &lValue);
235         _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue));
236         return Void();
237     }
238 
connectTWGraphicBufferProducer239     Return<void> connect(const sp<HProducerListener>& listener,
240             int32_t api, bool producerControlledByApp,
241             HGraphicBufferProducer::connect_cb _hidl_cb) override {
242         sp<BProducerListener> lListener = listener == nullptr ?
243                 nullptr : new LWProducerListener(listener);
244         BGraphicBufferProducer::QueueBufferOutput lOutput;
245         status_t status = mBase->connect(lListener,
246                 static_cast<int>(api),
247                 producerControlledByApp,
248                 &lOutput);
249 
250         HGraphicBufferProducer::QueueBufferOutput tOutput{};
251         std::vector<std::vector<native_handle_t*> > nhAA;
252         if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
253             LOG(ERROR) << "TWGraphicBufferProducer::connect - "
254                     "Invalid output";
255             _hidl_cb(static_cast<int32_t>(status), tOutput);
256             return Void();
257         }
258 
259         _hidl_cb(static_cast<int32_t>(status), tOutput);
260         for (auto& nhA : nhAA) {
261             for (auto& nh : nhA) {
262                 native_handle_delete(nh);
263             }
264         }
265         return Void();
266     }
267 
disconnectTWGraphicBufferProducer268     Return<int32_t> disconnect(
269             int32_t api,
270             HGraphicBufferProducer::DisconnectMode mode) override {
271         return static_cast<int32_t>(mBase->disconnect(
272                 static_cast<int>(api),
273                 ::android::conversion::toGuiDisconnectMode(mode)));
274     }
275 
setSidebandStreamTWGraphicBufferProducer276     Return<int32_t> setSidebandStream(const hidl_handle& stream) override {
277         return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create(
278                 stream ? native_handle_clone(stream) : NULL, true)));
279     }
280 
allocateBuffersTWGraphicBufferProducer281     Return<void> allocateBuffers(
282             uint32_t width, uint32_t height,
283             ::android::hardware::graphics::common::V1_0::PixelFormat format,
284             uint32_t usage) override {
285         mBase->allocateBuffers(
286                 width, height,
287                 static_cast<::android::PixelFormat>(format),
288                 usage);
289         return Void();
290     }
291 
allowAllocationTWGraphicBufferProducer292     Return<int32_t> allowAllocation(bool allow) override {
293         return static_cast<int32_t>(mBase->allowAllocation(allow));
294     }
295 
setGenerationNumberTWGraphicBufferProducer296     Return<int32_t> setGenerationNumber(uint32_t generationNumber) override {
297         return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber));
298     }
299 
getConsumerNameTWGraphicBufferProducer300     Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
301         _hidl_cb(mBase->getConsumerName().string());
302         return Void();
303     }
304 
setSharedBufferModeTWGraphicBufferProducer305     Return<int32_t> setSharedBufferMode(bool sharedBufferMode) override {
306         return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode));
307     }
308 
setAutoRefreshTWGraphicBufferProducer309     Return<int32_t> setAutoRefresh(bool autoRefresh) override {
310         return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh));
311     }
312 
setDequeueTimeoutTWGraphicBufferProducer313     Return<int32_t> setDequeueTimeout(int64_t timeoutNs) override {
314         return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs));
315     }
316 
getLastQueuedBufferTWGraphicBufferProducer317     Return<void> getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override {
318         sp<GraphicBuffer> lOutBuffer = new GraphicBuffer();
319         sp<Fence> lOutFence = new Fence();
320         float lOutTransformMatrix[16];
321         status_t status = mBase->getLastQueuedBuffer(
322                 &lOutBuffer, &lOutFence, lOutTransformMatrix);
323 
324         AnwBuffer tOutBuffer{};
325         if (lOutBuffer != nullptr) {
326             ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
327         }
328         hidl_handle tOutFence{};
329         native_handle_t* nh = nullptr;
330         if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
331             LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
332                     "Invalid output fence";
333             _hidl_cb(static_cast<int32_t>(status),
334                     tOutBuffer,
335                     tOutFence,
336                     hidl_array<float, 16>());
337             return Void();
338         }
339         hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix);
340 
341         _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix);
342         native_handle_delete(nh);
343         return Void();
344     }
345 
getFrameTimestampsTWGraphicBufferProducer346     Return<void> getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override {
347         ::android::FrameEventHistoryDelta lDelta;
348         mBase->getFrameTimestamps(&lDelta);
349 
350         HGraphicBufferProducer::FrameEventHistoryDelta tDelta{};
351         std::vector<std::vector<native_handle_t*> > nhAA;
352         if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
353             LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
354                     "Invalid output frame timestamps";
355             _hidl_cb(tDelta);
356             return Void();
357         }
358 
359         _hidl_cb(tDelta);
360         for (auto& nhA : nhAA) {
361             for (auto& nh : nhA) {
362                 native_handle_delete(nh);
363             }
364         }
365         return Void();
366     }
367 
getUniqueIdTWGraphicBufferProducer368     Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
369         uint64_t outId{};
370         status_t status = mBase->getUniqueId(&outId);
371         _hidl_cb(static_cast<int32_t>(status), outId);
372         return Void();
373     }
374 
375 private:
376     sp<BGraphicBufferProducer> mBase;
377 };
378 
379 }  // namespace android
380 
381 #endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_
382