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