ICameraService.cpp revision 0f61d8f14aa368c9cd7076528e8096e10ed100a0
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
37namespace android {
38
39namespace {
40
41enum {
42    EX_SECURITY = -1,
43    EX_BAD_PARCELABLE = -2,
44    EX_ILLEGAL_ARGUMENT = -3,
45    EX_NULL_POINTER = -4,
46    EX_ILLEGAL_STATE = -5,
47    EX_HAS_REPLY_HEADER = -128,  // special; see below
48};
49
50static bool readExceptionCode(Parcel& reply) {
51    int32_t exceptionCode = reply.readExceptionCode();
52
53    if (exceptionCode != 0) {
54        const char* errorMsg;
55        switch(exceptionCode) {
56            case EX_SECURITY:
57                errorMsg = "Security";
58                break;
59            case EX_BAD_PARCELABLE:
60                errorMsg = "BadParcelable";
61                break;
62            case EX_NULL_POINTER:
63                errorMsg = "NullPointer";
64                break;
65            case EX_ILLEGAL_STATE:
66                errorMsg = "IllegalState";
67                break;
68            // Binder should be handling this code inside Parcel::readException
69            // but lets have a to-string here anyway just in case.
70            case EX_HAS_REPLY_HEADER:
71                errorMsg = "HasReplyHeader";
72                break;
73            default:
74                errorMsg = "Unknown";
75        }
76
77        ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
78        return true;
79    }
80
81    return false;
82}
83
84};
85
86class BpCameraService: public BpInterface<ICameraService>
87{
88public:
89    BpCameraService(const sp<IBinder>& impl)
90        : BpInterface<ICameraService>(impl)
91    {
92    }
93
94    // get number of cameras available
95    virtual int32_t getNumberOfCameras()
96    {
97        Parcel data, reply;
98        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
99        remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
100
101        if (readExceptionCode(reply)) return 0;
102        return reply.readInt32();
103    }
104
105    // get information about a camera
106    virtual status_t getCameraInfo(int cameraId,
107                                   struct CameraInfo* cameraInfo) {
108        Parcel data, reply;
109        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
110        data.writeInt32(cameraId);
111        remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
112
113        if (readExceptionCode(reply)) return -EPROTO;
114        status_t result = reply.readInt32();
115        if (reply.readInt32() != 0) {
116            cameraInfo->facing = reply.readInt32();
117            cameraInfo->orientation = reply.readInt32();
118        }
119        return result;
120    }
121
122    // connect to camera service (android.hardware.Camera)
123    virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
124                             const String16 &clientPackageName, int clientUid,
125                             /*out*/
126                             sp<ICamera>& device)
127    {
128        Parcel data, reply;
129        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
130        data.writeStrongBinder(cameraClient->asBinder());
131        data.writeInt32(cameraId);
132        data.writeString16(clientPackageName);
133        data.writeInt32(clientUid);
134        remote()->transact(BnCameraService::CONNECT, data, &reply);
135
136        if (readExceptionCode(reply)) return -EPROTO;
137        status_t status = reply.readInt32();
138        if (reply.readInt32() != 0) {
139            device = interface_cast<ICamera>(reply.readStrongBinder());
140        }
141        return status;
142    }
143
144    // connect to camera service (pro client)
145    virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
146                                const String16 &clientPackageName, int clientUid,
147                                /*out*/
148                                sp<IProCameraUser>& device)
149    {
150        Parcel data, reply;
151        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
152        data.writeStrongBinder(cameraCb->asBinder());
153        data.writeInt32(cameraId);
154        data.writeString16(clientPackageName);
155        data.writeInt32(clientUid);
156        remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
157
158        if (readExceptionCode(reply)) return -EPROTO;
159        status_t status = reply.readInt32();
160        if (reply.readInt32() != 0) {
161            device = interface_cast<IProCameraUser>(reply.readStrongBinder());
162        }
163        return status;
164    }
165
166    // connect to camera service (android.hardware.camera2.CameraDevice)
167    virtual status_t connectDevice(
168            const sp<ICameraDeviceCallbacks>& cameraCb,
169            int cameraId,
170            const String16& clientPackageName,
171            int clientUid,
172            /*out*/
173            sp<ICameraDeviceUser>& device)
174    {
175        Parcel data, reply;
176        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
177        data.writeStrongBinder(cameraCb->asBinder());
178        data.writeInt32(cameraId);
179        data.writeString16(clientPackageName);
180        data.writeInt32(clientUid);
181        remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
182
183        if (readExceptionCode(reply)) return -EPROTO;
184        status_t status = reply.readInt32();
185        if (reply.readInt32() != 0) {
186            device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
187        }
188        return status;
189    }
190
191    virtual status_t addListener(const sp<ICameraServiceListener>& listener)
192    {
193        Parcel data, reply;
194        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
195        data.writeStrongBinder(listener->asBinder());
196        remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
197
198        if (readExceptionCode(reply)) return -EPROTO;
199        return reply.readInt32();
200    }
201
202    virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
203    {
204        Parcel data, reply;
205        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
206        data.writeStrongBinder(listener->asBinder());
207        remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
208
209        if (readExceptionCode(reply)) return -EPROTO;
210        return reply.readInt32();
211    }
212};
213
214IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
215
216// ----------------------------------------------------------------------
217
218status_t BnCameraService::onTransact(
219    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
220{
221    switch(code) {
222        case GET_NUMBER_OF_CAMERAS: {
223            CHECK_INTERFACE(ICameraService, data, reply);
224            reply->writeNoException();
225            reply->writeInt32(getNumberOfCameras());
226            return NO_ERROR;
227        } break;
228        case GET_CAMERA_INFO: {
229            CHECK_INTERFACE(ICameraService, data, reply);
230            CameraInfo cameraInfo = CameraInfo();
231            memset(&cameraInfo, 0, sizeof(cameraInfo));
232            status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
233            reply->writeNoException();
234            reply->writeInt32(result);
235
236            // Fake a parcelable object here
237            reply->writeInt32(1); // means the parcelable is included
238            reply->writeInt32(cameraInfo.facing);
239            reply->writeInt32(cameraInfo.orientation);
240            return NO_ERROR;
241        } break;
242        case CONNECT: {
243            CHECK_INTERFACE(ICameraService, data, reply);
244            sp<ICameraClient> cameraClient =
245                    interface_cast<ICameraClient>(data.readStrongBinder());
246            int32_t cameraId = data.readInt32();
247            const String16 clientName = data.readString16();
248            int32_t clientUid = data.readInt32();
249            sp<ICamera> camera;
250            status_t status = connect(cameraClient, cameraId,
251                    clientName, clientUid, /*out*/ camera);
252            reply->writeNoException();
253            reply->writeInt32(status);
254            if (camera != NULL) {
255                reply->writeInt32(1);
256                reply->writeStrongBinder(camera->asBinder());
257            } else {
258                reply->writeInt32(0);
259            }
260            return NO_ERROR;
261        } break;
262        case CONNECT_PRO: {
263            CHECK_INTERFACE(ICameraService, data, reply);
264            sp<IProCameraCallbacks> cameraClient =
265                interface_cast<IProCameraCallbacks>(data.readStrongBinder());
266            int32_t cameraId = data.readInt32();
267            const String16 clientName = data.readString16();
268            int32_t clientUid = data.readInt32();
269            sp<IProCameraUser> camera;
270            status_t status = connectPro(cameraClient, cameraId,
271                    clientName, clientUid, /*out*/ camera);
272            reply->writeNoException();
273            reply->writeInt32(status);
274            if (camera != NULL) {
275                reply->writeInt32(1);
276                reply->writeStrongBinder(camera->asBinder());
277            } else {
278                reply->writeInt32(0);
279            }
280            return NO_ERROR;
281        } break;
282        case CONNECT_DEVICE: {
283            CHECK_INTERFACE(ICameraService, data, reply);
284            sp<ICameraDeviceCallbacks> cameraClient =
285                interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
286            int32_t cameraId = data.readInt32();
287            const String16 clientName = data.readString16();
288            int32_t clientUid = data.readInt32();
289            sp<ICameraDeviceUser> camera;
290            status_t status = connectDevice(cameraClient, cameraId,
291                    clientName, clientUid, /*out*/ camera);
292            reply->writeNoException();
293            reply->writeInt32(status);
294            if (camera != NULL) {
295                reply->writeInt32(1);
296                reply->writeStrongBinder(camera->asBinder());
297            } else {
298                reply->writeInt32(0);
299            }
300            return NO_ERROR;
301        } break;
302        case ADD_LISTENER: {
303            CHECK_INTERFACE(ICameraService, data, reply);
304            sp<ICameraServiceListener> listener =
305                interface_cast<ICameraServiceListener>(data.readStrongBinder());
306            reply->writeNoException();
307            reply->writeInt32(addListener(listener));
308            return NO_ERROR;
309        } break;
310        case REMOVE_LISTENER: {
311            CHECK_INTERFACE(ICameraService, data, reply);
312            sp<ICameraServiceListener> listener =
313                interface_cast<ICameraServiceListener>(data.readStrongBinder());
314            reply->writeNoException();
315            reply->writeInt32(removeListener(listener));
316            return NO_ERROR;
317        } break;
318        default:
319            return BBinder::onTransact(code, data, reply, flags);
320    }
321}
322
323// ----------------------------------------------------------------------------
324
325}; // namespace android
326