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/CameraUtils.h>
25#include <android/hardware/ICamera.h>
26#include <android/hardware/ICameraClient.h>
27#include <gui/IGraphicBufferProducer.h>
28#include <gui/Surface.h>
29#include <media/hardware/HardwareAPI.h>
30
31namespace android {
32namespace hardware {
33
34enum {
35    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
36    SET_PREVIEW_TARGET,
37    SET_PREVIEW_CALLBACK_FLAG,
38    SET_PREVIEW_CALLBACK_TARGET,
39    START_PREVIEW,
40    STOP_PREVIEW,
41    AUTO_FOCUS,
42    CANCEL_AUTO_FOCUS,
43    TAKE_PICTURE,
44    SET_PARAMETERS,
45    GET_PARAMETERS,
46    SEND_COMMAND,
47    CONNECT,
48    LOCK,
49    UNLOCK,
50    PREVIEW_ENABLED,
51    START_RECORDING,
52    STOP_RECORDING,
53    RECORDING_ENABLED,
54    RELEASE_RECORDING_FRAME,
55    SET_VIDEO_BUFFER_MODE,
56    SET_VIDEO_BUFFER_TARGET,
57    RELEASE_RECORDING_FRAME_HANDLE,
58    RELEASE_RECORDING_FRAME_HANDLE_BATCH,
59};
60
61class BpCamera: public BpInterface<ICamera>
62{
63public:
64    explicit BpCamera(const sp<IBinder>& impl)
65        : BpInterface<ICamera>(impl)
66    {
67    }
68
69    // disconnect from camera service
70    binder::Status disconnect()
71    {
72        ALOGV("disconnect");
73        Parcel data, reply;
74        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
75        remote()->transact(DISCONNECT, data, &reply);
76        reply.readExceptionCode();
77        return binder::Status::ok();
78    }
79
80    // pass the buffered IGraphicBufferProducer to the camera service
81    status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
82    {
83        ALOGV("setPreviewTarget");
84        Parcel data, reply;
85        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
86        sp<IBinder> b(IInterface::asBinder(bufferProducer));
87        data.writeStrongBinder(b);
88        remote()->transact(SET_PREVIEW_TARGET, data, &reply);
89        return reply.readInt32();
90    }
91
92    // set the preview callback flag to affect how the received frames from
93    // preview are handled. See Camera.h for details.
94    void setPreviewCallbackFlag(int flag)
95    {
96        ALOGV("setPreviewCallbackFlag(%d)", flag);
97        Parcel data, reply;
98        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
99        data.writeInt32(flag);
100        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
101    }
102
103    status_t setPreviewCallbackTarget(
104            const sp<IGraphicBufferProducer>& callbackProducer)
105    {
106        ALOGV("setPreviewCallbackTarget");
107        Parcel data, reply;
108        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
109        sp<IBinder> b(IInterface::asBinder(callbackProducer));
110        data.writeStrongBinder(b);
111        remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply);
112        return reply.readInt32();
113    }
114
115    // start preview mode, must call setPreviewTarget first
116    status_t startPreview()
117    {
118        ALOGV("startPreview");
119        Parcel data, reply;
120        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
121        remote()->transact(START_PREVIEW, data, &reply);
122        return reply.readInt32();
123    }
124
125    // start recording mode, must call setPreviewTarget first
126    status_t startRecording()
127    {
128        ALOGV("startRecording");
129        Parcel data, reply;
130        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
131        remote()->transact(START_RECORDING, data, &reply);
132        return reply.readInt32();
133    }
134
135    // stop preview mode
136    void stopPreview()
137    {
138        ALOGV("stopPreview");
139        Parcel data, reply;
140        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
141        remote()->transact(STOP_PREVIEW, data, &reply);
142    }
143
144    // stop recording mode
145    void stopRecording()
146    {
147        ALOGV("stopRecording");
148        Parcel data, reply;
149        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
150        remote()->transact(STOP_RECORDING, data, &reply);
151    }
152
153    void releaseRecordingFrame(const sp<IMemory>& mem)
154    {
155        ALOGV("releaseRecordingFrame");
156        Parcel data, reply;
157        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
158        data.writeStrongBinder(IInterface::asBinder(mem));
159
160        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
161    }
162
163    void releaseRecordingFrameHandle(native_handle_t *handle) {
164        ALOGV("releaseRecordingFrameHandle");
165        Parcel data, reply;
166        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
167        data.writeNativeHandle(handle);
168
169        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE, data, &reply);
170
171        // Close the native handle because camera received a dup copy.
172        native_handle_close(handle);
173        native_handle_delete(handle);
174    }
175
176    void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
177        ALOGV("releaseRecordingFrameHandleBatch");
178        Parcel data, reply;
179        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
180        uint32_t n = handles.size();
181        data.writeUint32(n);
182        for (auto& handle : handles) {
183            data.writeNativeHandle(handle);
184        }
185        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE_BATCH, data, &reply);
186
187        // Close the native handle because camera received a dup copy.
188        for (auto& handle : handles) {
189            native_handle_close(handle);
190            native_handle_delete(handle);
191        }
192    }
193
194    status_t setVideoBufferMode(int32_t videoBufferMode)
195    {
196        ALOGV("setVideoBufferMode: %d", videoBufferMode);
197        Parcel data, reply;
198        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
199        data.writeInt32(videoBufferMode);
200        remote()->transact(SET_VIDEO_BUFFER_MODE, data, &reply);
201        return reply.readInt32();
202    }
203
204    // check preview state
205    bool previewEnabled()
206    {
207        ALOGV("previewEnabled");
208        Parcel data, reply;
209        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
210        remote()->transact(PREVIEW_ENABLED, data, &reply);
211        return reply.readInt32();
212    }
213
214    // check recording state
215    bool recordingEnabled()
216    {
217        ALOGV("recordingEnabled");
218        Parcel data, reply;
219        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
220        remote()->transact(RECORDING_ENABLED, data, &reply);
221        return reply.readInt32();
222    }
223
224    // auto focus
225    status_t autoFocus()
226    {
227        ALOGV("autoFocus");
228        Parcel data, reply;
229        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
230        remote()->transact(AUTO_FOCUS, data, &reply);
231        status_t ret = reply.readInt32();
232        return ret;
233    }
234
235    // cancel focus
236    status_t cancelAutoFocus()
237    {
238        ALOGV("cancelAutoFocus");
239        Parcel data, reply;
240        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
241        remote()->transact(CANCEL_AUTO_FOCUS, data, &reply);
242        status_t ret = reply.readInt32();
243        return ret;
244    }
245
246    // take a picture - returns an IMemory (ref-counted mmap)
247    status_t takePicture(int msgType)
248    {
249        ALOGV("takePicture: 0x%x", msgType);
250        Parcel data, reply;
251        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
252        data.writeInt32(msgType);
253        remote()->transact(TAKE_PICTURE, data, &reply);
254        status_t ret = reply.readInt32();
255        return ret;
256    }
257
258    // set preview/capture parameters - key/value pairs
259    status_t setParameters(const String8& params)
260    {
261        ALOGV("setParameters");
262        Parcel data, reply;
263        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
264        data.writeString8(params);
265        remote()->transact(SET_PARAMETERS, data, &reply);
266        return reply.readInt32();
267    }
268
269    // get preview/capture parameters - key/value pairs
270    String8 getParameters() const
271    {
272        ALOGV("getParameters");
273        Parcel data, reply;
274        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
275        remote()->transact(GET_PARAMETERS, data, &reply);
276        return reply.readString8();
277    }
278    virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
279    {
280        ALOGV("sendCommand");
281        Parcel data, reply;
282        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
283        data.writeInt32(cmd);
284        data.writeInt32(arg1);
285        data.writeInt32(arg2);
286        remote()->transact(SEND_COMMAND, data, &reply);
287        return reply.readInt32();
288    }
289    virtual status_t connect(const sp<ICameraClient>& cameraClient)
290    {
291        Parcel data, reply;
292        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
293        data.writeStrongBinder(IInterface::asBinder(cameraClient));
294        remote()->transact(CONNECT, data, &reply);
295        return reply.readInt32();
296    }
297    virtual status_t lock()
298    {
299        Parcel data, reply;
300        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
301        remote()->transact(LOCK, data, &reply);
302        return reply.readInt32();
303    }
304    virtual status_t unlock()
305    {
306        Parcel data, reply;
307        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
308        remote()->transact(UNLOCK, data, &reply);
309        return reply.readInt32();
310    }
311
312    status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer)
313    {
314        ALOGV("setVideoTarget");
315        Parcel data, reply;
316        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
317        sp<IBinder> b(IInterface::asBinder(bufferProducer));
318        data.writeStrongBinder(b);
319        remote()->transact(SET_VIDEO_BUFFER_TARGET, data, &reply);
320        return reply.readInt32();
321    }
322};
323
324IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
325
326// ----------------------------------------------------------------------
327
328status_t BnCamera::onTransact(
329    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
330{
331    switch(code) {
332        case DISCONNECT: {
333            ALOGV("DISCONNECT");
334            CHECK_INTERFACE(ICamera, data, reply);
335            disconnect();
336            reply->writeNoException();
337            return NO_ERROR;
338        } break;
339        case SET_PREVIEW_TARGET: {
340            ALOGV("SET_PREVIEW_TARGET");
341            CHECK_INTERFACE(ICamera, data, reply);
342            sp<IGraphicBufferProducer> st =
343                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
344            reply->writeInt32(setPreviewTarget(st));
345            return NO_ERROR;
346        } break;
347        case SET_PREVIEW_CALLBACK_FLAG: {
348            ALOGV("SET_PREVIEW_CALLBACK_TYPE");
349            CHECK_INTERFACE(ICamera, data, reply);
350            int callback_flag = data.readInt32();
351            setPreviewCallbackFlag(callback_flag);
352            return NO_ERROR;
353        } break;
354        case SET_PREVIEW_CALLBACK_TARGET: {
355            ALOGV("SET_PREVIEW_CALLBACK_TARGET");
356            CHECK_INTERFACE(ICamera, data, reply);
357            sp<IGraphicBufferProducer> cp =
358                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
359            reply->writeInt32(setPreviewCallbackTarget(cp));
360            return NO_ERROR;
361        }
362        case START_PREVIEW: {
363            ALOGV("START_PREVIEW");
364            CHECK_INTERFACE(ICamera, data, reply);
365            reply->writeInt32(startPreview());
366            return NO_ERROR;
367        } break;
368        case START_RECORDING: {
369            ALOGV("START_RECORDING");
370            CHECK_INTERFACE(ICamera, data, reply);
371            reply->writeInt32(startRecording());
372            return NO_ERROR;
373        } break;
374        case STOP_PREVIEW: {
375            ALOGV("STOP_PREVIEW");
376            CHECK_INTERFACE(ICamera, data, reply);
377            stopPreview();
378            return NO_ERROR;
379        } break;
380        case STOP_RECORDING: {
381            ALOGV("STOP_RECORDING");
382            CHECK_INTERFACE(ICamera, data, reply);
383            stopRecording();
384            return NO_ERROR;
385        } break;
386        case RELEASE_RECORDING_FRAME: {
387            ALOGV("RELEASE_RECORDING_FRAME");
388            CHECK_INTERFACE(ICamera, data, reply);
389            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
390            releaseRecordingFrame(mem);
391            return NO_ERROR;
392        } break;
393        case RELEASE_RECORDING_FRAME_HANDLE: {
394            ALOGV("RELEASE_RECORDING_FRAME_HANDLE");
395            CHECK_INTERFACE(ICamera, data, reply);
396            // releaseRecordingFrameHandle will be responsble to close the native handle.
397            releaseRecordingFrameHandle(data.readNativeHandle());
398            return NO_ERROR;
399        } break;
400        case RELEASE_RECORDING_FRAME_HANDLE_BATCH: {
401            ALOGV("RELEASE_RECORDING_FRAME_HANDLE_BATCH");
402            CHECK_INTERFACE(ICamera, data, reply);
403            // releaseRecordingFrameHandle will be responsble to close the native handle.
404            uint32_t n = data.readUint32();
405            std::vector<native_handle_t*> handles;
406            handles.reserve(n);
407            for (uint32_t i = 0; i < n; i++) {
408                handles.push_back(data.readNativeHandle());
409            }
410            releaseRecordingFrameHandleBatch(handles);
411            return NO_ERROR;
412        } break;
413        case SET_VIDEO_BUFFER_MODE: {
414            ALOGV("SET_VIDEO_BUFFER_MODE");
415            CHECK_INTERFACE(ICamera, data, reply);
416            int32_t mode = data.readInt32();
417            reply->writeInt32(setVideoBufferMode(mode));
418            return NO_ERROR;
419        } break;
420        case PREVIEW_ENABLED: {
421            ALOGV("PREVIEW_ENABLED");
422            CHECK_INTERFACE(ICamera, data, reply);
423            reply->writeInt32(previewEnabled());
424            return NO_ERROR;
425        } break;
426        case RECORDING_ENABLED: {
427            ALOGV("RECORDING_ENABLED");
428            CHECK_INTERFACE(ICamera, data, reply);
429            reply->writeInt32(recordingEnabled());
430            return NO_ERROR;
431        } break;
432        case AUTO_FOCUS: {
433            ALOGV("AUTO_FOCUS");
434            CHECK_INTERFACE(ICamera, data, reply);
435            reply->writeInt32(autoFocus());
436            return NO_ERROR;
437        } break;
438        case CANCEL_AUTO_FOCUS: {
439            ALOGV("CANCEL_AUTO_FOCUS");
440            CHECK_INTERFACE(ICamera, data, reply);
441            reply->writeInt32(cancelAutoFocus());
442            return NO_ERROR;
443        } break;
444        case TAKE_PICTURE: {
445            ALOGV("TAKE_PICTURE");
446            CHECK_INTERFACE(ICamera, data, reply);
447            int msgType = data.readInt32();
448            reply->writeInt32(takePicture(msgType));
449            return NO_ERROR;
450        } break;
451        case SET_PARAMETERS: {
452            ALOGV("SET_PARAMETERS");
453            CHECK_INTERFACE(ICamera, data, reply);
454            String8 params(data.readString8());
455            reply->writeInt32(setParameters(params));
456            return NO_ERROR;
457         } break;
458        case GET_PARAMETERS: {
459            ALOGV("GET_PARAMETERS");
460            CHECK_INTERFACE(ICamera, data, reply);
461             reply->writeString8(getParameters());
462            return NO_ERROR;
463         } break;
464        case SEND_COMMAND: {
465            ALOGV("SEND_COMMAND");
466            CHECK_INTERFACE(ICamera, data, reply);
467            int command = data.readInt32();
468            int arg1 = data.readInt32();
469            int arg2 = data.readInt32();
470            reply->writeInt32(sendCommand(command, arg1, arg2));
471            return NO_ERROR;
472         } break;
473        case CONNECT: {
474            CHECK_INTERFACE(ICamera, data, reply);
475            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
476            reply->writeInt32(connect(cameraClient));
477            return NO_ERROR;
478        } break;
479        case LOCK: {
480            CHECK_INTERFACE(ICamera, data, reply);
481            reply->writeInt32(lock());
482            return NO_ERROR;
483        } break;
484        case UNLOCK: {
485            CHECK_INTERFACE(ICamera, data, reply);
486            reply->writeInt32(unlock());
487            return NO_ERROR;
488        } break;
489        case SET_VIDEO_BUFFER_TARGET: {
490            ALOGV("SET_VIDEO_BUFFER_TARGET");
491            CHECK_INTERFACE(ICamera, data, reply);
492            sp<IGraphicBufferProducer> st =
493                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
494            reply->writeInt32(setVideoTarget(st));
495            return NO_ERROR;
496        } break;
497        default:
498            return BBinder::onTransact(code, data, reply, flags);
499    }
500}
501
502// ----------------------------------------------------------------------------
503
504} // namespace hardware
505} // namespace android
506