OSDN Git Service

am e2c4f4fb: am c1e6fbb5: Initialize local variables to avoid data leak
[android-x86/frameworks-native.git] / libs / gui / IGraphicBufferConsumer.cpp
1 /*
2  * Copyright (C) 2013 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
23 #include <binder/Parcel.h>
24 #include <binder/IInterface.h>
25
26 #include <gui/IConsumerListener.h>
27 #include <gui/IGraphicBufferConsumer.h>
28
29 #include <ui/GraphicBuffer.h>
30 #include <ui/Fence.h>
31
32 #include <system/window.h>
33
34 namespace android {
35 // ---------------------------------------------------------------------------
36
37 IGraphicBufferConsumer::BufferItem::BufferItem() :
38     mTransform(0),
39     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
40     mTimestamp(0),
41     mIsAutoTimestamp(false),
42     mFrameNumber(0),
43     mBuf(INVALID_BUFFER_SLOT),
44     mIsDroppable(false),
45     mAcquireCalled(false),
46     mTransformToDisplayInverse(false) {
47     mCrop.makeInvalid();
48 }
49
50 size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
51     size_t c =  sizeof(mCrop) +
52             sizeof(mTransform) +
53             sizeof(mScalingMode) +
54             sizeof(mTimestamp) +
55             sizeof(mIsAutoTimestamp) +
56             sizeof(mFrameNumber) +
57             sizeof(mBuf) +
58             sizeof(mIsDroppable) +
59             sizeof(mAcquireCalled) +
60             sizeof(mTransformToDisplayInverse);
61     return c;
62 }
63
64 size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
65     size_t c = 0;
66     if (mGraphicBuffer != 0) {
67         c += mGraphicBuffer->getFlattenedSize();
68         c = FlattenableUtils::align<4>(c);
69     }
70     if (mFence != 0) {
71         c += mFence->getFlattenedSize();
72         c = FlattenableUtils::align<4>(c);
73     }
74     return sizeof(int32_t) + c + getPodSize();
75 }
76
77 size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
78     size_t c = 0;
79     if (mGraphicBuffer != 0) {
80         c += mGraphicBuffer->getFdCount();
81     }
82     if (mFence != 0) {
83         c += mFence->getFdCount();
84     }
85     return c;
86 }
87
88 static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
89     FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
90 }
91
92 static bool readBoolFromInt(void const*& buffer, size_t& size) {
93     int32_t i;
94     FlattenableUtils::read(buffer, size, i);
95     return static_cast<bool>(i);
96 }
97
98 status_t IGraphicBufferConsumer::BufferItem::flatten(
99         void*& buffer, size_t& size, int*& fds, size_t& count) const {
100
101     // make sure we have enough space
102     if (size < BufferItem::getFlattenedSize()) {
103         return NO_MEMORY;
104     }
105
106     // content flags are stored first
107     uint32_t& flags = *static_cast<uint32_t*>(buffer);
108
109     // advance the pointer
110     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
111
112     flags = 0;
113     if (mGraphicBuffer != 0) {
114         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
115         if (err) return err;
116         size -= FlattenableUtils::align<4>(buffer);
117         flags |= 1;
118     }
119     if (mFence != 0) {
120         status_t err = mFence->flatten(buffer, size, fds, count);
121         if (err) return err;
122         size -= FlattenableUtils::align<4>(buffer);
123         flags |= 2;
124     }
125
126     // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
127     if (size < getPodSize()) {
128         return NO_MEMORY;
129     }
130
131     FlattenableUtils::write(buffer, size, mCrop);
132     FlattenableUtils::write(buffer, size, mTransform);
133     FlattenableUtils::write(buffer, size, mScalingMode);
134     FlattenableUtils::write(buffer, size, mTimestamp);
135     writeBoolAsInt(buffer, size, mIsAutoTimestamp);
136     FlattenableUtils::write(buffer, size, mFrameNumber);
137     FlattenableUtils::write(buffer, size, mBuf);
138     writeBoolAsInt(buffer, size, mIsDroppable);
139     writeBoolAsInt(buffer, size, mAcquireCalled);
140     writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
141
142     return NO_ERROR;
143 }
144
145 status_t IGraphicBufferConsumer::BufferItem::unflatten(
146         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
147
148     if (size < sizeof(uint32_t))
149         return NO_MEMORY;
150
151     uint32_t flags = 0;
152     FlattenableUtils::read(buffer, size, flags);
153
154     if (flags & 1) {
155         mGraphicBuffer = new GraphicBuffer();
156         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
157         if (err) return err;
158         size -= FlattenableUtils::align<4>(buffer);
159     }
160
161     if (flags & 2) {
162         mFence = new Fence();
163         status_t err = mFence->unflatten(buffer, size, fds, count);
164         if (err) return err;
165         size -= FlattenableUtils::align<4>(buffer);
166     }
167
168     // check we have enough space
169     if (size < getPodSize()) {
170         return NO_MEMORY;
171     }
172
173     FlattenableUtils::read(buffer, size, mCrop);
174     FlattenableUtils::read(buffer, size, mTransform);
175     FlattenableUtils::read(buffer, size, mScalingMode);
176     FlattenableUtils::read(buffer, size, mTimestamp);
177     mIsAutoTimestamp = readBoolFromInt(buffer, size);
178     FlattenableUtils::read(buffer, size, mFrameNumber);
179     FlattenableUtils::read(buffer, size, mBuf);
180     mIsDroppable = readBoolFromInt(buffer, size);
181     mAcquireCalled = readBoolFromInt(buffer, size);
182     mTransformToDisplayInverse = readBoolFromInt(buffer, size);
183
184     return NO_ERROR;
185 }
186
187 // ---------------------------------------------------------------------------
188
189 enum {
190     ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
191     DETACH_BUFFER,
192     ATTACH_BUFFER,
193     RELEASE_BUFFER,
194     CONSUMER_CONNECT,
195     CONSUMER_DISCONNECT,
196     GET_RELEASED_BUFFERS,
197     SET_DEFAULT_BUFFER_SIZE,
198     SET_DEFAULT_MAX_BUFFER_COUNT,
199     DISABLE_ASYNC_BUFFER,
200     SET_MAX_ACQUIRED_BUFFER_COUNT,
201     SET_CONSUMER_NAME,
202     SET_DEFAULT_BUFFER_FORMAT,
203     SET_CONSUMER_USAGE_BITS,
204     SET_TRANSFORM_HINT,
205     GET_SIDEBAND_STREAM,
206     DUMP,
207 };
208
209
210 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
211 {
212 public:
213     BpGraphicBufferConsumer(const sp<IBinder>& impl)
214         : BpInterface<IGraphicBufferConsumer>(impl)
215     {
216     }
217
218     virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
219         Parcel data, reply;
220         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
221         data.writeInt64(presentWhen);
222         status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
223         if (result != NO_ERROR) {
224             return result;
225         }
226         result = reply.read(*buffer);
227         if (result != NO_ERROR) {
228             return result;
229         }
230         return reply.readInt32();
231     }
232
233     virtual status_t detachBuffer(int slot) {
234         Parcel data, reply;
235         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
236         data.writeInt32(slot);
237         status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
238         if (result != NO_ERROR) {
239             return result;
240         }
241         result = reply.readInt32();
242         return result;
243     }
244
245     virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
246         Parcel data, reply;
247         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
248         data.write(*buffer.get());
249         status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
250         if (result != NO_ERROR) {
251             return result;
252         }
253         *slot = reply.readInt32();
254         result = reply.readInt32();
255         return result;
256     }
257
258     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
259             EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
260             const sp<Fence>& releaseFence) {
261         Parcel data, reply;
262         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
263         data.writeInt32(buf);
264         data.writeInt64(frameNumber);
265         data.write(*releaseFence);
266         status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
267         if (result != NO_ERROR) {
268             return result;
269         }
270         return reply.readInt32();
271     }
272
273     virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
274         Parcel data, reply;
275         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
276         data.writeStrongBinder(consumer->asBinder());
277         data.writeInt32(controlledByApp);
278         status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
279         if (result != NO_ERROR) {
280             return result;
281         }
282         return reply.readInt32();
283     }
284
285     virtual status_t consumerDisconnect() {
286         Parcel data, reply;
287         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
288         status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
289         if (result != NO_ERROR) {
290             return result;
291         }
292         return reply.readInt32();
293     }
294
295     virtual status_t getReleasedBuffers(uint64_t* slotMask) {
296         Parcel data, reply;
297         if (slotMask == NULL) {
298             ALOGE("getReleasedBuffers: slotMask must not be NULL");
299             return BAD_VALUE;
300         }
301         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
302         status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
303         if (result != NO_ERROR) {
304             return result;
305         }
306         *slotMask = reply.readInt64();
307         return reply.readInt32();
308     }
309
310     virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
311         Parcel data, reply;
312         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
313         data.writeInt32(w);
314         data.writeInt32(h);
315         status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
316         if (result != NO_ERROR) {
317             return result;
318         }
319         return reply.readInt32();
320     }
321
322     virtual status_t setDefaultMaxBufferCount(int bufferCount) {
323         Parcel data, reply;
324         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
325         data.writeInt32(bufferCount);
326         status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
327         if (result != NO_ERROR) {
328             return result;
329         }
330         return reply.readInt32();
331     }
332
333     virtual status_t disableAsyncBuffer() {
334         Parcel data, reply;
335         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
336         status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
337         if (result != NO_ERROR) {
338             return result;
339         }
340         return reply.readInt32();
341     }
342
343     virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
344         Parcel data, reply;
345         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
346         data.writeInt32(maxAcquiredBuffers);
347         status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
348         if (result != NO_ERROR) {
349             return result;
350         }
351         return reply.readInt32();
352     }
353
354     virtual void setConsumerName(const String8& name) {
355         Parcel data, reply;
356         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
357         data.writeString8(name);
358         remote()->transact(SET_CONSUMER_NAME, data, &reply);
359     }
360
361     virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
362         Parcel data, reply;
363         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
364         data.writeInt32(defaultFormat);
365         status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
366         if (result != NO_ERROR) {
367             return result;
368         }
369         return reply.readInt32();
370     }
371
372     virtual status_t setConsumerUsageBits(uint32_t usage) {
373         Parcel data, reply;
374         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
375         data.writeInt32(usage);
376         status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
377         if (result != NO_ERROR) {
378             return result;
379         }
380         return reply.readInt32();
381     }
382
383     virtual status_t setTransformHint(uint32_t hint) {
384         Parcel data, reply;
385         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
386         data.writeInt32(hint);
387         status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
388         if (result != NO_ERROR) {
389             return result;
390         }
391         return reply.readInt32();
392     }
393
394     virtual sp<NativeHandle> getSidebandStream() const {
395         Parcel data, reply;
396         status_t err;
397         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
398         if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
399             return NULL;
400         }
401         sp<NativeHandle> stream;
402         if (reply.readInt32()) {
403             stream = NativeHandle::create(reply.readNativeHandle(), true);
404         }
405         return stream;
406     }
407
408     virtual void dump(String8& result, const char* prefix) const {
409         Parcel data, reply;
410         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
411         data.writeString8(result);
412         data.writeString8(String8(prefix ? prefix : ""));
413         remote()->transact(DUMP, data, &reply);
414         reply.readString8();
415     }
416 };
417
418 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
419
420 // ----------------------------------------------------------------------
421
422 status_t BnGraphicBufferConsumer::onTransact(
423         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
424 {
425     switch(code) {
426         case ACQUIRE_BUFFER: {
427             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
428             BufferItem item;
429             int64_t presentWhen = data.readInt64();
430             status_t result = acquireBuffer(&item, presentWhen);
431             status_t err = reply->write(item);
432             if (err) return err;
433             reply->writeInt32(result);
434             return NO_ERROR;
435         } break;
436         case DETACH_BUFFER: {
437             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
438             int slot = data.readInt32();
439             int result = detachBuffer(slot);
440             reply->writeInt32(result);
441             return NO_ERROR;
442         } break;
443         case ATTACH_BUFFER: {
444             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
445             sp<GraphicBuffer> buffer = new GraphicBuffer();
446             data.read(*buffer.get());
447             int slot;
448             int result = attachBuffer(&slot, buffer);
449             reply->writeInt32(slot);
450             reply->writeInt32(result);
451             return NO_ERROR;
452         } break;
453         case RELEASE_BUFFER: {
454             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
455             int buf = data.readInt32();
456             uint64_t frameNumber = data.readInt64();
457             sp<Fence> releaseFence = new Fence();
458             status_t err = data.read(*releaseFence);
459             if (err) return err;
460             status_t result = releaseBuffer(buf, frameNumber,
461                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
462             reply->writeInt32(result);
463             return NO_ERROR;
464         } break;
465         case CONSUMER_CONNECT: {
466             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
467             sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
468             bool controlledByApp = data.readInt32();
469             status_t result = consumerConnect(consumer, controlledByApp);
470             reply->writeInt32(result);
471             return NO_ERROR;
472         } break;
473         case CONSUMER_DISCONNECT: {
474             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
475             status_t result = consumerDisconnect();
476             reply->writeInt32(result);
477             return NO_ERROR;
478         } break;
479         case GET_RELEASED_BUFFERS: {
480             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
481             uint64_t slotMask;
482             status_t result = getReleasedBuffers(&slotMask);
483             reply->writeInt64(slotMask);
484             reply->writeInt32(result);
485             return NO_ERROR;
486         } break;
487         case SET_DEFAULT_BUFFER_SIZE: {
488             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
489             uint32_t w = data.readInt32();
490             uint32_t h = data.readInt32();
491             status_t result = setDefaultBufferSize(w, h);
492             reply->writeInt32(result);
493             return NO_ERROR;
494         } break;
495         case SET_DEFAULT_MAX_BUFFER_COUNT: {
496             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
497             uint32_t bufferCount = data.readInt32();
498             status_t result = setDefaultMaxBufferCount(bufferCount);
499             reply->writeInt32(result);
500             return NO_ERROR;
501         } break;
502         case DISABLE_ASYNC_BUFFER: {
503             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
504             status_t result = disableAsyncBuffer();
505             reply->writeInt32(result);
506             return NO_ERROR;
507         } break;
508         case SET_MAX_ACQUIRED_BUFFER_COUNT: {
509             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
510             uint32_t maxAcquiredBuffers = data.readInt32();
511             status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
512             reply->writeInt32(result);
513             return NO_ERROR;
514         } break;
515         case SET_CONSUMER_NAME: {
516             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
517             setConsumerName( data.readString8() );
518             return NO_ERROR;
519         } break;
520         case SET_DEFAULT_BUFFER_FORMAT: {
521             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
522             uint32_t defaultFormat = data.readInt32();
523             status_t result = setDefaultBufferFormat(defaultFormat);
524             reply->writeInt32(result);
525             return NO_ERROR;
526         } break;
527         case SET_CONSUMER_USAGE_BITS: {
528             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
529             uint32_t usage = data.readInt32();
530             status_t result = setConsumerUsageBits(usage);
531             reply->writeInt32(result);
532             return NO_ERROR;
533         } break;
534         case SET_TRANSFORM_HINT: {
535             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
536             uint32_t hint = data.readInt32();
537             status_t result = setTransformHint(hint);
538             reply->writeInt32(result);
539             return NO_ERROR;
540         } break;
541         case DUMP: {
542             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
543             String8 result = data.readString8();
544             String8 prefix = data.readString8();
545             static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
546             reply->writeString8(result);
547             return NO_ERROR;
548         }
549     }
550     return BBinder::onTransact(code, data, reply, flags);
551 }
552
553 }; // namespace android