1 /*
2 * Copyright (C) 2010 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 <stdint.h>
18 #include <sys/types.h>
19
20 #include <utils/Errors.h>
21 #include <utils/NativeHandle.h>
22 #include <utils/RefBase.h>
23 #include <utils/Timers.h>
24 #include <utils/Vector.h>
25
26 #include <binder/Parcel.h>
27 #include <binder/IInterface.h>
28
29 #include <gui/IGraphicBufferProducer.h>
30 #include <gui/IProducerListener.h>
31
32 namespace android {
33 // ----------------------------------------------------------------------------
34
35 enum {
36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
37 SET_BUFFER_COUNT,
38 DEQUEUE_BUFFER,
39 DETACH_BUFFER,
40 DETACH_NEXT_BUFFER,
41 ATTACH_BUFFER,
42 QUEUE_BUFFER,
43 CANCEL_BUFFER,
44 QUERY,
45 CONNECT,
46 DISCONNECT,
47 SET_SIDEBAND_STREAM,
48 ALLOCATE_BUFFERS,
49 ALLOW_ALLOCATION,
50 SET_GENERATION_NUMBER,
51 GET_CONSUMER_NAME,
52 };
53
54 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
55 {
56 public:
BpGraphicBufferProducer(const sp<IBinder> & impl)57 BpGraphicBufferProducer(const sp<IBinder>& impl)
58 : BpInterface<IGraphicBufferProducer>(impl)
59 {
60 }
61
62 virtual ~BpGraphicBufferProducer();
63
requestBuffer(int bufferIdx,sp<GraphicBuffer> * buf)64 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
65 Parcel data, reply;
66 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
67 data.writeInt32(bufferIdx);
68 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
69 if (result != NO_ERROR) {
70 return result;
71 }
72 bool nonNull = reply.readInt32();
73 if (nonNull) {
74 *buf = new GraphicBuffer();
75 result = reply.read(**buf);
76 if(result != NO_ERROR) {
77 (*buf).clear();
78 return result;
79 }
80 }
81 result = reply.readInt32();
82 return result;
83 }
84
setBufferCount(int bufferCount)85 virtual status_t setBufferCount(int bufferCount)
86 {
87 Parcel data, reply;
88 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
89 data.writeInt32(bufferCount);
90 status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
91 if (result != NO_ERROR) {
92 return result;
93 }
94 result = reply.readInt32();
95 return result;
96 }
97
dequeueBuffer(int * buf,sp<Fence> * fence,bool async,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)98 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
99 uint32_t width, uint32_t height, PixelFormat format,
100 uint32_t usage) {
101 Parcel data, reply;
102 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
103 data.writeInt32(static_cast<int32_t>(async));
104 data.writeUint32(width);
105 data.writeUint32(height);
106 data.writeInt32(static_cast<int32_t>(format));
107 data.writeUint32(usage);
108 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
109 if (result != NO_ERROR) {
110 return result;
111 }
112 *buf = reply.readInt32();
113 bool nonNull = reply.readInt32();
114 if (nonNull) {
115 *fence = new Fence();
116 reply.read(**fence);
117 }
118 result = reply.readInt32();
119 return result;
120 }
121
detachBuffer(int slot)122 virtual status_t detachBuffer(int slot) {
123 Parcel data, reply;
124 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
125 data.writeInt32(slot);
126 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
127 if (result != NO_ERROR) {
128 return result;
129 }
130 result = reply.readInt32();
131 return result;
132 }
133
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)134 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
135 sp<Fence>* outFence) {
136 if (outBuffer == NULL) {
137 ALOGE("detachNextBuffer: outBuffer must not be NULL");
138 return BAD_VALUE;
139 } else if (outFence == NULL) {
140 ALOGE("detachNextBuffer: outFence must not be NULL");
141 return BAD_VALUE;
142 }
143 Parcel data, reply;
144 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
145 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
146 if (result != NO_ERROR) {
147 return result;
148 }
149 result = reply.readInt32();
150 if (result == NO_ERROR) {
151 bool nonNull = reply.readInt32();
152 if (nonNull) {
153 *outBuffer = new GraphicBuffer;
154 reply.read(**outBuffer);
155 }
156 nonNull = reply.readInt32();
157 if (nonNull) {
158 *outFence = new Fence;
159 reply.read(**outFence);
160 }
161 }
162 return result;
163 }
164
attachBuffer(int * slot,const sp<GraphicBuffer> & buffer)165 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
166 Parcel data, reply;
167 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
168 data.write(*buffer.get());
169 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
170 if (result != NO_ERROR) {
171 return result;
172 }
173 *slot = reply.readInt32();
174 result = reply.readInt32();
175 return result;
176 }
177
queueBuffer(int buf,const QueueBufferInput & input,QueueBufferOutput * output)178 virtual status_t queueBuffer(int buf,
179 const QueueBufferInput& input, QueueBufferOutput* output) {
180 Parcel data, reply;
181 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
182 data.writeInt32(buf);
183 data.write(input);
184 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
185 if (result != NO_ERROR) {
186 return result;
187 }
188 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
189 result = reply.readInt32();
190 return result;
191 }
192
cancelBuffer(int buf,const sp<Fence> & fence)193 virtual void cancelBuffer(int buf, const sp<Fence>& fence) {
194 Parcel data, reply;
195 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
196 data.writeInt32(buf);
197 data.write(*fence.get());
198 remote()->transact(CANCEL_BUFFER, data, &reply);
199 }
200
query(int what,int * value)201 virtual int query(int what, int* value) {
202 Parcel data, reply;
203 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
204 data.writeInt32(what);
205 status_t result = remote()->transact(QUERY, data, &reply);
206 if (result != NO_ERROR) {
207 return result;
208 }
209 value[0] = reply.readInt32();
210 result = reply.readInt32();
211 return result;
212 }
213
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)214 virtual status_t connect(const sp<IProducerListener>& listener,
215 int api, bool producerControlledByApp, QueueBufferOutput* output) {
216 Parcel data, reply;
217 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
218 if (listener != NULL) {
219 data.writeInt32(1);
220 data.writeStrongBinder(IInterface::asBinder(listener));
221 } else {
222 data.writeInt32(0);
223 }
224 data.writeInt32(api);
225 data.writeInt32(producerControlledByApp);
226 status_t result = remote()->transact(CONNECT, data, &reply);
227 if (result != NO_ERROR) {
228 return result;
229 }
230 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
231 result = reply.readInt32();
232 return result;
233 }
234
disconnect(int api)235 virtual status_t disconnect(int api) {
236 Parcel data, reply;
237 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
238 data.writeInt32(api);
239 status_t result =remote()->transact(DISCONNECT, data, &reply);
240 if (result != NO_ERROR) {
241 return result;
242 }
243 result = reply.readInt32();
244 return result;
245 }
246
setSidebandStream(const sp<NativeHandle> & stream)247 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
248 Parcel data, reply;
249 status_t result;
250 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
251 if (stream.get()) {
252 data.writeInt32(true);
253 data.writeNativeHandle(stream->handle());
254 } else {
255 data.writeInt32(false);
256 }
257 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
258 result = reply.readInt32();
259 }
260 return result;
261 }
262
allocateBuffers(bool async,uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)263 virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
264 PixelFormat format, uint32_t usage) {
265 Parcel data, reply;
266 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
267 data.writeInt32(static_cast<int32_t>(async));
268 data.writeUint32(width);
269 data.writeUint32(height);
270 data.writeInt32(static_cast<int32_t>(format));
271 data.writeUint32(usage);
272 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
273 if (result != NO_ERROR) {
274 ALOGE("allocateBuffers failed to transact: %d", result);
275 }
276 }
277
allowAllocation(bool allow)278 virtual status_t allowAllocation(bool allow) {
279 Parcel data, reply;
280 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
281 data.writeInt32(static_cast<int32_t>(allow));
282 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
283 if (result != NO_ERROR) {
284 return result;
285 }
286 result = reply.readInt32();
287 return result;
288 }
289
setGenerationNumber(uint32_t generationNumber)290 virtual status_t setGenerationNumber(uint32_t generationNumber) {
291 Parcel data, reply;
292 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
293 data.writeUint32(generationNumber);
294 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
295 if (result == NO_ERROR) {
296 result = reply.readInt32();
297 }
298 return result;
299 }
300
getConsumerName() const301 virtual String8 getConsumerName() const {
302 Parcel data, reply;
303 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
304 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
305 if (result != NO_ERROR) {
306 ALOGE("getConsumerName failed to transact: %d", result);
307 return String8("TransactFailed");
308 }
309 return reply.readString8();
310 }
311 };
312
313 // Out-of-line virtual method definition to trigger vtable emission in this
314 // translation unit (see clang warning -Wweak-vtables)
~BpGraphicBufferProducer()315 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
316
317 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
318
319 // ----------------------------------------------------------------------
320
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)321 status_t BnGraphicBufferProducer::onTransact(
322 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
323 {
324 switch(code) {
325 case REQUEST_BUFFER: {
326 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
327 int bufferIdx = data.readInt32();
328 sp<GraphicBuffer> buffer;
329 int result = requestBuffer(bufferIdx, &buffer);
330 reply->writeInt32(buffer != 0);
331 if (buffer != 0) {
332 reply->write(*buffer);
333 }
334 reply->writeInt32(result);
335 return NO_ERROR;
336 }
337 case SET_BUFFER_COUNT: {
338 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
339 int bufferCount = data.readInt32();
340 int result = setBufferCount(bufferCount);
341 reply->writeInt32(result);
342 return NO_ERROR;
343 }
344 case DEQUEUE_BUFFER: {
345 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
346 bool async = static_cast<bool>(data.readInt32());
347 uint32_t width = data.readUint32();
348 uint32_t height = data.readUint32();
349 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
350 uint32_t usage = data.readUint32();
351 int buf = 0;
352 sp<Fence> fence;
353 int result = dequeueBuffer(&buf, &fence, async, width, height,
354 format, usage);
355 reply->writeInt32(buf);
356 reply->writeInt32(fence != NULL);
357 if (fence != NULL) {
358 reply->write(*fence);
359 }
360 reply->writeInt32(result);
361 return NO_ERROR;
362 }
363 case DETACH_BUFFER: {
364 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
365 int slot = data.readInt32();
366 int result = detachBuffer(slot);
367 reply->writeInt32(result);
368 return NO_ERROR;
369 }
370 case DETACH_NEXT_BUFFER: {
371 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
372 sp<GraphicBuffer> buffer;
373 sp<Fence> fence;
374 int32_t result = detachNextBuffer(&buffer, &fence);
375 reply->writeInt32(result);
376 if (result == NO_ERROR) {
377 reply->writeInt32(buffer != NULL);
378 if (buffer != NULL) {
379 reply->write(*buffer);
380 }
381 reply->writeInt32(fence != NULL);
382 if (fence != NULL) {
383 reply->write(*fence);
384 }
385 }
386 return NO_ERROR;
387 }
388 case ATTACH_BUFFER: {
389 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
390 sp<GraphicBuffer> buffer = new GraphicBuffer();
391 data.read(*buffer.get());
392 int slot = 0;
393 int result = attachBuffer(&slot, buffer);
394 reply->writeInt32(slot);
395 reply->writeInt32(result);
396 return NO_ERROR;
397 }
398 case QUEUE_BUFFER: {
399 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
400 int buf = data.readInt32();
401 QueueBufferInput input(data);
402 QueueBufferOutput* const output =
403 reinterpret_cast<QueueBufferOutput *>(
404 reply->writeInplace(sizeof(QueueBufferOutput)));
405 memset(output, 0, sizeof(QueueBufferOutput));
406 status_t result = queueBuffer(buf, input, output);
407 reply->writeInt32(result);
408 return NO_ERROR;
409 }
410 case CANCEL_BUFFER: {
411 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
412 int buf = data.readInt32();
413 sp<Fence> fence = new Fence();
414 data.read(*fence.get());
415 cancelBuffer(buf, fence);
416 return NO_ERROR;
417 }
418 case QUERY: {
419 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
420 int value = 0;
421 int what = data.readInt32();
422 int res = query(what, &value);
423 reply->writeInt32(value);
424 reply->writeInt32(res);
425 return NO_ERROR;
426 }
427 case CONNECT: {
428 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
429 sp<IProducerListener> listener;
430 if (data.readInt32() == 1) {
431 listener = IProducerListener::asInterface(data.readStrongBinder());
432 }
433 int api = data.readInt32();
434 bool producerControlledByApp = data.readInt32();
435 QueueBufferOutput* const output =
436 reinterpret_cast<QueueBufferOutput *>(
437 reply->writeInplace(sizeof(QueueBufferOutput)));
438 memset(output, 0, sizeof(QueueBufferOutput));
439 status_t res = connect(listener, api, producerControlledByApp, output);
440 reply->writeInt32(res);
441 return NO_ERROR;
442 }
443 case DISCONNECT: {
444 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
445 int api = data.readInt32();
446 status_t res = disconnect(api);
447 reply->writeInt32(res);
448 return NO_ERROR;
449 }
450 case SET_SIDEBAND_STREAM: {
451 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
452 sp<NativeHandle> stream;
453 if (data.readInt32()) {
454 stream = NativeHandle::create(data.readNativeHandle(), true);
455 }
456 status_t result = setSidebandStream(stream);
457 reply->writeInt32(result);
458 return NO_ERROR;
459 }
460 case ALLOCATE_BUFFERS: {
461 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
462 bool async = static_cast<bool>(data.readInt32());
463 uint32_t width = data.readUint32();
464 uint32_t height = data.readUint32();
465 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
466 uint32_t usage = data.readUint32();
467 allocateBuffers(async, width, height, format, usage);
468 return NO_ERROR;
469 }
470 case ALLOW_ALLOCATION: {
471 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
472 bool allow = static_cast<bool>(data.readInt32());
473 status_t result = allowAllocation(allow);
474 reply->writeInt32(result);
475 return NO_ERROR;
476 }
477 case SET_GENERATION_NUMBER: {
478 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
479 uint32_t generationNumber = data.readUint32();
480 status_t result = setGenerationNumber(generationNumber);
481 reply->writeInt32(result);
482 return NO_ERROR;
483 }
484 case GET_CONSUMER_NAME: {
485 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
486 reply->writeString8(getConsumerName());
487 return NO_ERROR;
488 }
489 }
490 return BBinder::onTransact(code, data, reply, flags);
491 }
492
493 // ----------------------------------------------------------------------------
494
QueueBufferInput(const Parcel & parcel)495 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
496 parcel.read(*this);
497 }
498
getFlattenedSize() const499 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
500 return sizeof(timestamp)
501 + sizeof(isAutoTimestamp)
502 + sizeof(dataSpace)
503 + sizeof(crop)
504 + sizeof(scalingMode)
505 + sizeof(transform)
506 + sizeof(stickyTransform)
507 + sizeof(async)
508 + fence->getFlattenedSize()
509 + surfaceDamage.getFlattenedSize();
510 }
511
getFdCount() const512 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
513 return fence->getFdCount();
514 }
515
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const516 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
517 void*& buffer, size_t& size, int*& fds, size_t& count) const
518 {
519 if (size < getFlattenedSize()) {
520 return NO_MEMORY;
521 }
522 FlattenableUtils::write(buffer, size, timestamp);
523 FlattenableUtils::write(buffer, size, isAutoTimestamp);
524 FlattenableUtils::write(buffer, size, dataSpace);
525 FlattenableUtils::write(buffer, size, crop);
526 FlattenableUtils::write(buffer, size, scalingMode);
527 FlattenableUtils::write(buffer, size, transform);
528 FlattenableUtils::write(buffer, size, stickyTransform);
529 FlattenableUtils::write(buffer, size, async);
530 status_t result = fence->flatten(buffer, size, fds, count);
531 if (result != NO_ERROR) {
532 return result;
533 }
534 return surfaceDamage.flatten(buffer, size);
535 }
536
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)537 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
538 void const*& buffer, size_t& size, int const*& fds, size_t& count)
539 {
540 size_t minNeeded =
541 sizeof(timestamp)
542 + sizeof(isAutoTimestamp)
543 + sizeof(dataSpace)
544 + sizeof(crop)
545 + sizeof(scalingMode)
546 + sizeof(transform)
547 + sizeof(stickyTransform)
548 + sizeof(async);
549
550 if (size < minNeeded) {
551 return NO_MEMORY;
552 }
553
554 FlattenableUtils::read(buffer, size, timestamp);
555 FlattenableUtils::read(buffer, size, isAutoTimestamp);
556 FlattenableUtils::read(buffer, size, dataSpace);
557 FlattenableUtils::read(buffer, size, crop);
558 FlattenableUtils::read(buffer, size, scalingMode);
559 FlattenableUtils::read(buffer, size, transform);
560 FlattenableUtils::read(buffer, size, stickyTransform);
561 FlattenableUtils::read(buffer, size, async);
562
563 fence = new Fence();
564 status_t result = fence->unflatten(buffer, size, fds, count);
565 if (result != NO_ERROR) {
566 return result;
567 }
568 return surfaceDamage.unflatten(buffer, size);
569 }
570
571 }; // namespace android
572