ICameraService.cpp revision 2b59be89dc245b6e2475d9e8b0c5f2392370e71e
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
38namespace android {
39
40namespace {
41
42enum {
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
51static 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
87class BpCameraService: public BpInterface<ICameraService>
88{
89public:
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
238IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
239
240// ----------------------------------------------------------------------
241
242status_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
362