ICameraService.cpp revision 7b82efe7a376c882f8f938e1c41b8311a8cdda4a
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 sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
124                                const String16 &clientPackageName, int clientUid)
125    {
126        Parcel data, reply;
127        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
128        data.writeStrongBinder(cameraClient->asBinder());
129        data.writeInt32(cameraId);
130        data.writeString16(clientPackageName);
131        data.writeInt32(clientUid);
132        remote()->transact(BnCameraService::CONNECT, data, &reply);
133
134        if (readExceptionCode(reply)) return NULL;
135        return interface_cast<ICamera>(reply.readStrongBinder());
136    }
137
138    // connect to camera service (pro client)
139    virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
140                                       const String16 &clientPackageName, int clientUid)
141    {
142        Parcel data, reply;
143        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
144        data.writeStrongBinder(cameraCb->asBinder());
145        data.writeInt32(cameraId);
146        data.writeString16(clientPackageName);
147        data.writeInt32(clientUid);
148        remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
149
150        if (readExceptionCode(reply)) return NULL;
151        return interface_cast<IProCameraUser>(reply.readStrongBinder());
152    }
153
154    // connect to camera service (android.hardware.camera2.CameraDevice)
155    virtual sp<ICameraDeviceUser> connect(
156            const sp<ICameraDeviceCallbacks>& cameraCb,
157            int cameraId,
158            const String16& clientPackageName,
159            int clientUid)
160    {
161        Parcel data, reply;
162        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
163        data.writeStrongBinder(cameraCb->asBinder());
164        data.writeInt32(cameraId);
165        data.writeString16(clientPackageName);
166        data.writeInt32(clientUid);
167        remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
168
169        if (readExceptionCode(reply)) return NULL;
170        return interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
171    }
172
173    virtual status_t addListener(const sp<ICameraServiceListener>& listener)
174    {
175        Parcel data, reply;
176        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
177        data.writeStrongBinder(listener->asBinder());
178        remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
179
180        if (readExceptionCode(reply)) return -EPROTO;
181        return reply.readInt32();
182    }
183
184    virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
185    {
186        Parcel data, reply;
187        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
188        data.writeStrongBinder(listener->asBinder());
189        remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
190
191        if (readExceptionCode(reply)) return -EPROTO;
192        return reply.readInt32();
193    }
194};
195
196IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
197
198// ----------------------------------------------------------------------
199
200status_t BnCameraService::onTransact(
201    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
202{
203    switch(code) {
204        case GET_NUMBER_OF_CAMERAS: {
205            CHECK_INTERFACE(ICameraService, data, reply);
206            reply->writeNoException();
207            reply->writeInt32(getNumberOfCameras());
208            return NO_ERROR;
209        } break;
210        case GET_CAMERA_INFO: {
211            CHECK_INTERFACE(ICameraService, data, reply);
212            CameraInfo cameraInfo = CameraInfo();
213            memset(&cameraInfo, 0, sizeof(cameraInfo));
214            status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
215            reply->writeNoException();
216            reply->writeInt32(result);
217
218            // Fake a parcelable object here
219            reply->writeInt32(1); // means the parcelable is included
220            reply->writeInt32(cameraInfo.facing);
221            reply->writeInt32(cameraInfo.orientation);
222            return NO_ERROR;
223        } break;
224        case CONNECT: {
225            CHECK_INTERFACE(ICameraService, data, reply);
226            sp<ICameraClient> cameraClient =
227                    interface_cast<ICameraClient>(data.readStrongBinder());
228            int32_t cameraId = data.readInt32();
229            const String16 clientName = data.readString16();
230            int32_t clientUid = data.readInt32();
231            sp<ICamera> camera = connect(cameraClient, cameraId,
232                    clientName, clientUid);
233            reply->writeNoException();
234            reply->writeStrongBinder(camera->asBinder());
235            return NO_ERROR;
236        } break;
237        case CONNECT_PRO: {
238            CHECK_INTERFACE(ICameraService, data, reply);
239            sp<IProCameraCallbacks> cameraClient =
240                interface_cast<IProCameraCallbacks>(data.readStrongBinder());
241            int32_t cameraId = data.readInt32();
242            const String16 clientName = data.readString16();
243            int32_t clientUid = data.readInt32();
244            sp<IProCameraUser> camera = connect(cameraClient, cameraId,
245                                                clientName, clientUid);
246            reply->writeNoException();
247            reply->writeStrongBinder(camera->asBinder());
248            return NO_ERROR;
249        } break;
250        case CONNECT_DEVICE: {
251            CHECK_INTERFACE(ICameraService, data, reply);
252            sp<ICameraDeviceCallbacks> cameraClient =
253                interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
254            int32_t cameraId = data.readInt32();
255            const String16 clientName = data.readString16();
256            int32_t clientUid = data.readInt32();
257            sp<ICameraDeviceUser> camera = connect(cameraClient, cameraId,
258                                                clientName, clientUid);
259            reply->writeNoException();
260            reply->writeStrongBinder(camera->asBinder());
261            return NO_ERROR;
262        } break;
263        case ADD_LISTENER: {
264            CHECK_INTERFACE(ICameraService, data, reply);
265            sp<ICameraServiceListener> listener =
266                interface_cast<ICameraServiceListener>(data.readStrongBinder());
267            reply->writeNoException();
268            reply->writeInt32(addListener(listener));
269            return NO_ERROR;
270        } break;
271        case REMOVE_LISTENER: {
272            CHECK_INTERFACE(ICameraService, data, reply);
273            sp<ICameraServiceListener> listener =
274                interface_cast<ICameraServiceListener>(data.readStrongBinder());
275            reply->writeNoException();
276            reply->writeInt32(removeListener(listener));
277            return NO_ERROR;
278        } break;
279        default:
280            return BBinder::onTransact(code, data, reply, flags);
281    }
282}
283
284// ----------------------------------------------------------------------------
285
286}; // namespace android
287