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