1/*
2**
3** Copyright (C) 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 "Camera"
20#include <utils/Log.h>
21#include <utils/threads.h>
22#include <utils/String16.h>
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
25#include <binder/IMemory.h>
26
27#include <Camera.h>
28#include <ICameraRecordingProxyListener.h>
29#include <android/hardware/ICameraService.h>
30#include <android/hardware/ICamera.h>
31
32#include <gui/IGraphicBufferProducer.h>
33#include <gui/Surface.h>
34
35namespace android {
36
37Camera::Camera(int cameraId)
38    : CameraBase(cameraId)
39{
40}
41
42CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
43        &::android::hardware::ICameraService::connect;
44
45// construct a camera client from an existing camera remote
46sp<Camera> Camera::create(const sp<::android::hardware::ICamera>& camera)
47{
48     ALOGV("create");
49     if (camera == 0) {
50         ALOGE("camera remote is a NULL pointer");
51         return 0;
52     }
53
54    sp<Camera> c = new Camera(-1);
55    if (camera->connect(c) == NO_ERROR) {
56        c->mStatus = NO_ERROR;
57        c->mCamera = camera;
58        IInterface::asBinder(camera)->linkToDeath(c);
59        return c;
60    }
61    return 0;
62}
63
64Camera::~Camera()
65{
66    // We don't need to call disconnect() here because if the CameraService
67    // thinks we are the owner of the hardware, it will hold a (strong)
68    // reference to us, and we can't possibly be here. We also don't want to
69    // call disconnect() here if we are in the same process as mediaserver,
70    // because we may be invoked by CameraService::Client::connect() and will
71    // deadlock if we call any method of ICamera here.
72}
73
74sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
75        int clientUid, int clientPid)
76{
77    return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
78}
79
80status_t Camera::connectLegacy(int cameraId, int halVersion,
81        const String16& clientPackageName,
82        int clientUid,
83        sp<Camera>& camera)
84{
85    ALOGV("%s: connect legacy camera device", __FUNCTION__);
86    sp<Camera> c = new Camera(cameraId);
87    sp<::android::hardware::ICameraClient> cl = c;
88    status_t status = NO_ERROR;
89    const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService();
90
91    binder::Status ret;
92    if (cs != nullptr) {
93        ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
94                clientUid, /*out*/&(c->mCamera));
95    }
96    if (ret.isOk() && c->mCamera != nullptr) {
97        IInterface::asBinder(c->mCamera)->linkToDeath(c);
98        c->mStatus = NO_ERROR;
99        camera = c;
100    } else {
101        switch(ret.serviceSpecificErrorCode()) {
102            case hardware::ICameraService::ERROR_DISCONNECTED:
103                status = -ENODEV;
104                break;
105            case hardware::ICameraService::ERROR_CAMERA_IN_USE:
106                status = -EBUSY;
107                break;
108            case hardware::ICameraService::ERROR_INVALID_OPERATION:
109                status = -EINVAL;
110                break;
111            case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
112                status = -EUSERS;
113                break;
114            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
115                status = BAD_VALUE;
116                break;
117            case hardware::ICameraService::ERROR_DEPRECATED_HAL:
118                status = -EOPNOTSUPP;
119                break;
120            case hardware::ICameraService::ERROR_DISABLED:
121                status = -EACCES;
122                break;
123            case hardware::ICameraService::ERROR_PERMISSION_DENIED:
124                status = PERMISSION_DENIED;
125                break;
126            default:
127                status = -EINVAL;
128                ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
129                        (cs != nullptr) ? "Service not available" : ret.toString8().string());
130                break;
131        }
132        c.clear();
133    }
134    return status;
135}
136
137status_t Camera::reconnect()
138{
139    ALOGV("reconnect");
140    sp <::android::hardware::ICamera> c = mCamera;
141    if (c == 0) return NO_INIT;
142    return c->connect(this);
143}
144
145status_t Camera::lock()
146{
147    sp <::android::hardware::ICamera> c = mCamera;
148    if (c == 0) return NO_INIT;
149    return c->lock();
150}
151
152status_t Camera::unlock()
153{
154    sp <::android::hardware::ICamera> c = mCamera;
155    if (c == 0) return NO_INIT;
156    return c->unlock();
157}
158
159// pass the buffered IGraphicBufferProducer to the camera service
160status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
161{
162    ALOGV("setPreviewTarget(%p)", bufferProducer.get());
163    sp <::android::hardware::ICamera> c = mCamera;
164    if (c == 0) return NO_INIT;
165    ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
166    return c->setPreviewTarget(bufferProducer);
167}
168
169status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer)
170{
171    ALOGV("setVideoTarget(%p)", bufferProducer.get());
172    sp <::android::hardware::ICamera> c = mCamera;
173    if (c == 0) return NO_INIT;
174    ALOGD_IF(bufferProducer == 0, "app passed NULL video surface");
175    return c->setVideoTarget(bufferProducer);
176}
177
178// start preview mode
179status_t Camera::startPreview()
180{
181    ALOGV("startPreview");
182    sp <::android::hardware::ICamera> c = mCamera;
183    if (c == 0) return NO_INIT;
184    return c->startPreview();
185}
186
187status_t Camera::setVideoBufferMode(int32_t videoBufferMode)
188{
189    ALOGV("setVideoBufferMode: %d", videoBufferMode);
190    sp <::android::hardware::ICamera> c = mCamera;
191    if (c == 0) return NO_INIT;
192    return c->setVideoBufferMode(videoBufferMode);
193}
194
195// start recording mode, must call setPreviewTarget first
196status_t Camera::startRecording()
197{
198    ALOGV("startRecording");
199    sp <::android::hardware::ICamera> c = mCamera;
200    if (c == 0) return NO_INIT;
201    return c->startRecording();
202}
203
204// stop preview mode
205void Camera::stopPreview()
206{
207    ALOGV("stopPreview");
208    sp <::android::hardware::ICamera> c = mCamera;
209    if (c == 0) return;
210    c->stopPreview();
211}
212
213// stop recording mode
214void Camera::stopRecording()
215{
216    ALOGV("stopRecording");
217    {
218        Mutex::Autolock _l(mLock);
219        mRecordingProxyListener.clear();
220    }
221    sp <::android::hardware::ICamera> c = mCamera;
222    if (c == 0) return;
223    c->stopRecording();
224}
225
226// release a recording frame
227void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
228{
229    ALOGV("releaseRecordingFrame");
230    sp <::android::hardware::ICamera> c = mCamera;
231    if (c == 0) return;
232    c->releaseRecordingFrame(mem);
233}
234
235void Camera::releaseRecordingFrameHandle(native_handle_t* handle)
236{
237    ALOGV("releaseRecordingFrameHandle");
238    sp <::android::hardware::ICamera> c = mCamera;
239    if (c == 0) return;
240    c->releaseRecordingFrameHandle(handle);
241}
242
243// get preview state
244bool Camera::previewEnabled()
245{
246    ALOGV("previewEnabled");
247    sp <::android::hardware::ICamera> c = mCamera;
248    if (c == 0) return false;
249    return c->previewEnabled();
250}
251
252// get recording state
253bool Camera::recordingEnabled()
254{
255    ALOGV("recordingEnabled");
256    sp <::android::hardware::ICamera> c = mCamera;
257    if (c == 0) return false;
258    return c->recordingEnabled();
259}
260
261status_t Camera::autoFocus()
262{
263    ALOGV("autoFocus");
264    sp <::android::hardware::ICamera> c = mCamera;
265    if (c == 0) return NO_INIT;
266    return c->autoFocus();
267}
268
269status_t Camera::cancelAutoFocus()
270{
271    ALOGV("cancelAutoFocus");
272    sp <::android::hardware::ICamera> c = mCamera;
273    if (c == 0) return NO_INIT;
274    return c->cancelAutoFocus();
275}
276
277// take a picture
278status_t Camera::takePicture(int msgType)
279{
280    ALOGV("takePicture: 0x%x", msgType);
281    sp <::android::hardware::ICamera> c = mCamera;
282    if (c == 0) return NO_INIT;
283    return c->takePicture(msgType);
284}
285
286// set preview/capture parameters - key/value pairs
287status_t Camera::setParameters(const String8& params)
288{
289    ALOGV("setParameters");
290    sp <::android::hardware::ICamera> c = mCamera;
291    if (c == 0) return NO_INIT;
292    return c->setParameters(params);
293}
294
295// get preview/capture parameters - key/value pairs
296String8 Camera::getParameters() const
297{
298    ALOGV("getParameters");
299    String8 params;
300    sp <::android::hardware::ICamera> c = mCamera;
301    if (c != 0) params = mCamera->getParameters();
302    return params;
303}
304
305// send command to camera driver
306status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
307{
308    ALOGV("sendCommand");
309    sp <::android::hardware::ICamera> c = mCamera;
310    if (c == 0) return NO_INIT;
311    return c->sendCommand(cmd, arg1, arg2);
312}
313
314void Camera::setListener(const sp<CameraListener>& listener)
315{
316    Mutex::Autolock _l(mLock);
317    mListener = listener;
318}
319
320void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
321{
322    Mutex::Autolock _l(mLock);
323    mRecordingProxyListener = listener;
324}
325
326void Camera::setPreviewCallbackFlags(int flag)
327{
328    ALOGV("setPreviewCallbackFlags");
329    sp <::android::hardware::ICamera> c = mCamera;
330    if (c == 0) return;
331    mCamera->setPreviewCallbackFlag(flag);
332}
333
334status_t Camera::setPreviewCallbackTarget(
335        const sp<IGraphicBufferProducer>& callbackProducer)
336{
337    sp <::android::hardware::ICamera> c = mCamera;
338    if (c == 0) return NO_INIT;
339    return c->setPreviewCallbackTarget(callbackProducer);
340}
341
342// callback from camera service
343void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
344{
345    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
346}
347
348// callback from camera service when frame or image is ready
349void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
350                          camera_frame_metadata_t *metadata)
351{
352    sp<CameraListener> listener;
353    {
354        Mutex::Autolock _l(mLock);
355        listener = mListener;
356    }
357    if (listener != NULL) {
358        listener->postData(msgType, dataPtr, metadata);
359    }
360}
361
362// callback from camera service when timestamped frame is ready
363void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
364{
365    // If recording proxy listener is registered, forward the frame and return.
366    // The other listener (mListener) is ignored because the receiver needs to
367    // call releaseRecordingFrame.
368    sp<ICameraRecordingProxyListener> proxylistener;
369    {
370        Mutex::Autolock _l(mLock);
371        proxylistener = mRecordingProxyListener;
372    }
373    if (proxylistener != NULL) {
374        proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
375        return;
376    }
377
378    sp<CameraListener> listener;
379    {
380        Mutex::Autolock _l(mLock);
381        listener = mListener;
382    }
383
384    if (listener != NULL) {
385        listener->postDataTimestamp(timestamp, msgType, dataPtr);
386    } else {
387        ALOGW("No listener was set. Drop a recording frame.");
388        releaseRecordingFrame(dataPtr);
389    }
390}
391
392void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle)
393{
394    // If recording proxy listener is registered, forward the frame and return.
395    // The other listener (mListener) is ignored because the receiver needs to
396    // call releaseRecordingFrameHandle.
397    sp<ICameraRecordingProxyListener> proxylistener;
398    {
399        Mutex::Autolock _l(mLock);
400        proxylistener = mRecordingProxyListener;
401    }
402    if (proxylistener != NULL) {
403        proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle);
404        return;
405    }
406
407    sp<CameraListener> listener;
408    {
409        Mutex::Autolock _l(mLock);
410        listener = mListener;
411    }
412
413    if (listener != NULL) {
414        listener->postRecordingFrameHandleTimestamp(timestamp, handle);
415    } else {
416        ALOGW("No listener was set. Drop a recording frame.");
417        releaseRecordingFrameHandle(handle);
418    }
419}
420
421sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
422    ALOGV("getProxy");
423    return new RecordingProxy(this);
424}
425
426status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
427{
428    ALOGV("RecordingProxy::startRecording");
429    mCamera->setRecordingProxyListener(listener);
430    mCamera->reconnect();
431    return mCamera->startRecording();
432}
433
434void Camera::RecordingProxy::stopRecording()
435{
436    ALOGV("RecordingProxy::stopRecording");
437    mCamera->stopRecording();
438}
439
440void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
441{
442    ALOGV("RecordingProxy::releaseRecordingFrame");
443    mCamera->releaseRecordingFrame(mem);
444}
445
446void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) {
447    ALOGV("RecordingProxy::releaseRecordingFrameHandle");
448    mCamera->releaseRecordingFrameHandle(handle);
449}
450
451Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
452{
453    mCamera = camera;
454}
455
456}; // namespace android
457