1 /*
2  * Copyright (C) 2011 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 // tag as surfaceflinger
18 #define LOG_TAG "SurfaceFlinger"
19 
20 #include <stdint.h>
21 #include <sys/types.h>
22 
23 #include <binder/Parcel.h>
24 
25 #include <ui/GraphicBuffer.h>
26 
27 #include <gui/IGraphicBufferAlloc.h>
28 
29 // ---------------------------------------------------------------------------
30 
31 namespace android {
32 
33 enum {
34     CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
35 };
36 
37 class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
38 {
39 public:
BpGraphicBufferAlloc(const sp<IBinder> & impl)40     BpGraphicBufferAlloc(const sp<IBinder>& impl)
41         : BpInterface<IGraphicBufferAlloc>(impl)
42     {
43     }
44 
createGraphicBuffer(uint32_t w,uint32_t h,PixelFormat format,uint32_t usage,status_t * error)45     virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
46             PixelFormat format, uint32_t usage, status_t* error) {
47         Parcel data, reply;
48         data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
49         data.writeInt32(w);
50         data.writeInt32(h);
51         data.writeInt32(format);
52         data.writeInt32(usage);
53         remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
54         sp<GraphicBuffer> graphicBuffer;
55         status_t result = reply.readInt32();
56         if (result == NO_ERROR) {
57             graphicBuffer = new GraphicBuffer();
58             result = reply.read(*graphicBuffer);
59             // reply.readStrongBinder();
60             // here we don't even have to read the BufferReference from
61             // the parcel, it'll die with the parcel.
62         }
63         *error = result;
64         return graphicBuffer;
65     }
66 };
67 
68 IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
69 
70 // ----------------------------------------------------------------------
71 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)72 status_t BnGraphicBufferAlloc::onTransact(
73     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
74 {
75     // codes that don't require permission check
76 
77     /* BufferReference just keeps a strong reference to a
78      * GraphicBuffer until it is destroyed (that is, until
79      * no local or remote process have a reference to it).
80      */
81     class BufferReference : public BBinder {
82         sp<GraphicBuffer> buffer;
83     public:
84         BufferReference(const sp<GraphicBuffer>& buffer) : buffer(buffer) { }
85     };
86 
87 
88     switch(code) {
89         case CREATE_GRAPHIC_BUFFER: {
90             CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
91             uint32_t w = data.readInt32();
92             uint32_t h = data.readInt32();
93             PixelFormat format = data.readInt32();
94             uint32_t usage = data.readInt32();
95             status_t error;
96             sp<GraphicBuffer> result =
97                     createGraphicBuffer(w, h, format, usage, &error);
98             reply->writeInt32(error);
99             if (result != 0) {
100                 reply->write(*result);
101                 // We add a BufferReference to this parcel to make sure the
102                 // buffer stays alive until the GraphicBuffer object on
103                 // the other side has been created.
104                 // This is needed so that the buffer handle can be
105                 // registered before the buffer is destroyed on implementations
106                 // that do not use file-descriptors to track their buffers.
107                 reply->writeStrongBinder( new BufferReference(result) );
108             }
109             return NO_ERROR;
110         } break;
111         default:
112             return BBinder::onTransact(code, data, reply, flags);
113     }
114 }
115 
116 }; // namespace android
117