ICameraService.cpp revision e1445da74730473a66a3ae8414e940aebfe6585d
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
22#include <stdint.h>
23#include <sys/types.h>
24
25#include <binder/Parcel.h>
26#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28
29#include <camera/ICameraService.h>
30#include <camera/ICameraServiceListener.h>
31#include <camera/IProCameraUser.h>
32#include <camera/IProCameraCallbacks.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
40namespace android {
41
42namespace {
43
44enum {
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
53static 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
89class BpCameraService: public BpInterface<ICameraService>
90{
91public:
92    BpCameraService(const sp<IBinder>& impl)
93        : BpInterface<ICameraService>(impl)
94    {
95    }
96
97    // get number of cameras available
98    virtual int32_t getNumberOfCameras()
99    {
100        Parcel data, reply;
101        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
102        remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
103
104        if (readExceptionCode(reply)) return 0;
105        return reply.readInt32();
106    }
107
108    // get information about a camera
109    virtual status_t getCameraInfo(int cameraId,
110                                   struct CameraInfo* cameraInfo) {
111        Parcel data, reply;
112        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
113        data.writeInt32(cameraId);
114        remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
115
116        if (readExceptionCode(reply)) return -EPROTO;
117        status_t result = reply.readInt32();
118        if (reply.readInt32() != 0) {
119            cameraInfo->facing = reply.readInt32();
120            cameraInfo->orientation = reply.readInt32();
121        }
122        return result;
123    }
124
125    // get camera characteristics (static metadata)
126    virtual status_t getCameraCharacteristics(int cameraId,
127                                              CameraMetadata* cameraInfo) {
128        Parcel data, reply;
129        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
130        data.writeInt32(cameraId);
131        remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
132
133        if (readExceptionCode(reply)) return -EPROTO;
134        status_t result = reply.readInt32();
135
136        CameraMetadata out;
137        if (reply.readInt32() != 0) {
138            out.readFromParcel(&reply);
139        }
140
141        if (cameraInfo != NULL) {
142            cameraInfo->swap(out);
143        }
144
145        return result;
146    }
147
148    // Get enumeration and description of vendor tags for camera
149    virtual status_t getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
150        Parcel data, reply;
151        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
152        remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply);
153
154        if (readExceptionCode(reply)) return -EPROTO;
155        status_t result = reply.readInt32();
156
157        if (reply.readInt32() != 0) {
158            sp<VendorTagDescriptor> d;
159            if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) {
160                desc = d;
161            }
162        }
163        return result;
164    }
165
166    // connect to camera service (android.hardware.Camera)
167    virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
168                             const String16 &clientPackageName, int clientUid,
169                             /*out*/
170                             sp<ICamera>& device)
171    {
172        Parcel data, reply;
173        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
174        data.writeStrongBinder(cameraClient->asBinder());
175        data.writeInt32(cameraId);
176        data.writeString16(clientPackageName);
177        data.writeInt32(clientUid);
178        remote()->transact(BnCameraService::CONNECT, data, &reply);
179
180        if (readExceptionCode(reply)) return -EPROTO;
181        status_t status = reply.readInt32();
182        if (reply.readInt32() != 0) {
183            device = interface_cast<ICamera>(reply.readStrongBinder());
184        }
185        return status;
186    }
187
188    // connect to camera service (pro client)
189    virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
190                                const String16 &clientPackageName, int clientUid,
191                                /*out*/
192                                sp<IProCameraUser>& device)
193    {
194        Parcel data, reply;
195        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
196        data.writeStrongBinder(cameraCb->asBinder());
197        data.writeInt32(cameraId);
198        data.writeString16(clientPackageName);
199        data.writeInt32(clientUid);
200        remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
201
202        if (readExceptionCode(reply)) return -EPROTO;
203        status_t status = reply.readInt32();
204        if (reply.readInt32() != 0) {
205            device = interface_cast<IProCameraUser>(reply.readStrongBinder());
206        }
207        return status;
208    }
209
210    // connect to camera service (android.hardware.camera2.CameraDevice)
211    virtual status_t connectDevice(
212            const sp<ICameraDeviceCallbacks>& cameraCb,
213            int cameraId,
214            const String16& clientPackageName,
215            int clientUid,
216            /*out*/
217            sp<ICameraDeviceUser>& device)
218    {
219        Parcel data, reply;
220        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
221        data.writeStrongBinder(cameraCb->asBinder());
222        data.writeInt32(cameraId);
223        data.writeString16(clientPackageName);
224        data.writeInt32(clientUid);
225        remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
226
227        if (readExceptionCode(reply)) return -EPROTO;
228        status_t status = reply.readInt32();
229        if (reply.readInt32() != 0) {
230            device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
231        }
232        return status;
233    }
234
235    virtual status_t addListener(const sp<ICameraServiceListener>& listener)
236    {
237        Parcel data, reply;
238        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
239        data.writeStrongBinder(listener->asBinder());
240        remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
241
242        if (readExceptionCode(reply)) return -EPROTO;
243        return reply.readInt32();
244    }
245
246    virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
247    {
248        Parcel data, reply;
249        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
250        data.writeStrongBinder(listener->asBinder());
251        remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
252
253        if (readExceptionCode(reply)) return -EPROTO;
254        return reply.readInt32();
255    }
256};
257
258IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
259
260// ----------------------------------------------------------------------
261
262status_t BnCameraService::onTransact(
263    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
264{
265    switch(code) {
266        case GET_NUMBER_OF_CAMERAS: {
267            CHECK_INTERFACE(ICameraService, data, reply);
268            reply->writeNoException();
269            reply->writeInt32(getNumberOfCameras());
270            return NO_ERROR;
271        } break;
272        case GET_CAMERA_INFO: {
273            CHECK_INTERFACE(ICameraService, data, reply);
274            CameraInfo cameraInfo = CameraInfo();
275            memset(&cameraInfo, 0, sizeof(cameraInfo));
276            status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
277            reply->writeNoException();
278            reply->writeInt32(result);
279
280            // Fake a parcelable object here
281            reply->writeInt32(1); // means the parcelable is included
282            reply->writeInt32(cameraInfo.facing);
283            reply->writeInt32(cameraInfo.orientation);
284            return NO_ERROR;
285        } break;
286        case GET_CAMERA_CHARACTERISTICS: {
287            CHECK_INTERFACE(ICameraService, data, reply);
288            CameraMetadata info;
289            status_t result = getCameraCharacteristics(data.readInt32(), &info);
290            reply->writeNoException();
291            reply->writeInt32(result);
292
293            // out-variables are after exception and return value
294            reply->writeInt32(1); // means the parcelable is included
295            info.writeToParcel(reply);
296            return NO_ERROR;
297        } break;
298        case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: {
299            CHECK_INTERFACE(ICameraService, data, reply);
300            sp<VendorTagDescriptor> d;
301            status_t result = getCameraVendorTagDescriptor(d);
302            reply->writeNoException();
303            reply->writeInt32(result);
304
305            // out-variables are after exception and return value
306            if (d == NULL) {
307                reply->writeInt32(0);
308            } else {
309                reply->writeInt32(1); // means the parcelable is included
310                d->writeToParcel(reply);
311            }
312            return NO_ERROR;
313        } break;
314        case CONNECT: {
315            CHECK_INTERFACE(ICameraService, data, reply);
316            sp<ICameraClient> cameraClient =
317                    interface_cast<ICameraClient>(data.readStrongBinder());
318            int32_t cameraId = data.readInt32();
319            const String16 clientName = data.readString16();
320            int32_t clientUid = data.readInt32();
321            sp<ICamera> camera;
322            status_t status = connect(cameraClient, cameraId,
323                    clientName, clientUid, /*out*/camera);
324            reply->writeNoException();
325            reply->writeInt32(status);
326            if (camera != NULL) {
327                reply->writeInt32(1);
328                reply->writeStrongBinder(camera->asBinder());
329            } else {
330                reply->writeInt32(0);
331            }
332            return NO_ERROR;
333        } break;
334        case CONNECT_PRO: {
335            CHECK_INTERFACE(ICameraService, data, reply);
336            sp<IProCameraCallbacks> cameraClient =
337                interface_cast<IProCameraCallbacks>(data.readStrongBinder());
338            int32_t cameraId = data.readInt32();
339            const String16 clientName = data.readString16();
340            int32_t clientUid = data.readInt32();
341            sp<IProCameraUser> camera;
342            status_t status = connectPro(cameraClient, cameraId,
343                    clientName, clientUid, /*out*/camera);
344            reply->writeNoException();
345            reply->writeInt32(status);
346            if (camera != NULL) {
347                reply->writeInt32(1);
348                reply->writeStrongBinder(camera->asBinder());
349            } else {
350                reply->writeInt32(0);
351            }
352            return NO_ERROR;
353        } break;
354        case CONNECT_DEVICE: {
355            CHECK_INTERFACE(ICameraService, data, reply);
356            sp<ICameraDeviceCallbacks> cameraClient =
357                interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
358            int32_t cameraId = data.readInt32();
359            const String16 clientName = data.readString16();
360            int32_t clientUid = data.readInt32();
361            sp<ICameraDeviceUser> camera;
362            status_t status = connectDevice(cameraClient, cameraId,
363                    clientName, clientUid, /*out*/camera);
364            reply->writeNoException();
365            reply->writeInt32(status);
366            if (camera != NULL) {
367                reply->writeInt32(1);
368                reply->writeStrongBinder(camera->asBinder());
369            } else {
370                reply->writeInt32(0);
371            }
372            return NO_ERROR;
373        } break;
374        case ADD_LISTENER: {
375            CHECK_INTERFACE(ICameraService, data, reply);
376            sp<ICameraServiceListener> listener =
377                interface_cast<ICameraServiceListener>(data.readStrongBinder());
378            reply->writeNoException();
379            reply->writeInt32(addListener(listener));
380            return NO_ERROR;
381        } break;
382        case REMOVE_LISTENER: {
383            CHECK_INTERFACE(ICameraService, data, reply);
384            sp<ICameraServiceListener> listener =
385                interface_cast<ICameraServiceListener>(data.readStrongBinder());
386            reply->writeNoException();
387            reply->writeInt32(removeListener(listener));
388            return NO_ERROR;
389        } break;
390        default:
391            return BBinder::onTransact(code, data, reply, flags);
392    }
393}
394
395// ----------------------------------------------------------------------------
396
397}; // namespace android
398