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_dummy {
55     template <typename T>
56     LOG_dummy& operator<< (const T&) { return *this; }
57 };
58 
59 #define LOG(x)  LOG_dummy()
60 #endif
61 
62 // Instantiate only if HGraphicBufferProducer is base of BASE.
63 template <typename BASE,
64           typename = typename std::enable_if<std::is_base_of<HGraphicBufferProducer, BASE>::value>::type>
65 struct TWGraphicBufferProducer : public BASE {
TWGraphicBufferProducerTWGraphicBufferProducer66     TWGraphicBufferProducer(sp<BGraphicBufferProducer> const& base) : mBase(base) {}
requestBufferTWGraphicBufferProducer67     Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
68         sp<GraphicBuffer> buf;
69         status_t status = mBase->requestBuffer(slot, &buf);
70         AnwBuffer anwBuffer{};
71         if (buf != nullptr) {
72             ::android::conversion::wrapAs(&anwBuffer, *buf);
73         }
74         _hidl_cb(static_cast<int32_t>(status), anwBuffer);
75         return Void();
76     }
77 
setMaxDequeuedBufferCountTWGraphicBufferProducer78     Return<int32_t> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override {
79         return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount(
80                 static_cast<int>(maxDequeuedBuffers)));
81     }
82 
setAsyncModeTWGraphicBufferProducer83     Return<int32_t> setAsyncMode(bool async) override {
84         return static_cast<int32_t>(mBase->setAsyncMode(async));
85     }
86 
dequeueBufferTWGraphicBufferProducer87     Return<void> dequeueBuffer(
88             uint32_t width, uint32_t height,
89             ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
90             bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
91         int slot{};
92         sp<Fence> fence;
93         ::android::FrameEventHistoryDelta outTimestamps;
94         status_t status = mBase->dequeueBuffer(
95             &slot, &fence, width, height,
96             static_cast<::android::PixelFormat>(format), usage, nullptr,
97             getFrameTimestamps ? &outTimestamps : nullptr);
98         hidl_handle tFence{};
99         HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{};
100 
101         native_handle_t* nh = nullptr;
102         if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
103             LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
104                     "Invalid output fence";
105             _hidl_cb(static_cast<int32_t>(status),
106                      static_cast<int32_t>(slot),
107                      tFence,
108                      tOutTimestamps);
109             return Void();
110         }
111         std::vector<std::vector<native_handle_t*> > nhAA;
112         if (getFrameTimestamps && !::android::conversion::wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
113             LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
114                     "Invalid output timestamps";
115             _hidl_cb(static_cast<int32_t>(status),
116                      static_cast<int32_t>(slot),
117                      tFence,
118                      tOutTimestamps);
119             native_handle_delete(nh);
120             return Void();
121         }
122 
123         _hidl_cb(static_cast<int32_t>(status),
124                 static_cast<int32_t>(slot),
125                 tFence,
126                 tOutTimestamps);
127         native_handle_delete(nh);
128         if (getFrameTimestamps) {
129             for (auto& nhA : nhAA) {
130                 for (auto& handle : nhA) {
131                     native_handle_delete(handle);
132                 }
133             }
134         }
135         return Void();
136     }
137 
detachBufferTWGraphicBufferProducer138     Return<int32_t> detachBuffer(int32_t slot) override {
139         return static_cast<int32_t>(mBase->detachBuffer(slot));
140     }
141 
detachNextBufferTWGraphicBufferProducer142     Return<void> detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override {
143         sp<GraphicBuffer> outBuffer;
144         sp<Fence> outFence;
145         status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
146         AnwBuffer tBuffer{};
147         hidl_handle tFence{};
148 
149         if (outBuffer == nullptr) {
150             LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
151                     "Invalid output buffer";
152             _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
153             return Void();
154         }
155         ::android::conversion::wrapAs(&tBuffer, *outBuffer);
156         native_handle_t* nh = nullptr;
157         if ((outFence != nullptr) && !::android::conversion::wrapAs(&tFence, &nh, *outFence)) {
158             LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
159                     "Invalid output fence";
160             _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
161             return Void();
162         }
163 
164         _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
165         native_handle_delete(nh);
166         return Void();
167     }
168 
attachBufferTWGraphicBufferProducer169     Return<void> attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override {
170         int outSlot;
171         sp<GraphicBuffer> lBuffer = new GraphicBuffer();
172         if (!::android::conversion::convertTo(lBuffer.get(), buffer)) {
173             LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - "
174                     "Invalid input native window buffer";
175             _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1);
176             return Void();
177         }
178         status_t status = mBase->attachBuffer(&outSlot, lBuffer);
179 
180         _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot));
181         return Void();
182     }
183 
queueBufferTWGraphicBufferProducer184     Return<void> queueBuffer(
185             int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
186             HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
187         HGraphicBufferProducer::QueueBufferOutput tOutput{};
188         BGraphicBufferProducer::QueueBufferInput lInput(
189                 0, false, HAL_DATASPACE_UNKNOWN,
190                 ::android::Rect(0, 0, 1, 1),
191                 NATIVE_WINDOW_SCALING_MODE_FREEZE,
192                 0, ::android::Fence::NO_FENCE);
193         if (!::android::conversion::convertTo(&lInput, input)) {
194             LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
195                     "Invalid input";
196             _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
197             return Void();
198         }
199         BGraphicBufferProducer::QueueBufferOutput lOutput;
200         status_t status = mBase->queueBuffer(
201                 static_cast<int>(slot), lInput, &lOutput);
202 
203         std::vector<std::vector<native_handle_t*> > nhAA;
204         if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
205             LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
206                     "Invalid output";
207             _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
208             return Void();
209         }
210 
211         _hidl_cb(static_cast<int32_t>(status), tOutput);
212         for (auto& nhA : nhAA) {
213             for (auto& nh : nhA) {
214                 native_handle_delete(nh);
215             }
216         }
217         return Void();
218     }
219 
cancelBufferTWGraphicBufferProducer220     Return<int32_t> cancelBuffer(int32_t slot, const hidl_handle& fence) override {
221         sp<Fence> lFence = new Fence();
222         if (!::android::conversion::convertTo(lFence.get(), fence)) {
223             LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - "
224                     "Invalid input fence";
225             return static_cast<int32_t>(BAD_VALUE);
226         }
227         return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence));
228     }
229 
queryTWGraphicBufferProducer230     Return<void> query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override {
231         int lValue;
232         int lReturn = mBase->query(static_cast<int>(what), &lValue);
233         _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue));
234         return Void();
235     }
236 
connectTWGraphicBufferProducer237     Return<void> connect(const sp<HProducerListener>& listener,
238             int32_t api, bool producerControlledByApp,
239             HGraphicBufferProducer::connect_cb _hidl_cb) override {
240         sp<BProducerListener> lListener = listener == nullptr ?
241                 nullptr : new LWProducerListener(listener);
242         BGraphicBufferProducer::QueueBufferOutput lOutput;
243         status_t status = mBase->connect(lListener,
244                 static_cast<int>(api),
245                 producerControlledByApp,
246                 &lOutput);
247 
248         HGraphicBufferProducer::QueueBufferOutput tOutput{};
249         std::vector<std::vector<native_handle_t*> > nhAA;
250         if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
251             LOG(ERROR) << "TWGraphicBufferProducer::connect - "
252                     "Invalid output";
253             _hidl_cb(static_cast<int32_t>(status), tOutput);
254             return Void();
255         }
256 
257         _hidl_cb(static_cast<int32_t>(status), tOutput);
258         for (auto& nhA : nhAA) {
259             for (auto& nh : nhA) {
260                 native_handle_delete(nh);
261             }
262         }
263         return Void();
264     }
265 
disconnectTWGraphicBufferProducer266     Return<int32_t> disconnect(
267             int32_t api,
268             HGraphicBufferProducer::DisconnectMode mode) override {
269         return static_cast<int32_t>(mBase->disconnect(
270                 static_cast<int>(api),
271                 ::android::conversion::toGuiDisconnectMode(mode)));
272     }
273 
setSidebandStreamTWGraphicBufferProducer274     Return<int32_t> setSidebandStream(const hidl_handle& stream) override {
275         return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create(
276                 stream ? native_handle_clone(stream) : NULL, true)));
277     }
278 
allocateBuffersTWGraphicBufferProducer279     Return<void> allocateBuffers(
280             uint32_t width, uint32_t height,
281             ::android::hardware::graphics::common::V1_0::PixelFormat format,
282             uint32_t usage) override {
283         mBase->allocateBuffers(
284                 width, height,
285                 static_cast<::android::PixelFormat>(format),
286                 usage);
287         return Void();
288     }
289 
allowAllocationTWGraphicBufferProducer290     Return<int32_t> allowAllocation(bool allow) override {
291         return static_cast<int32_t>(mBase->allowAllocation(allow));
292     }
293 
setGenerationNumberTWGraphicBufferProducer294     Return<int32_t> setGenerationNumber(uint32_t generationNumber) override {
295         return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber));
296     }
297 
getConsumerNameTWGraphicBufferProducer298     Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
299         _hidl_cb(mBase->getConsumerName().string());
300         return Void();
301     }
302 
setSharedBufferModeTWGraphicBufferProducer303     Return<int32_t> setSharedBufferMode(bool sharedBufferMode) override {
304         return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode));
305     }
306 
setAutoRefreshTWGraphicBufferProducer307     Return<int32_t> setAutoRefresh(bool autoRefresh) override {
308         return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh));
309     }
310 
setDequeueTimeoutTWGraphicBufferProducer311     Return<int32_t> setDequeueTimeout(int64_t timeoutNs) override {
312         return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs));
313     }
314 
getLastQueuedBufferTWGraphicBufferProducer315     Return<void> getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override {
316         sp<GraphicBuffer> lOutBuffer = new GraphicBuffer();
317         sp<Fence> lOutFence = new Fence();
318         float lOutTransformMatrix[16];
319         status_t status = mBase->getLastQueuedBuffer(
320                 &lOutBuffer, &lOutFence, lOutTransformMatrix);
321 
322         AnwBuffer tOutBuffer{};
323         if (lOutBuffer != nullptr) {
324             ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
325         }
326         hidl_handle tOutFence{};
327         native_handle_t* nh = nullptr;
328         if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
329             LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
330                     "Invalid output fence";
331             _hidl_cb(static_cast<int32_t>(status),
332                     tOutBuffer,
333                     tOutFence,
334                     hidl_array<float, 16>());
335             return Void();
336         }
337         hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix);
338 
339         _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix);
340         native_handle_delete(nh);
341         return Void();
342     }
343 
getFrameTimestampsTWGraphicBufferProducer344     Return<void> getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override {
345         ::android::FrameEventHistoryDelta lDelta;
346         mBase->getFrameTimestamps(&lDelta);
347 
348         HGraphicBufferProducer::FrameEventHistoryDelta tDelta{};
349         std::vector<std::vector<native_handle_t*> > nhAA;
350         if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
351             LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
352                     "Invalid output frame timestamps";
353             _hidl_cb(tDelta);
354             return Void();
355         }
356 
357         _hidl_cb(tDelta);
358         for (auto& nhA : nhAA) {
359             for (auto& nh : nhA) {
360                 native_handle_delete(nh);
361             }
362         }
363         return Void();
364     }
365 
getUniqueIdTWGraphicBufferProducer366     Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
367         uint64_t outId{};
368         status_t status = mBase->getUniqueId(&outId);
369         _hidl_cb(static_cast<int32_t>(status), outId);
370         return Void();
371     }
372 
373 private:
374     sp<BGraphicBufferProducer> mBase;
375 };
376 
377 }  // namespace android
378 
379 #endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_
380