Camera.cpp revision fa4cf9d310685b4c25877cba772ff7da84caf517
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
42// construct a camera client from an existing camera remote
43sp<Camera> Camera::create(const sp<ICamera>& camera)
44{
45     ALOGV("create");
46     if (camera == 0) {
47         ALOGE("camera remote is a NULL pointer");
48         return 0;
49     }
50
51    sp<Camera> c = new Camera(-1);
52    if (camera->connect(c) == NO_ERROR) {
53        c->mStatus = NO_ERROR;
54        c->mCamera = camera;
55        camera->asBinder()->linkToDeath(c);
56        return c;
57    }
58    return 0;
59}
60
61Camera::~Camera()
62{
63    // We don't need to call disconnect() here because if the CameraService
64    // thinks we are the owner of the hardware, it will hold a (strong)
65    // reference to us, and we can't possibly be here. We also don't want to
66    // call disconnect() here if we are in the same process as mediaserver,
67    // because we may be invoked by CameraService::Client::connect() and will
68    // deadlock if we call any method of ICamera here.
69}
70
71sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
72        int clientUid)
73{
74    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
75}
76
77status_t Camera::reconnect()
78{
79    ALOGV("reconnect");
80    sp <ICamera> c = mCamera;
81    if (c == 0) return NO_INIT;
82    return c->connect(this);
83}
84
85status_t Camera::lock()
86{
87    sp <ICamera> c = mCamera;
88    if (c == 0) return NO_INIT;
89    return c->lock();
90}
91
92status_t Camera::unlock()
93{
94    sp <ICamera> c = mCamera;
95    if (c == 0) return NO_INIT;
96    return c->unlock();
97}
98
99// pass the buffered Surface to the camera service
100status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
101{
102    ALOGV("setPreviewDisplay(%p)", surface.get());
103    sp <ICamera> c = mCamera;
104    if (c == 0) return NO_INIT;
105    if (surface != 0) {
106        return c->setPreviewDisplay(surface);
107    } else {
108        ALOGD("app passed NULL surface");
109        return c->setPreviewDisplay(0);
110    }
111}
112
113// pass the buffered IGraphicBufferProducer to the camera service
114status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
115{
116    ALOGV("setPreviewTexture(%p)", bufferProducer.get());
117    sp <ICamera> c = mCamera;
118    if (c == 0) return NO_INIT;
119    if (bufferProducer != 0) {
120        return c->setPreviewTexture(bufferProducer);
121    } else {
122        ALOGD("app passed NULL surface");
123        return c->setPreviewTexture(0);
124    }
125}
126
127// start preview mode
128status_t Camera::startPreview()
129{
130    ALOGV("startPreview");
131    sp <ICamera> c = mCamera;
132    if (c == 0) return NO_INIT;
133    return c->startPreview();
134}
135
136status_t Camera::storeMetaDataInBuffers(bool enabled)
137{
138    ALOGV("storeMetaDataInBuffers: %s",
139            enabled? "true": "false");
140    sp <ICamera> c = mCamera;
141    if (c == 0) return NO_INIT;
142    return c->storeMetaDataInBuffers(enabled);
143}
144
145// start recording mode, must call setPreviewDisplay first
146status_t Camera::startRecording()
147{
148    ALOGV("startRecording");
149    sp <ICamera> c = mCamera;
150    if (c == 0) return NO_INIT;
151    return c->startRecording();
152}
153
154// stop preview mode
155void Camera::stopPreview()
156{
157    ALOGV("stopPreview");
158    sp <ICamera> c = mCamera;
159    if (c == 0) return;
160    c->stopPreview();
161}
162
163// stop recording mode
164void Camera::stopRecording()
165{
166    ALOGV("stopRecording");
167    {
168        Mutex::Autolock _l(mLock);
169        mRecordingProxyListener.clear();
170    }
171    sp <ICamera> c = mCamera;
172    if (c == 0) return;
173    c->stopRecording();
174}
175
176// release a recording frame
177void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
178{
179    ALOGV("releaseRecordingFrame");
180    sp <ICamera> c = mCamera;
181    if (c == 0) return;
182    c->releaseRecordingFrame(mem);
183}
184
185// get preview state
186bool Camera::previewEnabled()
187{
188    ALOGV("previewEnabled");
189    sp <ICamera> c = mCamera;
190    if (c == 0) return false;
191    return c->previewEnabled();
192}
193
194// get recording state
195bool Camera::recordingEnabled()
196{
197    ALOGV("recordingEnabled");
198    sp <ICamera> c = mCamera;
199    if (c == 0) return false;
200    return c->recordingEnabled();
201}
202
203status_t Camera::autoFocus()
204{
205    ALOGV("autoFocus");
206    sp <ICamera> c = mCamera;
207    if (c == 0) return NO_INIT;
208    return c->autoFocus();
209}
210
211status_t Camera::cancelAutoFocus()
212{
213    ALOGV("cancelAutoFocus");
214    sp <ICamera> c = mCamera;
215    if (c == 0) return NO_INIT;
216    return c->cancelAutoFocus();
217}
218
219// take a picture
220status_t Camera::takePicture(int msgType)
221{
222    ALOGV("takePicture: 0x%x", msgType);
223    sp <ICamera> c = mCamera;
224    if (c == 0) return NO_INIT;
225    return c->takePicture(msgType);
226}
227
228// set preview/capture parameters - key/value pairs
229status_t Camera::setParameters(const String8& params)
230{
231    ALOGV("setParameters");
232    sp <ICamera> c = mCamera;
233    if (c == 0) return NO_INIT;
234    return c->setParameters(params);
235}
236
237// get preview/capture parameters - key/value pairs
238String8 Camera::getParameters() const
239{
240    ALOGV("getParameters");
241    String8 params;
242    sp <ICamera> c = mCamera;
243    if (c != 0) params = mCamera->getParameters();
244    return params;
245}
246
247// send command to camera driver
248status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
249{
250    ALOGV("sendCommand");
251    sp <ICamera> c = mCamera;
252    if (c == 0) return NO_INIT;
253    return c->sendCommand(cmd, arg1, arg2);
254}
255
256void Camera::setListener(const sp<CameraListener>& listener)
257{
258    Mutex::Autolock _l(mLock);
259    mListener = listener;
260}
261
262void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
263{
264    Mutex::Autolock _l(mLock);
265    mRecordingProxyListener = listener;
266}
267
268void Camera::setPreviewCallbackFlags(int flag)
269{
270    ALOGV("setPreviewCallbackFlags");
271    sp <ICamera> c = mCamera;
272    if (c == 0) return;
273    mCamera->setPreviewCallbackFlag(flag);
274}
275
276// callback from camera service
277void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
278{
279    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
280}
281
282// callback from camera service when frame or image is ready
283void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
284                          camera_frame_metadata_t *metadata)
285{
286    sp<CameraListener> listener;
287    {
288        Mutex::Autolock _l(mLock);
289        listener = mListener;
290    }
291    if (listener != NULL) {
292        listener->postData(msgType, dataPtr, metadata);
293    }
294}
295
296// callback from camera service when timestamped frame is ready
297void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
298{
299    // If recording proxy listener is registered, forward the frame and return.
300    // The other listener (mListener) is ignored because the receiver needs to
301    // call releaseRecordingFrame.
302    sp<ICameraRecordingProxyListener> proxylistener;
303    {
304        Mutex::Autolock _l(mLock);
305        proxylistener = mRecordingProxyListener;
306    }
307    if (proxylistener != NULL) {
308        proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
309        return;
310    }
311
312    sp<CameraListener> listener;
313    {
314        Mutex::Autolock _l(mLock);
315        listener = mListener;
316    }
317
318    if (listener != NULL) {
319        listener->postDataTimestamp(timestamp, msgType, dataPtr);
320    } else {
321        ALOGW("No listener was set. Drop a recording frame.");
322        releaseRecordingFrame(dataPtr);
323    }
324}
325
326sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
327    ALOGV("getProxy");
328    return new RecordingProxy(this);
329}
330
331status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
332{
333    ALOGV("RecordingProxy::startRecording");
334    mCamera->setRecordingProxyListener(listener);
335    mCamera->reconnect();
336    return mCamera->startRecording();
337}
338
339void Camera::RecordingProxy::stopRecording()
340{
341    ALOGV("RecordingProxy::stopRecording");
342    mCamera->stopRecording();
343}
344
345void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
346{
347    ALOGV("RecordingProxy::releaseRecordingFrame");
348    mCamera->releaseRecordingFrame(mem);
349}
350
351Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
352{
353    mCamera = camera;
354}
355
356}; // namespace android
357