blob: ca7c8f88e1aed6c9b2555573a3fbbb79e7f30c3e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Mathias Agopian07952722009-05-19 19:08:10 -070023#include <binder/Parcel.h>
24#include <binder/IMemory.h>
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
Mathias Agopian439863f2011-06-28 19:09:31 -070028#include <private/surfaceflinger/LayerState.h>
29
Jamie Gennisd2acedf2011-03-08 12:18:54 -080030#include <surfaceflinger/ISurfaceComposer.h>
31
Mathias Agopian79f39eb2011-11-17 17:49:17 -080032#include <gui/BitTube.h>
33#include <gui/IDisplayEventConnection.h>
34
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035#include <ui/DisplayInfo.h>
36
Jamie Gennis9b8fc652011-08-17 18:19:00 -070037#include <gui/ISurfaceTexture.h>
38
Jamie Gennisd2acedf2011-03-08 12:18:54 -080039#include <utils/Log.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041// ---------------------------------------------------------------------------
42
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043namespace android {
44
Mathias Agopian79f39eb2011-11-17 17:49:17 -080045class IDisplayEventConnection;
46
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
48{
49public:
50 BpSurfaceComposer(const sp<IBinder>& impl)
51 : BpInterface<ISurfaceComposer>(impl)
52 {
53 }
54
Mathias Agopian770492c2010-05-28 14:22:23 -070055 virtual sp<ISurfaceComposerClient> createConnection()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 {
57 uint32_t n;
58 Parcel data, reply;
59 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
60 remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
Mathias Agopian770492c2010-05-28 14:22:23 -070061 return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 }
63
Jamie Gennisf7acf162011-01-12 18:30:40 -080064 virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
65 {
66 uint32_t n;
67 Parcel data, reply;
68 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
69 remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);
70 return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());
71 }
72
Mathias Agopiand763b5d2009-07-02 18:11:53 -070073 virtual sp<IMemoryHeap> getCblk() const
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 {
75 Parcel data, reply;
76 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
77 remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
Mathias Agopiand763b5d2009-07-02 18:11:53 -070078 return interface_cast<IMemoryHeap>(reply.readStrongBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 }
80
Jamie Gennise2909e12011-10-10 15:48:06 -070081 virtual void setTransactionState(const Vector<ComposerState>& state,
Jamie Gennis122aa6b2011-10-12 17:39:00 -070082 int orientation, uint32_t flags)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 {
84 Parcel data, reply;
85 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
Mathias Agopian439863f2011-06-28 19:09:31 -070086 Vector<ComposerState>::const_iterator b(state.begin());
87 Vector<ComposerState>::const_iterator e(state.end());
88 data.writeInt32(state.size());
89 for ( ; b != e ; ++b ) {
90 b->write(data);
91 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 data.writeInt32(orientation);
Jamie Gennis122aa6b2011-10-12 17:39:00 -070093 data.writeInt32(flags);
Jamie Gennise2909e12011-10-10 15:48:06 -070094 remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 }
96
97 virtual void bootFinished()
98 {
99 Parcel data, reply;
100 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
101 remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
102 }
103
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700104 virtual status_t captureScreen(DisplayID dpy,
105 sp<IMemoryHeap>* heap,
Mathias Agopian597c7f62010-09-29 13:02:36 -0700106 uint32_t* width, uint32_t* height, PixelFormat* format,
Mathias Agopian3dd25a62010-12-10 16:22:31 -0800107 uint32_t reqWidth, uint32_t reqHeight,
108 uint32_t minLayerZ, uint32_t maxLayerZ)
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700109 {
110 Parcel data, reply;
111 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
112 data.writeInt32(dpy);
Mathias Agopian597c7f62010-09-29 13:02:36 -0700113 data.writeInt32(reqWidth);
114 data.writeInt32(reqHeight);
Mathias Agopian3dd25a62010-12-10 16:22:31 -0800115 data.writeInt32(minLayerZ);
116 data.writeInt32(maxLayerZ);
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700117 remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
118 *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
119 *width = reply.readInt32();
120 *height = reply.readInt32();
121 *format = reply.readInt32();
122 return reply.readInt32();
123 }
124
Mathias Agopianaab758e2010-10-11 12:37:43 -0700125 virtual status_t turnElectronBeamOff(int32_t mode)
126 {
127 Parcel data, reply;
128 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
129 data.writeInt32(mode);
130 remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
131 return reply.readInt32();
132 }
133
Mathias Agopian2d2b8032010-10-12 16:05:48 -0700134 virtual status_t turnElectronBeamOn(int32_t mode)
135 {
136 Parcel data, reply;
137 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
138 data.writeInt32(mode);
139 remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_ON, data, &reply);
140 return reply.readInt32();
141 }
142
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700143 virtual bool authenticateSurfaceTexture(
144 const sp<ISurfaceTexture>& surfaceTexture) const
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800145 {
146 Parcel data, reply;
147 int err = NO_ERROR;
148 err = data.writeInterfaceToken(
149 ISurfaceComposer::getInterfaceDescriptor());
150 if (err != NO_ERROR) {
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700151 LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800152 "interface descriptor: %s (%d)", strerror(-err), -err);
153 return false;
154 }
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700155 err = data.writeStrongBinder(surfaceTexture->asBinder());
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800156 if (err != NO_ERROR) {
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700157 LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
158 "strong binder to parcel: %s (%d)", strerror(-err), -err);
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800159 return false;
160 }
161 err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
162 &reply);
163 if (err != NO_ERROR) {
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700164 LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
165 "performing transaction: %s (%d)", strerror(-err), -err);
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800166 return false;
167 }
168 int32_t result = 0;
169 err = reply.readInt32(&result);
170 if (err != NO_ERROR) {
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700171 LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
172 "retrieving result: %s (%d)", strerror(-err), -err);
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800173 return false;
174 }
175 return result != 0;
176 }
Mathias Agopian79f39eb2011-11-17 17:49:17 -0800177
178 virtual sp<IDisplayEventConnection> createDisplayEventConnection()
179 {
180 Parcel data, reply;
181 sp<IDisplayEventConnection> result;
182 int err = data.writeInterfaceToken(
183 ISurfaceComposer::getInterfaceDescriptor());
184 if (err != NO_ERROR) {
185 return result;
186 }
187 err = remote()->transact(
188 BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
189 data, &reply);
190 if (err != NO_ERROR) {
191 LOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
192 "transaction: %s (%d)", strerror(-err), -err);
193 return result;
194 }
195 result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
196 return result;
197 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198};
199
200IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
201
202// ----------------------------------------------------------------------
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204status_t BnSurfaceComposer::onTransact(
205 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
206{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 switch(code) {
208 case CREATE_CONNECTION: {
Mathias Agopianaaf834a2009-05-22 19:00:22 -0700209 CHECK_INTERFACE(ISurfaceComposer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 sp<IBinder> b = createConnection()->asBinder();
211 reply->writeStrongBinder(b);
212 } break;
Jamie Gennisf7acf162011-01-12 18:30:40 -0800213 case CREATE_GRAPHIC_BUFFER_ALLOC: {
214 CHECK_INTERFACE(ISurfaceComposer, data, reply);
215 sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
216 reply->writeStrongBinder(b);
217 } break;
Mathias Agopian439863f2011-06-28 19:09:31 -0700218 case SET_TRANSACTION_STATE: {
Mathias Agopianaaf834a2009-05-22 19:00:22 -0700219 CHECK_INTERFACE(ISurfaceComposer, data, reply);
Mathias Agopian439863f2011-06-28 19:09:31 -0700220 size_t count = data.readInt32();
221 ComposerState s;
222 Vector<ComposerState> state;
223 state.setCapacity(count);
224 for (size_t i=0 ; i<count ; i++) {
225 s.read(data);
226 state.add(s);
227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 int orientation = data.readInt32();
Jamie Gennis122aa6b2011-10-12 17:39:00 -0700229 uint32_t flags = data.readInt32();
230 setTransactionState(state, orientation, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 } break;
232 case BOOT_FINISHED: {
Mathias Agopianaaf834a2009-05-22 19:00:22 -0700233 CHECK_INTERFACE(ISurfaceComposer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 bootFinished();
235 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 case GET_CBLK: {
Mathias Agopianaaf834a2009-05-22 19:00:22 -0700237 CHECK_INTERFACE(ISurfaceComposer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 sp<IBinder> b = getCblk()->asBinder();
239 reply->writeStrongBinder(b);
240 } break;
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700241 case CAPTURE_SCREEN: {
242 CHECK_INTERFACE(ISurfaceComposer, data, reply);
243 DisplayID dpy = data.readInt32();
Mathias Agopian597c7f62010-09-29 13:02:36 -0700244 uint32_t reqWidth = data.readInt32();
245 uint32_t reqHeight = data.readInt32();
Mathias Agopian3dd25a62010-12-10 16:22:31 -0800246 uint32_t minLayerZ = data.readInt32();
247 uint32_t maxLayerZ = data.readInt32();
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700248 sp<IMemoryHeap> heap;
249 uint32_t w, h;
250 PixelFormat f;
Mathias Agopian597c7f62010-09-29 13:02:36 -0700251 status_t res = captureScreen(dpy, &heap, &w, &h, &f,
Mathias Agopian3dd25a62010-12-10 16:22:31 -0800252 reqWidth, reqHeight, minLayerZ, maxLayerZ);
Mathias Agopianca5edbe2010-09-24 11:26:58 -0700253 reply->writeStrongBinder(heap->asBinder());
254 reply->writeInt32(w);
255 reply->writeInt32(h);
256 reply->writeInt32(f);
257 reply->writeInt32(res);
258 } break;
Mathias Agopianaab758e2010-10-11 12:37:43 -0700259 case TURN_ELECTRON_BEAM_OFF: {
260 CHECK_INTERFACE(ISurfaceComposer, data, reply);
261 int32_t mode = data.readInt32();
262 status_t res = turnElectronBeamOff(mode);
263 reply->writeInt32(res);
Jamie Gennis96fceaf2010-12-20 11:05:18 -0800264 } break;
Mathias Agopian2d2b8032010-10-12 16:05:48 -0700265 case TURN_ELECTRON_BEAM_ON: {
266 CHECK_INTERFACE(ISurfaceComposer, data, reply);
267 int32_t mode = data.readInt32();
268 status_t res = turnElectronBeamOn(mode);
269 reply->writeInt32(res);
Jamie Gennis96fceaf2010-12-20 11:05:18 -0800270 } break;
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800271 case AUTHENTICATE_SURFACE: {
272 CHECK_INTERFACE(ISurfaceComposer, data, reply);
Jamie Gennis9b8fc652011-08-17 18:19:00 -0700273 sp<ISurfaceTexture> surfaceTexture =
274 interface_cast<ISurfaceTexture>(data.readStrongBinder());
275 int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
Jamie Gennisd2acedf2011-03-08 12:18:54 -0800276 reply->writeInt32(result);
277 } break;
Mathias Agopian79f39eb2011-11-17 17:49:17 -0800278 case CREATE_DISPLAY_EVENT_CONNECTION: {
279 CHECK_INTERFACE(ISurfaceComposer, data, reply);
280 sp<IDisplayEventConnection> connection(createDisplayEventConnection());
281 reply->writeStrongBinder(connection->asBinder());
282 return NO_ERROR;
283 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 default:
Mathias Agopianaaf834a2009-05-22 19:00:22 -0700285 return BBinder::onTransact(code, data, reply, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 }
287 return NO_ERROR;
288}
289
290// ----------------------------------------------------------------------------
291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292};