Camera.cpp revision 32fa6d0e65dbf956e253a1006e9419dce2fe75c9
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/Camera.h>
28#include <camera/ICameraRecordingProxyListener.h>
29#include <camera/ICameraService.h>
30#include <camera/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        &ICameraService::connect;
44
45// construct a camera client from an existing camera remote
46sp<Camera> Camera::create(const sp<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& opPackageName, int clientUid)
75{
76    return CameraBaseT::connect(cameraId, opPackageName, clientUid);
77}
78
79status_t Camera::connectLegacy(int cameraId, int halVersion,
80        const String16& opPackageName,
81        int clientUid,
82        sp<Camera>& camera)
83{
84    ALOGV("%s: connect legacy camera device", __FUNCTION__);
85    sp<Camera> c = new Camera(cameraId);
86    sp<ICameraClient> cl = c;
87    status_t status = NO_ERROR;
88    const sp<ICameraService>& cs = CameraBaseT::getCameraService();
89
90    if (cs != 0) {
91        status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName,
92                                        clientUid, /*out*/c->mCamera);
93    }
94    if (status == OK && c->mCamera != 0) {
95        IInterface::asBinder(c->mCamera)->linkToDeath(c);
96        c->mStatus = NO_ERROR;
97        camera = c;
98    } else {
99        ALOGW("An error occurred while connecting to camera: %d", cameraId);
100        c.clear();
101    }
102    return status;
103}
104
105status_t Camera::reconnect()
106{
107    ALOGV("reconnect");
108    sp <ICamera> c = mCamera;
109    if (c == 0) return NO_INIT;
110    return c->connect(this);
111}
112
113status_t Camera::lock()
114{
115    sp <ICamera> c = mCamera;
116    if (c == 0) return NO_INIT;
117    return c->lock();
118}
119
120status_t Camera::unlock()
121{
122    sp <ICamera> c = mCamera;
123    if (c == 0) return NO_INIT;
124    return c->unlock();
125}
126
127// pass the buffered IGraphicBufferProducer to the camera service
128status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
129{
130    ALOGV("setPreviewTarget(%p)", bufferProducer.get());
131    sp <ICamera> c = mCamera;
132    if (c == 0) return NO_INIT;
133    ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
134    return c->setPreviewTarget(bufferProducer);
135}
136
137// start preview mode
138status_t Camera::startPreview()
139{
140    ALOGV("startPreview");
141    sp <ICamera> c = mCamera;
142    if (c == 0) return NO_INIT;
143    return c->startPreview();
144}
145
146status_t Camera::storeMetaDataInBuffers(bool enabled)
147{
148    ALOGV("storeMetaDataInBuffers: %s",
149            enabled? "true": "false");
150    sp <ICamera> c = mCamera;
151    if (c == 0) return NO_INIT;
152    return c->storeMetaDataInBuffers(enabled);
153}
154
155// start recording mode, must call setPreviewTarget first
156status_t Camera::startRecording()
157{
158    ALOGV("startRecording");
159    sp <ICamera> c = mCamera;
160    if (c == 0) return NO_INIT;
161    return c->startRecording();
162}
163
164// stop preview mode
165void Camera::stopPreview()
166{
167    ALOGV("stopPreview");
168    sp <ICamera> c = mCamera;
169    if (c == 0) return;
170    c->stopPreview();
171}
172
173// stop recording mode
174void Camera::stopRecording()
175{
176    ALOGV("stopRecording");
177    {
178        Mutex::Autolock _l(mLock);
179        mRecordingProxyListener.clear();
180    }
181    sp <ICamera> c = mCamera;
182    if (c == 0) return;
183    c->stopRecording();
184}
185
186// release a recording frame
187void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
188{
189    ALOGV("releaseRecordingFrame");
190    sp <ICamera> c = mCamera;
191    if (c == 0) return;
192    c->releaseRecordingFrame(mem);
193}
194
195// get preview state
196bool Camera::previewEnabled()
197{
198    ALOGV("previewEnabled");
199    sp <ICamera> c = mCamera;
200    if (c == 0) return false;
201    return c->previewEnabled();
202}
203
204// get recording state
205bool Camera::recordingEnabled()
206{
207    ALOGV("recordingEnabled");
208    sp <ICamera> c = mCamera;
209    if (c == 0) return false;
210    return c->recordingEnabled();
211}
212
213status_t Camera::autoFocus()
214{
215    ALOGV("autoFocus");
216    sp <ICamera> c = mCamera;
217    if (c == 0) return NO_INIT;
218    return c->autoFocus();
219}
220
221status_t Camera::cancelAutoFocus()
222{
223    ALOGV("cancelAutoFocus");
224    sp <ICamera> c = mCamera;
225    if (c == 0) return NO_INIT;
226    return c->cancelAutoFocus();
227}
228
229// take a picture
230status_t Camera::takePicture(int msgType)
231{
232    ALOGV("takePicture: 0x%x", msgType);
233    sp <ICamera> c = mCamera;
234    if (c == 0) return NO_INIT;
235    return c->takePicture(msgType);
236}
237
238// set preview/capture parameters - key/value pairs
239status_t Camera::setParameters(const String8& params)
240{
241    ALOGV("setParameters");
242    sp <ICamera> c = mCamera;
243    if (c == 0) return NO_INIT;
244    return c->setParameters(params);
245}
246
247// get preview/capture parameters - key/value pairs
248String8 Camera::getParameters() const
249{
250    ALOGV("getParameters");
251    String8 params;
252    sp <ICamera> c = mCamera;
253    if (c != 0) params = mCamera->getParameters();
254    return params;
255}
256
257// send command to camera driver
258status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
259{
260    ALOGV("sendCommand");
261    sp <ICamera> c = mCamera;
262    if (c == 0) return NO_INIT;
263    return c->sendCommand(cmd, arg1, arg2);
264}
265
266void Camera::setListener(const sp<CameraListener>& listener)
267{
268    Mutex::Autolock _l(mLock);
269    mListener = listener;
270}
271
272void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
273{
274    Mutex::Autolock _l(mLock);
275    mRecordingProxyListener = listener;
276}
277
278void Camera::setPreviewCallbackFlags(int flag)
279{
280    ALOGV("setPreviewCallbackFlags");
281    sp <ICamera> c = mCamera;
282    if (c == 0) return;
283    mCamera->setPreviewCallbackFlag(flag);
284}
285
286status_t Camera::setPreviewCallbackTarget(
287        const sp<IGraphicBufferProducer>& callbackProducer)
288{
289    sp <ICamera> c = mCamera;
290    if (c == 0) return NO_INIT;
291    return c->setPreviewCallbackTarget(callbackProducer);
292}
293
294// callback from camera service
295void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
296{
297    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
298}
299
300// callback from camera service when frame or image is ready
301void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
302                          camera_frame_metadata_t *metadata)
303{
304    sp<CameraListener> listener;
305    {
306        Mutex::Autolock _l(mLock);
307        listener = mListener;
308    }
309    if (listener != NULL) {
310        listener->postData(msgType, dataPtr, metadata);
311    }
312}
313
314// callback from camera service when timestamped frame is ready
315void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
316{
317    // If recording proxy listener is registered, forward the frame and return.
318    // The other listener (mListener) is ignored because the receiver needs to
319    // call releaseRecordingFrame.
320    sp<ICameraRecordingProxyListener> proxylistener;
321    {
322        Mutex::Autolock _l(mLock);
323        proxylistener = mRecordingProxyListener;
324    }
325    if (proxylistener != NULL) {
326        proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
327        return;
328    }
329
330    sp<CameraListener> listener;
331    {
332        Mutex::Autolock _l(mLock);
333        listener = mListener;
334    }
335
336    if (listener != NULL) {
337        listener->postDataTimestamp(timestamp, msgType, dataPtr);
338    } else {
339        ALOGW("No listener was set. Drop a recording frame.");
340        releaseRecordingFrame(dataPtr);
341    }
342}
343
344sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
345    ALOGV("getProxy");
346    return new RecordingProxy(this);
347}
348
349status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
350{
351    ALOGV("RecordingProxy::startRecording");
352    mCamera->setRecordingProxyListener(listener);
353    mCamera->reconnect();
354    return mCamera->startRecording();
355}
356
357void Camera::RecordingProxy::stopRecording()
358{
359    ALOGV("RecordingProxy::stopRecording");
360    mCamera->stopRecording();
361}
362
363void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
364{
365    ALOGV("RecordingProxy::releaseRecordingFrame");
366    mCamera->releaseRecordingFrame(mem);
367}
368
369Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
370{
371    mCamera = camera;
372}
373
374}; // namespace android
375