ICamera.cpp revision 99617adda9bc46c43f511f0940bc735c73de61de
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_NDEBUG 0
19#define LOG_TAG "ICamera"
20#include <utils/Log.h>
21#include <stdint.h>
22#include <sys/types.h>
23#include <binder/Parcel.h>
24#include <camera/ICamera.h>
25#include <gui/IGraphicBufferProducer.h>
26#include <gui/Surface.h>
27
28namespace android {
29
30enum {
31    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
32    SET_PREVIEW_TEXTURE,
33    SET_PREVIEW_CALLBACK_FLAG,
34    START_PREVIEW,
35    STOP_PREVIEW,
36    AUTO_FOCUS,
37    CANCEL_AUTO_FOCUS,
38    TAKE_PICTURE,
39    SET_PARAMETERS,
40    GET_PARAMETERS,
41    SEND_COMMAND,
42    CONNECT,
43    LOCK,
44    UNLOCK,
45    PREVIEW_ENABLED,
46    START_RECORDING,
47    STOP_RECORDING,
48    RECORDING_ENABLED,
49    RELEASE_RECORDING_FRAME,
50    STORE_META_DATA_IN_BUFFERS,
51};
52
53class BpCamera: public BpInterface<ICamera>
54{
55public:
56    BpCamera(const sp<IBinder>& impl)
57        : BpInterface<ICamera>(impl)
58    {
59    }
60
61    // disconnect from camera service
62    void disconnect()
63    {
64        ALOGV("disconnect");
65        Parcel data, reply;
66        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
67        remote()->transact(DISCONNECT, data, &reply);
68    }
69
70    // pass the buffered IGraphicBufferProducer to the camera service
71    status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
72    {
73        ALOGV("setPreviewTexture");
74        Parcel data, reply;
75        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
76        sp<IBinder> b(bufferProducer->asBinder());
77        data.writeStrongBinder(b);
78        remote()->transact(SET_PREVIEW_TEXTURE, data, &reply);
79        return reply.readInt32();
80    }
81
82    // set the preview callback flag to affect how the received frames from
83    // preview are handled. See Camera.h for details.
84    void setPreviewCallbackFlag(int flag)
85    {
86        ALOGV("setPreviewCallbackFlag(%d)", flag);
87        Parcel data, reply;
88        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
89        data.writeInt32(flag);
90        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
91    }
92
93    // start preview mode, must call setPreviewDisplay first
94    status_t startPreview()
95    {
96        ALOGV("startPreview");
97        Parcel data, reply;
98        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
99        remote()->transact(START_PREVIEW, data, &reply);
100        return reply.readInt32();
101    }
102
103    // start recording mode, must call setPreviewDisplay first
104    status_t startRecording()
105    {
106        ALOGV("startRecording");
107        Parcel data, reply;
108        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
109        remote()->transact(START_RECORDING, data, &reply);
110        return reply.readInt32();
111    }
112
113    // stop preview mode
114    void stopPreview()
115    {
116        ALOGV("stopPreview");
117        Parcel data, reply;
118        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
119        remote()->transact(STOP_PREVIEW, data, &reply);
120    }
121
122    // stop recording mode
123    void stopRecording()
124    {
125        ALOGV("stopRecording");
126        Parcel data, reply;
127        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
128        remote()->transact(STOP_RECORDING, data, &reply);
129    }
130
131    void releaseRecordingFrame(const sp<IMemory>& mem)
132    {
133        ALOGV("releaseRecordingFrame");
134        Parcel data, reply;
135        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
136        data.writeStrongBinder(mem->asBinder());
137        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
138    }
139
140    status_t storeMetaDataInBuffers(bool enabled)
141    {
142        ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false");
143        Parcel data, reply;
144        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
145        data.writeInt32(enabled);
146        remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
147        return reply.readInt32();
148    }
149
150    // check preview state
151    bool previewEnabled()
152    {
153        ALOGV("previewEnabled");
154        Parcel data, reply;
155        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
156        remote()->transact(PREVIEW_ENABLED, data, &reply);
157        return reply.readInt32();
158    }
159
160    // check recording state
161    bool recordingEnabled()
162    {
163        ALOGV("recordingEnabled");
164        Parcel data, reply;
165        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
166        remote()->transact(RECORDING_ENABLED, data, &reply);
167        return reply.readInt32();
168    }
169
170    // auto focus
171    status_t autoFocus()
172    {
173        ALOGV("autoFocus");
174        Parcel data, reply;
175        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
176        remote()->transact(AUTO_FOCUS, data, &reply);
177        status_t ret = reply.readInt32();
178        return ret;
179    }
180
181    // cancel focus
182    status_t cancelAutoFocus()
183    {
184        ALOGV("cancelAutoFocus");
185        Parcel data, reply;
186        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
187        remote()->transact(CANCEL_AUTO_FOCUS, data, &reply);
188        status_t ret = reply.readInt32();
189        return ret;
190    }
191
192    // take a picture - returns an IMemory (ref-counted mmap)
193    status_t takePicture(int msgType)
194    {
195        ALOGV("takePicture: 0x%x", msgType);
196        Parcel data, reply;
197        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
198        data.writeInt32(msgType);
199        remote()->transact(TAKE_PICTURE, data, &reply);
200        status_t ret = reply.readInt32();
201        return ret;
202    }
203
204    // set preview/capture parameters - key/value pairs
205    status_t setParameters(const String8& params)
206    {
207        ALOGV("setParameters");
208        Parcel data, reply;
209        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
210        data.writeString8(params);
211        remote()->transact(SET_PARAMETERS, data, &reply);
212        return reply.readInt32();
213    }
214
215    // get preview/capture parameters - key/value pairs
216    String8 getParameters() const
217    {
218        ALOGV("getParameters");
219        Parcel data, reply;
220        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
221        remote()->transact(GET_PARAMETERS, data, &reply);
222        return reply.readString8();
223    }
224    virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
225    {
226        ALOGV("sendCommand");
227        Parcel data, reply;
228        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
229        data.writeInt32(cmd);
230        data.writeInt32(arg1);
231        data.writeInt32(arg2);
232        remote()->transact(SEND_COMMAND, data, &reply);
233        return reply.readInt32();
234    }
235    virtual status_t connect(const sp<ICameraClient>& cameraClient)
236    {
237        Parcel data, reply;
238        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
239        data.writeStrongBinder(cameraClient->asBinder());
240        remote()->transact(CONNECT, data, &reply);
241        return reply.readInt32();
242    }
243    virtual status_t lock()
244    {
245        Parcel data, reply;
246        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
247        remote()->transact(LOCK, data, &reply);
248        return reply.readInt32();
249    }
250    virtual status_t unlock()
251    {
252        Parcel data, reply;
253        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
254        remote()->transact(UNLOCK, data, &reply);
255        return reply.readInt32();
256    }
257};
258
259IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
260
261// ----------------------------------------------------------------------
262
263status_t BnCamera::onTransact(
264    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
265{
266    switch(code) {
267        case DISCONNECT: {
268            ALOGV("DISCONNECT");
269            CHECK_INTERFACE(ICamera, data, reply);
270            disconnect();
271            return NO_ERROR;
272        } break;
273        case SET_PREVIEW_TEXTURE: {
274            ALOGV("SET_PREVIEW_TEXTURE");
275            CHECK_INTERFACE(ICamera, data, reply);
276            sp<IGraphicBufferProducer> st =
277                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
278            reply->writeInt32(setPreviewTexture(st));
279            return NO_ERROR;
280        } break;
281        case SET_PREVIEW_CALLBACK_FLAG: {
282            ALOGV("SET_PREVIEW_CALLBACK_TYPE");
283            CHECK_INTERFACE(ICamera, data, reply);
284            int callback_flag = data.readInt32();
285            setPreviewCallbackFlag(callback_flag);
286            return NO_ERROR;
287        } break;
288        case START_PREVIEW: {
289            ALOGV("START_PREVIEW");
290            CHECK_INTERFACE(ICamera, data, reply);
291            reply->writeInt32(startPreview());
292            return NO_ERROR;
293        } break;
294        case START_RECORDING: {
295            ALOGV("START_RECORDING");
296            CHECK_INTERFACE(ICamera, data, reply);
297            reply->writeInt32(startRecording());
298            return NO_ERROR;
299        } break;
300        case STOP_PREVIEW: {
301            ALOGV("STOP_PREVIEW");
302            CHECK_INTERFACE(ICamera, data, reply);
303            stopPreview();
304            return NO_ERROR;
305        } break;
306        case STOP_RECORDING: {
307            ALOGV("STOP_RECORDING");
308            CHECK_INTERFACE(ICamera, data, reply);
309            stopRecording();
310            return NO_ERROR;
311        } break;
312        case RELEASE_RECORDING_FRAME: {
313            ALOGV("RELEASE_RECORDING_FRAME");
314            CHECK_INTERFACE(ICamera, data, reply);
315            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
316            releaseRecordingFrame(mem);
317            return NO_ERROR;
318        } break;
319        case STORE_META_DATA_IN_BUFFERS: {
320            ALOGV("STORE_META_DATA_IN_BUFFERS");
321            CHECK_INTERFACE(ICamera, data, reply);
322            bool enabled = data.readInt32();
323            reply->writeInt32(storeMetaDataInBuffers(enabled));
324            return NO_ERROR;
325        } break;
326        case PREVIEW_ENABLED: {
327            ALOGV("PREVIEW_ENABLED");
328            CHECK_INTERFACE(ICamera, data, reply);
329            reply->writeInt32(previewEnabled());
330            return NO_ERROR;
331        } break;
332        case RECORDING_ENABLED: {
333            ALOGV("RECORDING_ENABLED");
334            CHECK_INTERFACE(ICamera, data, reply);
335            reply->writeInt32(recordingEnabled());
336            return NO_ERROR;
337        } break;
338        case AUTO_FOCUS: {
339            ALOGV("AUTO_FOCUS");
340            CHECK_INTERFACE(ICamera, data, reply);
341            reply->writeInt32(autoFocus());
342            return NO_ERROR;
343        } break;
344        case CANCEL_AUTO_FOCUS: {
345            ALOGV("CANCEL_AUTO_FOCUS");
346            CHECK_INTERFACE(ICamera, data, reply);
347            reply->writeInt32(cancelAutoFocus());
348            return NO_ERROR;
349        } break;
350        case TAKE_PICTURE: {
351            ALOGV("TAKE_PICTURE");
352            CHECK_INTERFACE(ICamera, data, reply);
353            int msgType = data.readInt32();
354            reply->writeInt32(takePicture(msgType));
355            return NO_ERROR;
356        } break;
357        case SET_PARAMETERS: {
358            ALOGV("SET_PARAMETERS");
359            CHECK_INTERFACE(ICamera, data, reply);
360            String8 params(data.readString8());
361            reply->writeInt32(setParameters(params));
362            return NO_ERROR;
363         } break;
364        case GET_PARAMETERS: {
365            ALOGV("GET_PARAMETERS");
366            CHECK_INTERFACE(ICamera, data, reply);
367             reply->writeString8(getParameters());
368            return NO_ERROR;
369         } break;
370        case SEND_COMMAND: {
371            ALOGV("SEND_COMMAND");
372            CHECK_INTERFACE(ICamera, data, reply);
373            int command = data.readInt32();
374            int arg1 = data.readInt32();
375            int arg2 = data.readInt32();
376            reply->writeInt32(sendCommand(command, arg1, arg2));
377            return NO_ERROR;
378         } break;
379        case CONNECT: {
380            CHECK_INTERFACE(ICamera, data, reply);
381            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
382            reply->writeInt32(connect(cameraClient));
383            return NO_ERROR;
384        } break;
385        case LOCK: {
386            CHECK_INTERFACE(ICamera, data, reply);
387            reply->writeInt32(lock());
388            return NO_ERROR;
389        } break;
390        case UNLOCK: {
391            CHECK_INTERFACE(ICamera, data, reply);
392            reply->writeInt32(unlock());
393            return NO_ERROR;
394        } break;
395        default:
396            return BBinder::onTransact(code, data, reply, flags);
397    }
398}
399
400// ----------------------------------------------------------------------------
401
402}; // namespace android
403