• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <utils/Errors.h>
21 #include <utils/String16.h>
22 
23 #include <inttypes.h>
24 #include <stdint.h>
25 #include <sys/types.h>
26 
27 #include <binder/Parcel.h>
28 #include <binder/IPCThreadState.h>
29 #include <binder/IServiceManager.h>
30 
31 #include <camera/ICameraService.h>
32 #include <camera/ICameraServiceListener.h>
33 #include <camera/ICamera.h>
34 #include <camera/ICameraClient.h>
35 #include <camera/camera2/ICameraDeviceUser.h>
36 #include <camera/camera2/ICameraDeviceCallbacks.h>
37 #include <camera/CameraMetadata.h>
38 #include <camera/VendorTagDescriptor.h>
39 
40 namespace android {
41 
42 namespace {
43 
44 enum {
45     EX_SECURITY = -1,
46     EX_BAD_PARCELABLE = -2,
47     EX_ILLEGAL_ARGUMENT = -3,
48     EX_NULL_POINTER = -4,
49     EX_ILLEGAL_STATE = -5,
50     EX_HAS_REPLY_HEADER = -128,  // special; see below
51 };
52 
readExceptionCode(Parcel & reply)53 static bool readExceptionCode(Parcel& reply) {
54     int32_t exceptionCode = reply.readExceptionCode();
55 
56     if (exceptionCode != 0) {
57         const char* errorMsg;
58         switch(exceptionCode) {
59             case EX_SECURITY:
60                 errorMsg = "Security";
61                 break;
62             case EX_BAD_PARCELABLE:
63                 errorMsg = "BadParcelable";
64                 break;
65             case EX_NULL_POINTER:
66                 errorMsg = "NullPointer";
67                 break;
68             case EX_ILLEGAL_STATE:
69                 errorMsg = "IllegalState";
70                 break;
71             // Binder should be handling this code inside Parcel::readException
72             // but lets have a to-string here anyway just in case.
73             case EX_HAS_REPLY_HEADER:
74                 errorMsg = "HasReplyHeader";
75                 break;
76             default:
77                 errorMsg = "Unknown";
78         }
79 
80         ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
81         return true;
82     }
83 
84     return false;
85 }
86 
87 };
88 
89 class BpCameraService: public BpInterface<ICameraService>
90 {
91 public:
BpCameraService(const sp<IBinder> & impl)92     BpCameraService(const sp<IBinder>& impl)
93         : BpInterface<ICameraService>(impl)
94     {
95     }
96 
97     // get number of cameras available that support standard camera operations
getNumberOfCameras()98     virtual int32_t getNumberOfCameras()
99     {
100         return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE);
101     }
102 
103     // get number of cameras available of a given type
getNumberOfCameras(int type)104     virtual int32_t getNumberOfCameras(int type)
105     {
106         Parcel data, reply;
107         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
108         data.writeInt32(type);
109         remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
110 
111         if (readExceptionCode(reply)) return 0;
112         return reply.readInt32();
113     }
114 
115     // get information about a camera
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)116     virtual status_t getCameraInfo(int cameraId,
117                                    struct CameraInfo* cameraInfo) {
118         Parcel data, reply;
119         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
120         data.writeInt32(cameraId);
121         remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
122 
123         if (readExceptionCode(reply)) return -EPROTO;
124         status_t result = reply.readInt32();
125         if (reply.readInt32() != 0) {
126             cameraInfo->facing = reply.readInt32();
127             cameraInfo->orientation = reply.readInt32();
128         }
129         return result;
130     }
131 
132     // get camera characteristics (static metadata)
getCameraCharacteristics(int cameraId,CameraMetadata * cameraInfo)133     virtual status_t getCameraCharacteristics(int cameraId,
134                                               CameraMetadata* cameraInfo) {
135         Parcel data, reply;
136         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
137         data.writeInt32(cameraId);
138         remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
139 
140         if (readExceptionCode(reply)) return -EPROTO;
141         status_t result = reply.readInt32();
142 
143         CameraMetadata out;
144         if (reply.readInt32() != 0) {
145             out.readFromParcel(&reply);
146         }
147 
148         if (cameraInfo != NULL) {
149             cameraInfo->swap(out);
150         }
151 
152         return result;
153     }
154 
155     // Get enumeration and description of vendor tags for camera
getCameraVendorTagDescriptor(sp<VendorTagDescriptor> & desc)156     virtual status_t getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
157         Parcel data, reply;
158         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
159         remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply);
160 
161         if (readExceptionCode(reply)) return -EPROTO;
162         status_t result = reply.readInt32();
163 
164         if (reply.readInt32() != 0) {
165             sp<VendorTagDescriptor> d;
166             if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) {
167                 desc = d;
168             }
169         }
170         return result;
171     }
172 
173     // connect to camera service (android.hardware.Camera)
connect(const sp<ICameraClient> & cameraClient,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)174     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
175                              const String16 &clientPackageName, int clientUid,
176                              /*out*/
177                              sp<ICamera>& device)
178     {
179         Parcel data, reply;
180         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
181         data.writeStrongBinder(IInterface::asBinder(cameraClient));
182         data.writeInt32(cameraId);
183         data.writeString16(clientPackageName);
184         data.writeInt32(clientUid);
185 
186         status_t status;
187         status = remote()->transact(BnCameraService::CONNECT, data, &reply);
188         if (status != OK) return status;
189 
190         if (readExceptionCode(reply)) return -EPROTO;
191         status = reply.readInt32();
192         if (reply.readInt32() != 0) {
193             device = interface_cast<ICamera>(reply.readStrongBinder());
194         }
195         return status;
196     }
197 
198     // connect to camera service (android.hardware.Camera)
connectLegacy(const sp<ICameraClient> & cameraClient,int cameraId,int halVersion,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)199     virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
200                              int halVersion,
201                              const String16 &clientPackageName, int clientUid,
202                              /*out*/sp<ICamera>& device)
203     {
204         Parcel data, reply;
205         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
206         data.writeStrongBinder(IInterface::asBinder(cameraClient));
207         data.writeInt32(cameraId);
208         data.writeInt32(halVersion);
209         data.writeString16(clientPackageName);
210         data.writeInt32(clientUid);
211 
212         status_t status;
213         status = remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
214         if (status != OK) return status;
215 
216         if (readExceptionCode(reply)) return -EPROTO;
217         status = reply.readInt32();
218         if (reply.readInt32() != 0) {
219             device = interface_cast<ICamera>(reply.readStrongBinder());
220         }
221         return status;
222     }
223 
setTorchMode(const String16 & cameraId,bool enabled,const sp<IBinder> & clientBinder)224     virtual status_t setTorchMode(const String16& cameraId, bool enabled,
225             const sp<IBinder>& clientBinder)
226     {
227         Parcel data, reply;
228         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
229         data.writeString16(cameraId);
230         data.writeInt32(enabled ? 1 : 0);
231         data.writeStrongBinder(clientBinder);
232         remote()->transact(BnCameraService::SET_TORCH_MODE, data, &reply);
233 
234         if (readExceptionCode(reply)) return -EPROTO;
235         return reply.readInt32();
236     }
237 
238     // connect to camera service (android.hardware.camera2.CameraDevice)
connectDevice(const sp<ICameraDeviceCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICameraDeviceUser> & device)239     virtual status_t connectDevice(
240             const sp<ICameraDeviceCallbacks>& cameraCb,
241             int cameraId,
242             const String16& clientPackageName,
243             int clientUid,
244             /*out*/
245             sp<ICameraDeviceUser>& device)
246     {
247         Parcel data, reply;
248         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
249         data.writeStrongBinder(IInterface::asBinder(cameraCb));
250         data.writeInt32(cameraId);
251         data.writeString16(clientPackageName);
252         data.writeInt32(clientUid);
253 
254         status_t status;
255         status = remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
256         if (status != OK) return status;
257 
258         if (readExceptionCode(reply)) return -EPROTO;
259         status = reply.readInt32();
260         if (reply.readInt32() != 0) {
261             device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
262         }
263         return status;
264     }
265 
addListener(const sp<ICameraServiceListener> & listener)266     virtual status_t addListener(const sp<ICameraServiceListener>& listener)
267     {
268         Parcel data, reply;
269         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
270         data.writeStrongBinder(IInterface::asBinder(listener));
271         remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
272 
273         if (readExceptionCode(reply)) return -EPROTO;
274         return reply.readInt32();
275     }
276 
removeListener(const sp<ICameraServiceListener> & listener)277     virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
278     {
279         Parcel data, reply;
280         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
281         data.writeStrongBinder(IInterface::asBinder(listener));
282         remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
283 
284         if (readExceptionCode(reply)) return -EPROTO;
285         return reply.readInt32();
286     }
287 
getLegacyParameters(int cameraId,String16 * parameters)288     virtual status_t getLegacyParameters(int cameraId, String16* parameters) {
289         if (parameters == NULL) {
290             ALOGE("%s: parameters must not be null", __FUNCTION__);
291             return BAD_VALUE;
292         }
293 
294         Parcel data, reply;
295         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
296 
297         data.writeInt32(cameraId);
298         remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply);
299         if (readExceptionCode(reply)) return -EPROTO;
300 
301         status_t res = data.readInt32();
302         int32_t length = data.readInt32(); // -1 means null
303         if (length > 0) {
304             *parameters = data.readString16();
305         } else {
306             *parameters = String16();
307         }
308 
309         return res;
310     }
311 
supportsCameraApi(int cameraId,int apiVersion)312     virtual status_t supportsCameraApi(int cameraId, int apiVersion) {
313         Parcel data, reply;
314 
315         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
316         data.writeInt32(cameraId);
317         data.writeInt32(apiVersion);
318         remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply);
319         if (readExceptionCode(reply)) return -EPROTO;
320 
321         status_t res = data.readInt32();
322         return res;
323     }
324 
notifySystemEvent(int32_t eventId,const int32_t * args,size_t len)325     virtual void notifySystemEvent(int32_t eventId, const int32_t* args, size_t len) {
326         Parcel data, reply;
327         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
328         data.writeInt32(eventId);
329         data.writeInt32Array(len, args);
330         remote()->transact(BnCameraService::NOTIFY_SYSTEM_EVENT, data, &reply,
331                 IBinder::FLAG_ONEWAY);
332     }
333 
334 };
335 
336 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
337 
338 // ----------------------------------------------------------------------
339 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)340 status_t BnCameraService::onTransact(
341     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
342 {
343     switch(code) {
344         case GET_NUMBER_OF_CAMERAS: {
345             CHECK_INTERFACE(ICameraService, data, reply);
346             reply->writeNoException();
347             reply->writeInt32(getNumberOfCameras(data.readInt32()));
348             return NO_ERROR;
349         } break;
350         case GET_CAMERA_INFO: {
351             CHECK_INTERFACE(ICameraService, data, reply);
352             CameraInfo cameraInfo = CameraInfo();
353             memset(&cameraInfo, 0, sizeof(cameraInfo));
354             status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
355             reply->writeNoException();
356             reply->writeInt32(result);
357 
358             // Fake a parcelable object here
359             reply->writeInt32(1); // means the parcelable is included
360             reply->writeInt32(cameraInfo.facing);
361             reply->writeInt32(cameraInfo.orientation);
362             return NO_ERROR;
363         } break;
364         case GET_CAMERA_CHARACTERISTICS: {
365             CHECK_INTERFACE(ICameraService, data, reply);
366             CameraMetadata info;
367             status_t result = getCameraCharacteristics(data.readInt32(), &info);
368             reply->writeNoException();
369             reply->writeInt32(result);
370 
371             // out-variables are after exception and return value
372             reply->writeInt32(1); // means the parcelable is included
373             info.writeToParcel(reply);
374             return NO_ERROR;
375         } break;
376         case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: {
377             CHECK_INTERFACE(ICameraService, data, reply);
378             sp<VendorTagDescriptor> d;
379             status_t result = getCameraVendorTagDescriptor(d);
380             reply->writeNoException();
381             reply->writeInt32(result);
382 
383             // out-variables are after exception and return value
384             if (d == NULL) {
385                 reply->writeInt32(0);
386             } else {
387                 reply->writeInt32(1); // means the parcelable is included
388                 d->writeToParcel(reply);
389             }
390             return NO_ERROR;
391         } break;
392         case CONNECT: {
393             CHECK_INTERFACE(ICameraService, data, reply);
394             sp<ICameraClient> cameraClient =
395                     interface_cast<ICameraClient>(data.readStrongBinder());
396             int32_t cameraId = data.readInt32();
397             const String16 clientName = data.readString16();
398             int32_t clientUid = data.readInt32();
399             sp<ICamera> camera;
400             status_t status = connect(cameraClient, cameraId,
401                     clientName, clientUid, /*out*/camera);
402             reply->writeNoException();
403             reply->writeInt32(status);
404             if (camera != NULL) {
405                 reply->writeInt32(1);
406                 reply->writeStrongBinder(IInterface::asBinder(camera));
407             } else {
408                 reply->writeInt32(0);
409             }
410             return NO_ERROR;
411         } break;
412         case CONNECT_DEVICE: {
413             CHECK_INTERFACE(ICameraService, data, reply);
414             sp<ICameraDeviceCallbacks> cameraClient =
415                 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
416             int32_t cameraId = data.readInt32();
417             const String16 clientName = data.readString16();
418             int32_t clientUid = data.readInt32();
419             sp<ICameraDeviceUser> camera;
420             status_t status = connectDevice(cameraClient, cameraId,
421                     clientName, clientUid, /*out*/camera);
422             reply->writeNoException();
423             reply->writeInt32(status);
424             if (camera != NULL) {
425                 reply->writeInt32(1);
426                 reply->writeStrongBinder(IInterface::asBinder(camera));
427             } else {
428                 reply->writeInt32(0);
429             }
430             return NO_ERROR;
431         } break;
432         case ADD_LISTENER: {
433             CHECK_INTERFACE(ICameraService, data, reply);
434             sp<ICameraServiceListener> listener =
435                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
436             reply->writeNoException();
437             reply->writeInt32(addListener(listener));
438             return NO_ERROR;
439         } break;
440         case REMOVE_LISTENER: {
441             CHECK_INTERFACE(ICameraService, data, reply);
442             sp<ICameraServiceListener> listener =
443                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
444             reply->writeNoException();
445             reply->writeInt32(removeListener(listener));
446             return NO_ERROR;
447         } break;
448         case GET_LEGACY_PARAMETERS: {
449             CHECK_INTERFACE(ICameraService, data, reply);
450             int cameraId = data.readInt32();
451             String16 parameters;
452 
453             reply->writeNoException();
454             // return value
455             reply->writeInt32(getLegacyParameters(cameraId, &parameters));
456             // out parameters
457             reply->writeInt32(1); // parameters is always available
458             reply->writeString16(parameters);
459             return NO_ERROR;
460         } break;
461         case SUPPORTS_CAMERA_API: {
462             CHECK_INTERFACE(ICameraService, data, reply);
463             int cameraId = data.readInt32();
464             int apiVersion = data.readInt32();
465 
466             reply->writeNoException();
467             // return value
468             reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
469             return NO_ERROR;
470         } break;
471         case CONNECT_LEGACY: {
472             CHECK_INTERFACE(ICameraService, data, reply);
473             sp<ICameraClient> cameraClient =
474                     interface_cast<ICameraClient>(data.readStrongBinder());
475             int32_t cameraId = data.readInt32();
476             int32_t halVersion = data.readInt32();
477             const String16 clientName = data.readString16();
478             int32_t clientUid = data.readInt32();
479             sp<ICamera> camera;
480             status_t status = connectLegacy(cameraClient, cameraId, halVersion,
481                     clientName, clientUid, /*out*/camera);
482             reply->writeNoException();
483             reply->writeInt32(status);
484             if (camera != NULL) {
485                 reply->writeInt32(1);
486                 reply->writeStrongBinder(IInterface::asBinder(camera));
487             } else {
488                 reply->writeInt32(0);
489             }
490             return NO_ERROR;
491         } break;
492         case SET_TORCH_MODE: {
493             CHECK_INTERFACE(ICameraService, data, reply);
494             String16 cameraId = data.readString16();
495             bool enabled = data.readInt32() != 0 ? true : false;
496             const sp<IBinder> clientBinder = data.readStrongBinder();
497             status_t status = setTorchMode(cameraId, enabled, clientBinder);
498             reply->writeNoException();
499             reply->writeInt32(status);
500             return NO_ERROR;
501         } break;
502         case NOTIFY_SYSTEM_EVENT: {
503             CHECK_INTERFACE(ICameraService, data, reply);
504             int32_t eventId = data.readInt32();
505             int32_t len = data.readInt32();
506             if (len < 0) {
507                 ALOGE("%s: Received poorly formatted length in binder request: notifySystemEvent.",
508                         __FUNCTION__);
509                 return FAILED_TRANSACTION;
510             }
511             if (len > 512) {
512                 ALOGE("%s: Length %" PRIi32 " too long in binder request: notifySystemEvent.",
513                         __FUNCTION__, len);
514                 return FAILED_TRANSACTION;
515             }
516             int32_t events[len];
517             memset(events, 0, sizeof(int32_t) * len);
518             status_t status = data.read(events, sizeof(int32_t) * len);
519             if (status != NO_ERROR) {
520                 ALOGE("%s: Received poorly formatted binder request: notifySystemEvent.",
521                         __FUNCTION__);
522                 return FAILED_TRANSACTION;
523             }
524             notifySystemEvent(eventId, events, len);
525             return NO_ERROR;
526         } break;
527         default:
528             return BBinder::onTransact(code, data, reply, flags);
529     }
530 }
531 
532 // ----------------------------------------------------------------------------
533 
534 }; // namespace android
535