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