OSDN Git Service

Correctly handle dup() failure in Parcel::readNativeHandle am: 1de7966c72 am: 275c9f6...
[android-x86/frameworks-native.git] / libs / gui / IGraphicBufferProducer.cpp
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:
57     BpGraphicBufferProducer(const sp<IBinder>& impl)
58         : BpInterface<IGraphicBufferProducer>(impl)
59     {
60     }
61
62     virtual ~BpGraphicBufferProducer();
63
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
301     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)
315 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
316
317 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
318
319 // ----------------------------------------------------------------------
320
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
495 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
496     parcel.read(*this);
497 }
498
499 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
512 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
513     return fence->getFdCount();
514 }
515
516 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
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