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
243void Camera::releaseRecordingFrameHandleBatch(
244        const std::vector<native_handle_t*> handles) {
245    ALOGV("releaseRecordingFrameHandleBatch");
246    sp <::android::hardware::ICamera> c = mCamera;
247    if (c == 0) return;
248    c->releaseRecordingFrameHandleBatch(handles);
249}
250
251// get preview state
252bool Camera::previewEnabled()
253{
254    ALOGV("previewEnabled");
255    sp <::android::hardware::ICamera> c = mCamera;
256    if (c == 0) return false;
257    return c->previewEnabled();
258}
259
260// get recording state
261bool Camera::recordingEnabled()
262{
263    ALOGV("recordingEnabled");
264    sp <::android::hardware::ICamera> c = mCamera;
265    if (c == 0) return false;
266    return c->recordingEnabled();
267}
268
269status_t Camera::autoFocus()
270{
271    ALOGV("autoFocus");
272    sp <::android::hardware::ICamera> c = mCamera;
273    if (c == 0) return NO_INIT;
274    return c->autoFocus();
275}
276
277status_t Camera::cancelAutoFocus()
278{
279    ALOGV("cancelAutoFocus");
280    sp <::android::hardware::ICamera> c = mCamera;
281    if (c == 0) return NO_INIT;
282    return c->cancelAutoFocus();
283}
284
285// take a picture
286status_t Camera::takePicture(int msgType)
287{
288    ALOGV("takePicture: 0x%x", msgType);
289    sp <::android::hardware::ICamera> c = mCamera;
290    if (c == 0) return NO_INIT;
291    return c->takePicture(msgType);
292}
293
294// set preview/capture parameters - key/value pairs
295status_t Camera::setParameters(const String8& params)
296{
297    ALOGV("setParameters");
298    sp <::android::hardware::ICamera> c = mCamera;
299    if (c == 0) return NO_INIT;
300    return c->setParameters(params);
301}
302
303// get preview/capture parameters - key/value pairs
304String8 Camera::getParameters() const
305{
306    ALOGV("getParameters");
307    String8 params;
308    sp <::android::hardware::ICamera> c = mCamera;
309    if (c != 0) params = mCamera->getParameters();
310    return params;
311}
312
313// send command to camera driver
314status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
315{
316    ALOGV("sendCommand");
317    sp <::android::hardware::ICamera> c = mCamera;
318    if (c == 0) return NO_INIT;
319    return c->sendCommand(cmd, arg1, arg2);
320}
321
322void Camera::setListener(const sp<CameraListener>& listener)
323{
324    Mutex::Autolock _l(mLock);
325    mListener = listener;
326}
327
328void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
329{
330    Mutex::Autolock _l(mLock);
331    mRecordingProxyListener = listener;
332}
333
334void Camera::setPreviewCallbackFlags(int flag)
335{
336    ALOGV("setPreviewCallbackFlags");
337    sp <::android::hardware::ICamera> c = mCamera;
338    if (c == 0) return;
339    mCamera->setPreviewCallbackFlag(flag);
340}
341
342status_t Camera::setPreviewCallbackTarget(
343        const sp<IGraphicBufferProducer>& callbackProducer)
344{
345    sp <::android::hardware::ICamera> c = mCamera;
346    if (c == 0) return NO_INIT;
347    return c->setPreviewCallbackTarget(callbackProducer);
348}
349
350// callback from camera service
351void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
352{
353    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
354}
355
356// callback from camera service when frame or image is ready
357void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
358                          camera_frame_metadata_t *metadata)
359{
360    sp<CameraListener> listener;
361    {
362        Mutex::Autolock _l(mLock);
363        listener = mListener;
364    }
365    if (listener != NULL) {
366        listener->postData(msgType, dataPtr, metadata);
367    }
368}
369
370// callback from camera service when timestamped frame is ready
371void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
372{
373    // If recording proxy listener is registered, forward the frame and return.
374    // The other listener (mListener) is ignored because the receiver needs to
375    // call releaseRecordingFrame.
376    sp<ICameraRecordingProxyListener> proxylistener;
377    {
378        Mutex::Autolock _l(mLock);
379        proxylistener = mRecordingProxyListener;
380    }
381    if (proxylistener != NULL) {
382        proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
383        return;
384    }
385
386    sp<CameraListener> listener;
387    {
388        Mutex::Autolock _l(mLock);
389        listener = mListener;
390    }
391
392    if (listener != NULL) {
393        listener->postDataTimestamp(timestamp, msgType, dataPtr);
394    } else {
395        ALOGW("No listener was set. Drop a recording frame.");
396        releaseRecordingFrame(dataPtr);
397    }
398}
399
400void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle)
401{
402    // If recording proxy listener is registered, forward the frame and return.
403    // The other listener (mListener) is ignored because the receiver needs to
404    // call releaseRecordingFrameHandle.
405    sp<ICameraRecordingProxyListener> proxylistener;
406    {
407        Mutex::Autolock _l(mLock);
408        proxylistener = mRecordingProxyListener;
409    }
410    if (proxylistener != NULL) {
411        proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle);
412        return;
413    }
414
415    sp<CameraListener> listener;
416    {
417        Mutex::Autolock _l(mLock);
418        listener = mListener;
419    }
420
421    if (listener != NULL) {
422        listener->postRecordingFrameHandleTimestamp(timestamp, handle);
423    } else {
424        ALOGW("No listener was set. Drop a recording frame.");
425        releaseRecordingFrameHandle(handle);
426    }
427}
428
429void Camera::recordingFrameHandleCallbackTimestampBatch(
430        const std::vector<nsecs_t>& timestamps,
431        const std::vector<native_handle_t*>& handles)
432{
433    // If recording proxy listener is registered, forward the frame and return.
434    // The other listener (mListener) is ignored because the receiver needs to
435    // call releaseRecordingFrameHandle.
436    sp<ICameraRecordingProxyListener> proxylistener;
437    {
438        Mutex::Autolock _l(mLock);
439        proxylistener = mRecordingProxyListener;
440    }
441    if (proxylistener != NULL) {
442        proxylistener->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
443        return;
444    }
445
446    sp<CameraListener> listener;
447    {
448        Mutex::Autolock _l(mLock);
449        listener = mListener;
450    }
451
452    if (listener != NULL) {
453        listener->postRecordingFrameHandleTimestampBatch(timestamps, handles);
454    } else {
455        ALOGW("No listener was set. Drop a batch of recording frames.");
456        releaseRecordingFrameHandleBatch(handles);
457    }
458}
459
460sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
461    ALOGV("getProxy");
462    return new RecordingProxy(this);
463}
464
465status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
466{
467    ALOGV("RecordingProxy::startRecording");
468    mCamera->setRecordingProxyListener(listener);
469    mCamera->reconnect();
470    return mCamera->startRecording();
471}
472
473void Camera::RecordingProxy::stopRecording()
474{
475    ALOGV("RecordingProxy::stopRecording");
476    mCamera->stopRecording();
477}
478
479void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
480{
481    ALOGV("RecordingProxy::releaseRecordingFrame");
482    mCamera->releaseRecordingFrame(mem);
483}
484
485void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) {
486    ALOGV("RecordingProxy::releaseRecordingFrameHandle");
487    mCamera->releaseRecordingFrameHandle(handle);
488}
489
490void Camera::RecordingProxy::releaseRecordingFrameHandleBatch(
491        const std::vector<native_handle_t*>& handles) {
492    ALOGV("RecordingProxy::releaseRecordingFrameHandleBatch");
493    mCamera->releaseRecordingFrameHandleBatch(handles);
494}
495
496Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
497{
498    mCamera = camera;
499}
500
501}; // namespace android
502