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