OSDN Git Service

Merge "stagefright: parseApp check data boundary conditions" into klp-dev
[android-x86/frameworks-av.git] / camera / ICameraService.cpp
1 /*
2 **
3 ** Copyright 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License"); 
6 ** you may not use this file except in compliance with the License. 
7 ** You may obtain a copy of the License at 
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0 
10 **
11 ** Unless required by applicable law or agreed to in writing, software 
12 ** distributed under the License is distributed on an "AS IS" BASIS, 
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14 ** See the License for the specific language governing permissions and 
15 ** limitations under the License.
16 */
17
18 #define LOG_TAG "BpCameraService"
19 #include <utils/Log.h>
20
21 #include <stdint.h>
22 #include <sys/types.h>
23
24 #include <binder/Parcel.h>
25 #include <binder/IPCThreadState.h>
26 #include <binder/IServiceManager.h>
27
28 #include <camera/ICameraService.h>
29 #include <camera/ICameraServiceListener.h>
30 #include <camera/IProCameraUser.h>
31 #include <camera/IProCameraCallbacks.h>
32 #include <camera/ICamera.h>
33 #include <camera/ICameraClient.h>
34 #include <camera/camera2/ICameraDeviceUser.h>
35 #include <camera/camera2/ICameraDeviceCallbacks.h>
36 #include <camera/CameraMetadata.h>
37
38 namespace android {
39
40 namespace {
41
42 enum {
43     EX_SECURITY = -1,
44     EX_BAD_PARCELABLE = -2,
45     EX_ILLEGAL_ARGUMENT = -3,
46     EX_NULL_POINTER = -4,
47     EX_ILLEGAL_STATE = -5,
48     EX_HAS_REPLY_HEADER = -128,  // special; see below
49 };
50
51 static bool readExceptionCode(Parcel& reply) {
52     int32_t exceptionCode = reply.readExceptionCode();
53
54     if (exceptionCode != 0) {
55         const char* errorMsg;
56         switch(exceptionCode) {
57             case EX_SECURITY:
58                 errorMsg = "Security";
59                 break;
60             case EX_BAD_PARCELABLE:
61                 errorMsg = "BadParcelable";
62                 break;
63             case EX_NULL_POINTER:
64                 errorMsg = "NullPointer";
65                 break;
66             case EX_ILLEGAL_STATE:
67                 errorMsg = "IllegalState";
68                 break;
69             // Binder should be handling this code inside Parcel::readException
70             // but lets have a to-string here anyway just in case.
71             case EX_HAS_REPLY_HEADER:
72                 errorMsg = "HasReplyHeader";
73                 break;
74             default:
75                 errorMsg = "Unknown";
76         }
77
78         ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
79         return true;
80     }
81
82     return false;
83 }
84
85 };
86
87 class BpCameraService: public BpInterface<ICameraService>
88 {
89 public:
90     BpCameraService(const sp<IBinder>& impl)
91         : BpInterface<ICameraService>(impl)
92     {
93     }
94
95     // get number of cameras available
96     virtual int32_t getNumberOfCameras()
97     {
98         Parcel data, reply;
99         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
100         remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
101
102         if (readExceptionCode(reply)) return 0;
103         return reply.readInt32();
104     }
105
106     // get information about a camera
107     virtual status_t getCameraInfo(int cameraId,
108                                    struct CameraInfo* cameraInfo) {
109         Parcel data, reply;
110         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
111         data.writeInt32(cameraId);
112         remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
113
114         if (readExceptionCode(reply)) return -EPROTO;
115         status_t result = reply.readInt32();
116         if (reply.readInt32() != 0) {
117             cameraInfo->facing = reply.readInt32();
118             cameraInfo->orientation = reply.readInt32();
119         }
120         return result;
121     }
122
123     // get camera characteristics (static metadata)
124     virtual status_t getCameraCharacteristics(int cameraId,
125                                               CameraMetadata* cameraInfo) {
126         Parcel data, reply;
127         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
128         data.writeInt32(cameraId);
129         remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
130
131         if (readExceptionCode(reply)) return -EPROTO;
132         status_t result = reply.readInt32();
133
134         CameraMetadata out;
135         if (reply.readInt32() != 0) {
136             out.readFromParcel(&reply);
137         }
138
139         if (cameraInfo != NULL) {
140             cameraInfo->swap(out);
141         }
142
143         return result;
144     }
145
146     // connect to camera service (android.hardware.Camera)
147     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
148                              const String16 &clientPackageName, int clientUid,
149                              /*out*/
150                              sp<ICamera>& device)
151     {
152         Parcel data, reply;
153         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
154         data.writeStrongBinder(cameraClient->asBinder());
155         data.writeInt32(cameraId);
156         data.writeString16(clientPackageName);
157         data.writeInt32(clientUid);
158         remote()->transact(BnCameraService::CONNECT, data, &reply);
159
160         if (readExceptionCode(reply)) return -EPROTO;
161         status_t status = reply.readInt32();
162         if (reply.readInt32() != 0) {
163             device = interface_cast<ICamera>(reply.readStrongBinder());
164         }
165         return status;
166     }
167
168     // connect to camera service (pro client)
169     virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
170                                 const String16 &clientPackageName, int clientUid,
171                                 /*out*/
172                                 sp<IProCameraUser>& device)
173     {
174         Parcel data, reply;
175         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
176         data.writeStrongBinder(cameraCb->asBinder());
177         data.writeInt32(cameraId);
178         data.writeString16(clientPackageName);
179         data.writeInt32(clientUid);
180         remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
181
182         if (readExceptionCode(reply)) return -EPROTO;
183         status_t status = reply.readInt32();
184         if (reply.readInt32() != 0) {
185             device = interface_cast<IProCameraUser>(reply.readStrongBinder());
186         }
187         return status;
188     }
189
190     // connect to camera service (android.hardware.camera2.CameraDevice)
191     virtual status_t connectDevice(
192             const sp<ICameraDeviceCallbacks>& cameraCb,
193             int cameraId,
194             const String16& clientPackageName,
195             int clientUid,
196             /*out*/
197             sp<ICameraDeviceUser>& device)
198     {
199         Parcel data, reply;
200         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
201         data.writeStrongBinder(cameraCb->asBinder());
202         data.writeInt32(cameraId);
203         data.writeString16(clientPackageName);
204         data.writeInt32(clientUid);
205         remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
206
207         if (readExceptionCode(reply)) return -EPROTO;
208         status_t status = reply.readInt32();
209         if (reply.readInt32() != 0) {
210             device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
211         }
212         return status;
213     }
214
215     virtual status_t addListener(const sp<ICameraServiceListener>& listener)
216     {
217         Parcel data, reply;
218         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
219         data.writeStrongBinder(listener->asBinder());
220         remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
221
222         if (readExceptionCode(reply)) return -EPROTO;
223         return reply.readInt32();
224     }
225
226     virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
227     {
228         Parcel data, reply;
229         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
230         data.writeStrongBinder(listener->asBinder());
231         remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
232
233         if (readExceptionCode(reply)) return -EPROTO;
234         return reply.readInt32();
235     }
236 };
237
238 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
239
240 // ----------------------------------------------------------------------
241
242 status_t BnCameraService::onTransact(
243     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
244 {
245     switch(code) {
246         case GET_NUMBER_OF_CAMERAS: {
247             CHECK_INTERFACE(ICameraService, data, reply);
248             reply->writeNoException();
249             reply->writeInt32(getNumberOfCameras());
250             return NO_ERROR;
251         } break;
252         case GET_CAMERA_INFO: {
253             CHECK_INTERFACE(ICameraService, data, reply);
254             CameraInfo cameraInfo = CameraInfo();
255             memset(&cameraInfo, 0, sizeof(cameraInfo));
256             status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
257             reply->writeNoException();
258             reply->writeInt32(result);
259
260             // Fake a parcelable object here
261             reply->writeInt32(1); // means the parcelable is included
262             reply->writeInt32(cameraInfo.facing);
263             reply->writeInt32(cameraInfo.orientation);
264             return NO_ERROR;
265         } break;
266         case GET_CAMERA_CHARACTERISTICS: {
267             CHECK_INTERFACE(ICameraService, data, reply);
268             CameraMetadata info;
269             status_t result = getCameraCharacteristics(data.readInt32(), &info);
270             reply->writeNoException();
271             reply->writeInt32(result);
272
273             // out-variables are after exception and return value
274             reply->writeInt32(1); // means the parcelable is included
275             info.writeToParcel(reply);
276             return NO_ERROR;
277         } break;
278         case CONNECT: {
279             CHECK_INTERFACE(ICameraService, data, reply);
280             sp<ICameraClient> cameraClient =
281                     interface_cast<ICameraClient>(data.readStrongBinder());
282             int32_t cameraId = data.readInt32();
283             const String16 clientName = data.readString16();
284             int32_t clientUid = data.readInt32();
285             sp<ICamera> camera;
286             status_t status = connect(cameraClient, cameraId,
287                     clientName, clientUid, /*out*/ camera);
288             reply->writeNoException();
289             reply->writeInt32(status);
290             if (camera != NULL) {
291                 reply->writeInt32(1);
292                 reply->writeStrongBinder(camera->asBinder());
293             } else {
294                 reply->writeInt32(0);
295             }
296             return NO_ERROR;
297         } break;
298         case CONNECT_PRO: {
299             CHECK_INTERFACE(ICameraService, data, reply);
300             sp<IProCameraCallbacks> cameraClient =
301                 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
302             int32_t cameraId = data.readInt32();
303             const String16 clientName = data.readString16();
304             int32_t clientUid = data.readInt32();
305             sp<IProCameraUser> camera;
306             status_t status = connectPro(cameraClient, cameraId,
307                     clientName, clientUid, /*out*/ camera);
308             reply->writeNoException();
309             reply->writeInt32(status);
310             if (camera != NULL) {
311                 reply->writeInt32(1);
312                 reply->writeStrongBinder(camera->asBinder());
313             } else {
314                 reply->writeInt32(0);
315             }
316             return NO_ERROR;
317         } break;
318         case CONNECT_DEVICE: {
319             CHECK_INTERFACE(ICameraService, data, reply);
320             sp<ICameraDeviceCallbacks> cameraClient =
321                 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
322             int32_t cameraId = data.readInt32();
323             const String16 clientName = data.readString16();
324             int32_t clientUid = data.readInt32();
325             sp<ICameraDeviceUser> camera;
326             status_t status = connectDevice(cameraClient, cameraId,
327                     clientName, clientUid, /*out*/ camera);
328             reply->writeNoException();
329             reply->writeInt32(status);
330             if (camera != NULL) {
331                 reply->writeInt32(1);
332                 reply->writeStrongBinder(camera->asBinder());
333             } else {
334                 reply->writeInt32(0);
335             }
336             return NO_ERROR;
337         } break;
338         case ADD_LISTENER: {
339             CHECK_INTERFACE(ICameraService, data, reply);
340             sp<ICameraServiceListener> listener =
341                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
342             reply->writeNoException();
343             reply->writeInt32(addListener(listener));
344             return NO_ERROR;
345         } break;
346         case REMOVE_LISTENER: {
347             CHECK_INTERFACE(ICameraService, data, reply);
348             sp<ICameraServiceListener> listener =
349                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
350             reply->writeNoException();
351             reply->writeInt32(removeListener(listener));
352             return NO_ERROR;
353         } break;
354         default:
355             return BBinder::onTransact(code, data, reply, flags);
356     }
357 }
358
359 // ----------------------------------------------------------------------------
360
361 }; // namespace android