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