ISurfaceComposer.cpp revision 698c0873cf2e07bdc7fd1e72169aee2a19fa40d7
1/*
2 * Copyright (C) 2007 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#include <binder/IMemory.h>
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27
28#include <private/surfaceflinger/LayerState.h>
29
30#include <surfaceflinger/ISurfaceComposer.h>
31
32#include <ui/DisplayInfo.h>
33
34#include <utils/Log.h>
35
36// ---------------------------------------------------------------------------
37
38#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
39#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
40
41// ---------------------------------------------------------------------------
42
43namespace android {
44
45class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
46{
47public:
48    BpSurfaceComposer(const sp<IBinder>& impl)
49        : BpInterface<ISurfaceComposer>(impl)
50    {
51    }
52
53    virtual sp<ISurfaceComposerClient> createConnection()
54    {
55        uint32_t n;
56        Parcel data, reply;
57        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
58        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
59        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
60    }
61
62    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
63    {
64        uint32_t n;
65        Parcel data, reply;
66        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
67        remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);
68        return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());
69    }
70
71    virtual sp<IMemoryHeap> getCblk() const
72    {
73        Parcel data, reply;
74        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
75        remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
76        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
77    }
78
79    virtual void setTransactionState(const Vector<ComposerState>& state)
80    {
81        Parcel data, reply;
82        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
83        Vector<ComposerState>::const_iterator b(state.begin());
84        Vector<ComposerState>::const_iterator e(state.end());
85        data.writeInt32(state.size());
86        for ( ; b != e ; ++b ) {
87            b->write(data);
88        }
89        remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
90    }
91
92    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
93    {
94        Parcel data, reply;
95        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
96        data.writeInt32(dpy);
97        data.writeInt32(flags);
98        remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
99        return reply.readInt32();
100    }
101
102    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
103    {
104        Parcel data, reply;
105        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
106        data.writeInt32(dpy);
107        data.writeInt32(flags);
108        remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
109        return reply.readInt32();
110    }
111
112    virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags)
113    {
114        Parcel data, reply;
115        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
116        data.writeInt32(dpy);
117        data.writeInt32(orientation);
118        data.writeInt32(flags);
119        remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
120        return reply.readInt32();
121    }
122
123    virtual void bootFinished()
124    {
125        Parcel data, reply;
126        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
127        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
128    }
129
130    virtual status_t captureScreen(DisplayID dpy,
131            sp<IMemoryHeap>* heap,
132            uint32_t* width, uint32_t* height, PixelFormat* format,
133            uint32_t reqWidth, uint32_t reqHeight,
134            uint32_t minLayerZ, uint32_t maxLayerZ)
135    {
136        Parcel data, reply;
137        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
138        data.writeInt32(dpy);
139        data.writeInt32(reqWidth);
140        data.writeInt32(reqHeight);
141        data.writeInt32(minLayerZ);
142        data.writeInt32(maxLayerZ);
143        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
144        *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
145        *width = reply.readInt32();
146        *height = reply.readInt32();
147        *format = reply.readInt32();
148        return reply.readInt32();
149    }
150
151    virtual status_t turnElectronBeamOff(int32_t mode)
152    {
153        Parcel data, reply;
154        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
155        data.writeInt32(mode);
156        remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
157        return reply.readInt32();
158    }
159
160    virtual status_t turnElectronBeamOn(int32_t mode)
161    {
162        Parcel data, reply;
163        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
164        data.writeInt32(mode);
165        remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_ON, data, &reply);
166        return reply.readInt32();
167    }
168
169    virtual bool authenticateSurface(const sp<ISurface>& surface) const
170    {
171        Parcel data, reply;
172        int err = NO_ERROR;
173        err = data.writeInterfaceToken(
174                ISurfaceComposer::getInterfaceDescriptor());
175        if (err != NO_ERROR) {
176            LOGE("ISurfaceComposer::authenticateSurface: error writing "
177                    "interface descriptor: %s (%d)", strerror(-err), -err);
178            return false;
179        }
180        err = data.writeStrongBinder(surface->asBinder());
181        if (err != NO_ERROR) {
182            LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
183                    "binder to parcel: %s (%d)", strerror(-err), -err);
184            return false;
185        }
186        err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
187                &reply);
188        if (err != NO_ERROR) {
189            LOGE("ISurfaceComposer::authenticateSurface: error performing "
190                    "transaction: %s (%d)", strerror(-err), -err);
191            return false;
192        }
193        int32_t result = 0;
194        err = reply.readInt32(&result);
195        if (err != NO_ERROR) {
196            LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
197                    "result: %s (%d)", strerror(-err), -err);
198            return false;
199        }
200        return result != 0;
201    }
202};
203
204IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
205
206// ----------------------------------------------------------------------
207
208status_t BnSurfaceComposer::onTransact(
209    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
210{
211    switch(code) {
212        case CREATE_CONNECTION: {
213            CHECK_INTERFACE(ISurfaceComposer, data, reply);
214            sp<IBinder> b = createConnection()->asBinder();
215            reply->writeStrongBinder(b);
216        } break;
217        case CREATE_GRAPHIC_BUFFER_ALLOC: {
218            CHECK_INTERFACE(ISurfaceComposer, data, reply);
219            sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
220            reply->writeStrongBinder(b);
221        } break;
222        case SET_TRANSACTION_STATE: {
223            CHECK_INTERFACE(ISurfaceComposer, data, reply);
224            size_t count = data.readInt32();
225            ComposerState s;
226            Vector<ComposerState> state;
227            state.setCapacity(count);
228            for (size_t i=0 ; i<count ; i++) {
229                s.read(data);
230                state.add(s);
231            }
232            setTransactionState(state);
233        } break;
234        case SET_ORIENTATION: {
235            CHECK_INTERFACE(ISurfaceComposer, data, reply);
236            DisplayID dpy = data.readInt32();
237            int orientation = data.readInt32();
238            uint32_t flags = data.readInt32();
239            reply->writeInt32( setOrientation(dpy, orientation, flags) );
240        } break;
241        case FREEZE_DISPLAY: {
242            CHECK_INTERFACE(ISurfaceComposer, data, reply);
243            DisplayID dpy = data.readInt32();
244            uint32_t flags = data.readInt32();
245            reply->writeInt32( freezeDisplay(dpy, flags) );
246        } break;
247        case UNFREEZE_DISPLAY: {
248            CHECK_INTERFACE(ISurfaceComposer, data, reply);
249            DisplayID dpy = data.readInt32();
250            uint32_t flags = data.readInt32();
251            reply->writeInt32( unfreezeDisplay(dpy, flags) );
252        } break;
253        case BOOT_FINISHED: {
254            CHECK_INTERFACE(ISurfaceComposer, data, reply);
255            bootFinished();
256        } break;
257        case GET_CBLK: {
258            CHECK_INTERFACE(ISurfaceComposer, data, reply);
259            sp<IBinder> b = getCblk()->asBinder();
260            reply->writeStrongBinder(b);
261        } break;
262        case CAPTURE_SCREEN: {
263            CHECK_INTERFACE(ISurfaceComposer, data, reply);
264            DisplayID dpy = data.readInt32();
265            uint32_t reqWidth = data.readInt32();
266            uint32_t reqHeight = data.readInt32();
267            uint32_t minLayerZ = data.readInt32();
268            uint32_t maxLayerZ = data.readInt32();
269            sp<IMemoryHeap> heap;
270            uint32_t w, h;
271            PixelFormat f;
272            status_t res = captureScreen(dpy, &heap, &w, &h, &f,
273                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
274            reply->writeStrongBinder(heap->asBinder());
275            reply->writeInt32(w);
276            reply->writeInt32(h);
277            reply->writeInt32(f);
278            reply->writeInt32(res);
279        } break;
280        case TURN_ELECTRON_BEAM_OFF: {
281            CHECK_INTERFACE(ISurfaceComposer, data, reply);
282            int32_t mode = data.readInt32();
283            status_t res = turnElectronBeamOff(mode);
284            reply->writeInt32(res);
285        } break;
286        case TURN_ELECTRON_BEAM_ON: {
287            CHECK_INTERFACE(ISurfaceComposer, data, reply);
288            int32_t mode = data.readInt32();
289            status_t res = turnElectronBeamOn(mode);
290            reply->writeInt32(res);
291        } break;
292        case AUTHENTICATE_SURFACE: {
293            CHECK_INTERFACE(ISurfaceComposer, data, reply);
294            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
295            int32_t result = authenticateSurface(surface) ? 1 : 0;
296            reply->writeInt32(result);
297        } break;
298        default:
299            return BBinder::onTransact(code, data, reply, flags);
300    }
301    return NO_ERROR;
302}
303
304// ----------------------------------------------------------------------------
305
306};
307