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