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 (android.hardware.Camera)
190    virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
191                             int halVersion,
192                             const String16 &clientPackageName, int clientUid,
193                             /*out*/sp<ICamera>& device)
194    {
195        Parcel data, reply;
196        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
197        data.writeStrongBinder(cameraClient->asBinder());
198        data.writeInt32(cameraId);
199        data.writeInt32(halVersion);
200        data.writeString16(clientPackageName);
201        data.writeInt32(clientUid);
202        remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
203
204        if (readExceptionCode(reply)) return -EPROTO;
205        status_t status = reply.readInt32();
206        if (reply.readInt32() != 0) {
207            device = interface_cast<ICamera>(reply.readStrongBinder());
208        }
209        return status;
210    }
211
212    // connect to camera service (pro client)
213    virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
214                                const String16 &clientPackageName, int clientUid,
215                                /*out*/
216                                sp<IProCameraUser>& device)
217    {
218        Parcel data, reply;
219        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
220        data.writeStrongBinder(cameraCb->asBinder());
221        data.writeInt32(cameraId);
222        data.writeString16(clientPackageName);
223        data.writeInt32(clientUid);
224        remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
225
226        if (readExceptionCode(reply)) return -EPROTO;
227        status_t status = reply.readInt32();
228        if (reply.readInt32() != 0) {
229            device = interface_cast<IProCameraUser>(reply.readStrongBinder());
230        }
231        return status;
232    }
233
234    // connect to camera service (android.hardware.camera2.CameraDevice)
235    virtual status_t connectDevice(
236            const sp<ICameraDeviceCallbacks>& cameraCb,
237            int cameraId,
238            const String16& clientPackageName,
239            int clientUid,
240            /*out*/
241            sp<ICameraDeviceUser>& device)
242    {
243        Parcel data, reply;
244        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
245        data.writeStrongBinder(cameraCb->asBinder());
246        data.writeInt32(cameraId);
247        data.writeString16(clientPackageName);
248        data.writeInt32(clientUid);
249        remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
250
251        if (readExceptionCode(reply)) return -EPROTO;
252        status_t status = reply.readInt32();
253        if (reply.readInt32() != 0) {
254            device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
255        }
256        return status;
257    }
258
259    virtual status_t addListener(const sp<ICameraServiceListener>& listener)
260    {
261        Parcel data, reply;
262        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
263        data.writeStrongBinder(listener->asBinder());
264        remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
265
266        if (readExceptionCode(reply)) return -EPROTO;
267        return reply.readInt32();
268    }
269
270    virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
271    {
272        Parcel data, reply;
273        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
274        data.writeStrongBinder(listener->asBinder());
275        remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
276
277        if (readExceptionCode(reply)) return -EPROTO;
278        return reply.readInt32();
279    }
280
281    virtual status_t getLegacyParameters(int cameraId, String16* parameters) {
282        if (parameters == NULL) {
283            ALOGE("%s: parameters must not be null", __FUNCTION__);
284            return BAD_VALUE;
285        }
286
287        Parcel data, reply;
288
289        data.writeInt32(cameraId);
290        remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply);
291        if (readExceptionCode(reply)) return -EPROTO;
292
293        status_t res = data.readInt32();
294        int32_t length = data.readInt32(); // -1 means null
295        if (length > 0) {
296            *parameters = data.readString16();
297        } else {
298            *parameters = String16();
299        }
300
301        return res;
302    }
303
304    virtual status_t supportsCameraApi(int cameraId, int apiVersion) {
305        Parcel data, reply;
306
307        data.writeInt32(cameraId);
308        data.writeInt32(apiVersion);
309        remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply);
310        if (readExceptionCode(reply)) return -EPROTO;
311
312        status_t res = data.readInt32();
313        return res;
314    }
315};
316
317IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
318
319// ----------------------------------------------------------------------
320
321status_t BnCameraService::onTransact(
322    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
323{
324    switch(code) {
325        case GET_NUMBER_OF_CAMERAS: {
326            CHECK_INTERFACE(ICameraService, data, reply);
327            reply->writeNoException();
328            reply->writeInt32(getNumberOfCameras());
329            return NO_ERROR;
330        } break;
331        case GET_CAMERA_INFO: {
332            CHECK_INTERFACE(ICameraService, data, reply);
333            CameraInfo cameraInfo = CameraInfo();
334            memset(&cameraInfo, 0, sizeof(cameraInfo));
335            status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
336            reply->writeNoException();
337            reply->writeInt32(result);
338
339            // Fake a parcelable object here
340            reply->writeInt32(1); // means the parcelable is included
341            reply->writeInt32(cameraInfo.facing);
342            reply->writeInt32(cameraInfo.orientation);
343            return NO_ERROR;
344        } break;
345        case GET_CAMERA_CHARACTERISTICS: {
346            CHECK_INTERFACE(ICameraService, data, reply);
347            CameraMetadata info;
348            status_t result = getCameraCharacteristics(data.readInt32(), &info);
349            reply->writeNoException();
350            reply->writeInt32(result);
351
352            // out-variables are after exception and return value
353            reply->writeInt32(1); // means the parcelable is included
354            info.writeToParcel(reply);
355            return NO_ERROR;
356        } break;
357        case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: {
358            CHECK_INTERFACE(ICameraService, data, reply);
359            sp<VendorTagDescriptor> d;
360            status_t result = getCameraVendorTagDescriptor(d);
361            reply->writeNoException();
362            reply->writeInt32(result);
363
364            // out-variables are after exception and return value
365            if (d == NULL) {
366                reply->writeInt32(0);
367            } else {
368                reply->writeInt32(1); // means the parcelable is included
369                d->writeToParcel(reply);
370            }
371            return NO_ERROR;
372        } break;
373        case CONNECT: {
374            CHECK_INTERFACE(ICameraService, data, reply);
375            sp<ICameraClient> cameraClient =
376                    interface_cast<ICameraClient>(data.readStrongBinder());
377            int32_t cameraId = data.readInt32();
378            const String16 clientName = data.readString16();
379            int32_t clientUid = data.readInt32();
380            sp<ICamera> camera;
381            status_t status = connect(cameraClient, cameraId,
382                    clientName, clientUid, /*out*/camera);
383            reply->writeNoException();
384            reply->writeInt32(status);
385            if (camera != NULL) {
386                reply->writeInt32(1);
387                reply->writeStrongBinder(camera->asBinder());
388            } else {
389                reply->writeInt32(0);
390            }
391            return NO_ERROR;
392        } break;
393        case CONNECT_PRO: {
394            CHECK_INTERFACE(ICameraService, data, reply);
395            sp<IProCameraCallbacks> cameraClient =
396                interface_cast<IProCameraCallbacks>(data.readStrongBinder());
397            int32_t cameraId = data.readInt32();
398            const String16 clientName = data.readString16();
399            int32_t clientUid = data.readInt32();
400            sp<IProCameraUser> camera;
401            status_t status = connectPro(cameraClient, cameraId,
402                    clientName, clientUid, /*out*/camera);
403            reply->writeNoException();
404            reply->writeInt32(status);
405            if (camera != NULL) {
406                reply->writeInt32(1);
407                reply->writeStrongBinder(camera->asBinder());
408            } else {
409                reply->writeInt32(0);
410            }
411            return NO_ERROR;
412        } break;
413        case CONNECT_DEVICE: {
414            CHECK_INTERFACE(ICameraService, data, reply);
415            sp<ICameraDeviceCallbacks> cameraClient =
416                interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
417            int32_t cameraId = data.readInt32();
418            const String16 clientName = data.readString16();
419            int32_t clientUid = data.readInt32();
420            sp<ICameraDeviceUser> camera;
421            status_t status = connectDevice(cameraClient, cameraId,
422                    clientName, clientUid, /*out*/camera);
423            reply->writeNoException();
424            reply->writeInt32(status);
425            if (camera != NULL) {
426                reply->writeInt32(1);
427                reply->writeStrongBinder(camera->asBinder());
428            } else {
429                reply->writeInt32(0);
430            }
431            return NO_ERROR;
432        } break;
433        case ADD_LISTENER: {
434            CHECK_INTERFACE(ICameraService, data, reply);
435            sp<ICameraServiceListener> listener =
436                interface_cast<ICameraServiceListener>(data.readStrongBinder());
437            reply->writeNoException();
438            reply->writeInt32(addListener(listener));
439            return NO_ERROR;
440        } break;
441        case REMOVE_LISTENER: {
442            CHECK_INTERFACE(ICameraService, data, reply);
443            sp<ICameraServiceListener> listener =
444                interface_cast<ICameraServiceListener>(data.readStrongBinder());
445            reply->writeNoException();
446            reply->writeInt32(removeListener(listener));
447            return NO_ERROR;
448        } break;
449        case GET_LEGACY_PARAMETERS: {
450            CHECK_INTERFACE(ICameraService, data, reply);
451            int cameraId = data.readInt32();
452            String16 parameters;
453
454            reply->writeNoException();
455            // return value
456            reply->writeInt32(getLegacyParameters(cameraId, &parameters));
457            // out parameters
458            reply->writeInt32(1); // parameters is always available
459            reply->writeString16(parameters);
460            return NO_ERROR;
461        } break;
462        case SUPPORTS_CAMERA_API: {
463            CHECK_INTERFACE(ICameraService, data, reply);
464            int cameraId = data.readInt32();
465            int apiVersion = data.readInt32();
466
467            reply->writeNoException();
468            // return value
469            reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
470            return NO_ERROR;
471        } break;
472        case CONNECT_LEGACY: {
473            CHECK_INTERFACE(ICameraService, data, reply);
474            sp<ICameraClient> cameraClient =
475                    interface_cast<ICameraClient>(data.readStrongBinder());
476            int32_t cameraId = data.readInt32();
477            int32_t halVersion = data.readInt32();
478            const String16 clientName = data.readString16();
479            int32_t clientUid = data.readInt32();
480            sp<ICamera> camera;
481            status_t status = connectLegacy(cameraClient, cameraId, halVersion,
482                    clientName, clientUid, /*out*/camera);
483            reply->writeNoException();
484            reply->writeInt32(status);
485            if (camera != NULL) {
486                reply->writeInt32(1);
487                reply->writeStrongBinder(camera->asBinder());
488            } else {
489                reply->writeInt32(0);
490            }
491            return NO_ERROR;
492        } break;
493        default:
494            return BBinder::onTransact(code, data, reply, flags);
495    }
496}
497
498// ----------------------------------------------------------------------------
499
500}; // namespace android
501