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