• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/BufferItem.h>
27 #include <gui/IConsumerListener.h>
28 #include <gui/IGraphicBufferConsumer.h>
29 
30 #include <ui/GraphicBuffer.h>
31 #include <ui/Fence.h>
32 
33 #include <system/window.h>
34 
35 namespace android {
36 
37 enum {
38     ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
39     DETACH_BUFFER,
40     ATTACH_BUFFER,
41     RELEASE_BUFFER,
42     CONSUMER_CONNECT,
43     CONSUMER_DISCONNECT,
44     GET_RELEASED_BUFFERS,
45     SET_DEFAULT_BUFFER_SIZE,
46     SET_DEFAULT_MAX_BUFFER_COUNT,
47     DISABLE_ASYNC_BUFFER,
48     SET_MAX_ACQUIRED_BUFFER_COUNT,
49     SET_CONSUMER_NAME,
50     SET_DEFAULT_BUFFER_FORMAT,
51     SET_DEFAULT_BUFFER_DATA_SPACE,
52     SET_CONSUMER_USAGE_BITS,
53     SET_TRANSFORM_HINT,
54     GET_SIDEBAND_STREAM,
55     DUMP,
56 };
57 
58 
59 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
60 {
61 public:
BpGraphicBufferConsumer(const sp<IBinder> & impl)62     BpGraphicBufferConsumer(const sp<IBinder>& impl)
63         : BpInterface<IGraphicBufferConsumer>(impl)
64     {
65     }
66 
67     virtual ~BpGraphicBufferConsumer();
68 
acquireBuffer(BufferItem * buffer,nsecs_t presentWhen,uint64_t maxFrameNumber)69     virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen,
70             uint64_t maxFrameNumber) {
71         Parcel data, reply;
72         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
73         data.writeInt64(presentWhen);
74         data.writeUint64(maxFrameNumber);
75         status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
76         if (result != NO_ERROR) {
77             return result;
78         }
79         result = reply.read(*buffer);
80         if (result != NO_ERROR) {
81             return result;
82         }
83         return reply.readInt32();
84     }
85 
detachBuffer(int slot)86     virtual status_t detachBuffer(int slot) {
87         Parcel data, reply;
88         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
89         data.writeInt32(slot);
90         status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
91         if (result != NO_ERROR) {
92             return result;
93         }
94         result = reply.readInt32();
95         return result;
96     }
97 
attachBuffer(int * slot,const sp<GraphicBuffer> & buffer)98     virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
99         Parcel data, reply;
100         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
101         data.write(*buffer.get());
102         status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
103         if (result != NO_ERROR) {
104             return result;
105         }
106         *slot = reply.readInt32();
107         result = reply.readInt32();
108         return result;
109     }
110 
releaseBuffer(int buf,uint64_t frameNumber,EGLDisplay display,EGLSyncKHR fence,const sp<Fence> & releaseFence)111     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
112             EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
113             const sp<Fence>& releaseFence) {
114         Parcel data, reply;
115         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
116         data.writeInt32(buf);
117         data.writeInt64(static_cast<int64_t>(frameNumber));
118         data.write(*releaseFence);
119         status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
120         if (result != NO_ERROR) {
121             return result;
122         }
123         return reply.readInt32();
124     }
125 
consumerConnect(const sp<IConsumerListener> & consumer,bool controlledByApp)126     virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
127         Parcel data, reply;
128         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
129         data.writeStrongBinder(IInterface::asBinder(consumer));
130         data.writeInt32(controlledByApp);
131         status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
132         if (result != NO_ERROR) {
133             return result;
134         }
135         return reply.readInt32();
136     }
137 
consumerDisconnect()138     virtual status_t consumerDisconnect() {
139         Parcel data, reply;
140         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
141         status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
142         if (result != NO_ERROR) {
143             return result;
144         }
145         return reply.readInt32();
146     }
147 
getReleasedBuffers(uint64_t * slotMask)148     virtual status_t getReleasedBuffers(uint64_t* slotMask) {
149         Parcel data, reply;
150         if (slotMask == NULL) {
151             ALOGE("getReleasedBuffers: slotMask must not be NULL");
152             return BAD_VALUE;
153         }
154         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
155         status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
156         if (result != NO_ERROR) {
157             return result;
158         }
159         *slotMask = static_cast<uint64_t>(reply.readInt64());
160         return reply.readInt32();
161     }
162 
setDefaultBufferSize(uint32_t width,uint32_t height)163     virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) {
164         Parcel data, reply;
165         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
166         data.writeUint32(width);
167         data.writeUint32(height);
168         status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
169         if (result != NO_ERROR) {
170             return result;
171         }
172         return reply.readInt32();
173     }
174 
setDefaultMaxBufferCount(int bufferCount)175     virtual status_t setDefaultMaxBufferCount(int bufferCount) {
176         Parcel data, reply;
177         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
178         data.writeInt32(bufferCount);
179         status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
180         if (result != NO_ERROR) {
181             return result;
182         }
183         return reply.readInt32();
184     }
185 
disableAsyncBuffer()186     virtual status_t disableAsyncBuffer() {
187         Parcel data, reply;
188         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
189         status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
190         if (result != NO_ERROR) {
191             return result;
192         }
193         return reply.readInt32();
194     }
195 
setMaxAcquiredBufferCount(int maxAcquiredBuffers)196     virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
197         Parcel data, reply;
198         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
199         data.writeInt32(maxAcquiredBuffers);
200         status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
201         if (result != NO_ERROR) {
202             return result;
203         }
204         return reply.readInt32();
205     }
206 
setConsumerName(const String8 & name)207     virtual void setConsumerName(const String8& name) {
208         Parcel data, reply;
209         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
210         data.writeString8(name);
211         remote()->transact(SET_CONSUMER_NAME, data, &reply);
212     }
213 
setDefaultBufferFormat(PixelFormat defaultFormat)214     virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) {
215         Parcel data, reply;
216         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
217         data.writeInt32(static_cast<int32_t>(defaultFormat));
218         status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
219         if (result != NO_ERROR) {
220             return result;
221         }
222         return reply.readInt32();
223     }
224 
setDefaultBufferDataSpace(android_dataspace defaultDataSpace)225     virtual status_t setDefaultBufferDataSpace(
226             android_dataspace defaultDataSpace) {
227         Parcel data, reply;
228         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
229         data.writeInt32(static_cast<int32_t>(defaultDataSpace));
230         status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
231                 data, &reply);
232         if (result != NO_ERROR) {
233             return result;
234         }
235         return reply.readInt32();
236     }
237 
setConsumerUsageBits(uint32_t usage)238     virtual status_t setConsumerUsageBits(uint32_t usage) {
239         Parcel data, reply;
240         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
241         data.writeUint32(usage);
242         status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
243         if (result != NO_ERROR) {
244             return result;
245         }
246         return reply.readInt32();
247     }
248 
setTransformHint(uint32_t hint)249     virtual status_t setTransformHint(uint32_t hint) {
250         Parcel data, reply;
251         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
252         data.writeUint32(hint);
253         status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
254         if (result != NO_ERROR) {
255             return result;
256         }
257         return reply.readInt32();
258     }
259 
getSidebandStream() const260     virtual sp<NativeHandle> getSidebandStream() const {
261         Parcel data, reply;
262         status_t err;
263         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
264         if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
265             return NULL;
266         }
267         sp<NativeHandle> stream;
268         if (reply.readInt32()) {
269             stream = NativeHandle::create(reply.readNativeHandle(), true);
270         }
271         return stream;
272     }
273 
dump(String8 & result,const char * prefix) const274     virtual void dump(String8& result, const char* prefix) const {
275         Parcel data, reply;
276         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
277         data.writeString8(result);
278         data.writeString8(String8(prefix ? prefix : ""));
279         remote()->transact(DUMP, data, &reply);
280         reply.readString8();
281     }
282 };
283 
284 // Out-of-line virtual method definition to trigger vtable emission in this
285 // translation unit (see clang warning -Wweak-vtables)
~BpGraphicBufferConsumer()286 BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {}
287 
288 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
289 
290 // ----------------------------------------------------------------------
291 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)292 status_t BnGraphicBufferConsumer::onTransact(
293         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
294 {
295     switch(code) {
296         case ACQUIRE_BUFFER: {
297             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
298             BufferItem item;
299             int64_t presentWhen = data.readInt64();
300             uint64_t maxFrameNumber = data.readUint64();
301             status_t result = acquireBuffer(&item, presentWhen, maxFrameNumber);
302             status_t err = reply->write(item);
303             if (err) return err;
304             reply->writeInt32(result);
305             return NO_ERROR;
306         }
307         case DETACH_BUFFER: {
308             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
309             int slot = data.readInt32();
310             int result = detachBuffer(slot);
311             reply->writeInt32(result);
312             return NO_ERROR;
313         }
314         case ATTACH_BUFFER: {
315             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
316             sp<GraphicBuffer> buffer = new GraphicBuffer();
317             data.read(*buffer.get());
318             int slot = -1;
319             int result = attachBuffer(&slot, buffer);
320             reply->writeInt32(slot);
321             reply->writeInt32(result);
322             return NO_ERROR;
323         }
324         case RELEASE_BUFFER: {
325             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
326             int buf = data.readInt32();
327             uint64_t frameNumber = static_cast<uint64_t>(data.readInt64());
328             sp<Fence> releaseFence = new Fence();
329             status_t err = data.read(*releaseFence);
330             if (err) return err;
331             status_t result = releaseBuffer(buf, frameNumber,
332                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
333             reply->writeInt32(result);
334             return NO_ERROR;
335         }
336         case CONSUMER_CONNECT: {
337             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
338             sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
339             bool controlledByApp = data.readInt32();
340             status_t result = consumerConnect(consumer, controlledByApp);
341             reply->writeInt32(result);
342             return NO_ERROR;
343         }
344         case CONSUMER_DISCONNECT: {
345             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
346             status_t result = consumerDisconnect();
347             reply->writeInt32(result);
348             return NO_ERROR;
349         }
350         case GET_RELEASED_BUFFERS: {
351             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
352             uint64_t slotMask = 0;
353             status_t result = getReleasedBuffers(&slotMask);
354             reply->writeInt64(static_cast<int64_t>(slotMask));
355             reply->writeInt32(result);
356             return NO_ERROR;
357         }
358         case SET_DEFAULT_BUFFER_SIZE: {
359             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
360             uint32_t width = data.readUint32();
361             uint32_t height = data.readUint32();
362             status_t result = setDefaultBufferSize(width, height);
363             reply->writeInt32(result);
364             return NO_ERROR;
365         }
366         case SET_DEFAULT_MAX_BUFFER_COUNT: {
367             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
368             int bufferCount = data.readInt32();
369             status_t result = setDefaultMaxBufferCount(bufferCount);
370             reply->writeInt32(result);
371             return NO_ERROR;
372         }
373         case DISABLE_ASYNC_BUFFER: {
374             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
375             status_t result = disableAsyncBuffer();
376             reply->writeInt32(result);
377             return NO_ERROR;
378         }
379         case SET_MAX_ACQUIRED_BUFFER_COUNT: {
380             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
381             int maxAcquiredBuffers = data.readInt32();
382             status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
383             reply->writeInt32(result);
384             return NO_ERROR;
385         }
386         case SET_CONSUMER_NAME: {
387             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
388             setConsumerName( data.readString8() );
389             return NO_ERROR;
390         }
391         case SET_DEFAULT_BUFFER_FORMAT: {
392             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
393             PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32());
394             status_t result = setDefaultBufferFormat(defaultFormat);
395             reply->writeInt32(result);
396             return NO_ERROR;
397         }
398         case SET_DEFAULT_BUFFER_DATA_SPACE: {
399             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
400             android_dataspace defaultDataSpace =
401                     static_cast<android_dataspace>(data.readInt32());
402             status_t result = setDefaultBufferDataSpace(defaultDataSpace);
403             reply->writeInt32(result);
404             return NO_ERROR;
405         }
406         case SET_CONSUMER_USAGE_BITS: {
407             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
408             uint32_t usage = data.readUint32();
409             status_t result = setConsumerUsageBits(usage);
410             reply->writeInt32(result);
411             return NO_ERROR;
412         }
413         case SET_TRANSFORM_HINT: {
414             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
415             uint32_t hint = data.readUint32();
416             status_t result = setTransformHint(hint);
417             reply->writeInt32(result);
418             return NO_ERROR;
419         }
420         case GET_SIDEBAND_STREAM: {
421             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
422             sp<NativeHandle> stream = getSidebandStream();
423             reply->writeInt32(static_cast<int32_t>(stream != NULL));
424             if (stream != NULL) {
425                 reply->writeNativeHandle(stream->handle());
426             }
427             return NO_ERROR;
428         }
429         case DUMP: {
430             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
431             String8 result = data.readString8();
432             String8 prefix = data.readString8();
433             static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
434             reply->writeString8(result);
435             return NO_ERROR;
436         }
437     }
438     return BBinder::onTransact(code, data, reply, flags);
439 }
440 
441 }; // namespace android
442