Camera.cpp revision ddbdb35d176266b5ab64c30178f5cb76c5b1b4b4
1/*
2**
3** Copyright (C) 2008, The Android Open Source Project
4** Copyright (C) 2008 HTC Inc.
5**
6** Licensed under the Apache License, Version 2.0 (the "License");
7** you may not use this file except in compliance with the License.
8** You may obtain a copy of the License at
9**
10**     http://www.apache.org/licenses/LICENSE-2.0
11**
12** Unless required by applicable law or agreed to in writing, software
13** distributed under the License is distributed on an "AS IS" BASIS,
14** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15** See the License for the specific language governing permissions and
16** limitations under the License.
17*/
18
19//#define LOG_NDEBUG 0
20#define LOG_TAG "Camera"
21#include <utils/Log.h>
22#include <utils/threads.h>
23
24#include <binder/IServiceManager.h>
25#include <binder/IMemory.h>
26
27#include <camera/Camera.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            LOGW("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    LOGE_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     LOGV("create");
74     if (camera == 0) {
75         LOGE("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    }
85    return c;
86}
87
88void Camera::init()
89{
90    mStatus = UNKNOWN_ERROR;
91}
92
93Camera::~Camera()
94{
95    // We don't need to call disconnect() here because if the CameraService
96    // thinks we are the owner of the hardware, it will hold a (strong)
97    // reference to us, and we can't possibly be here. We also don't want to
98    // call disconnect() here if we are in the same process as mediaserver,
99    // because we may be invoked by CameraService::Client::connect() and will
100    // deadlock if we call any method of ICamera here.
101}
102
103int32_t Camera::getNumberOfCameras()
104{
105    const sp<ICameraService>& cs = getCameraService();
106    if (cs == 0) return 0;
107    return cs->getNumberOfCameras();
108}
109
110status_t Camera::getCameraInfo(int cameraId,
111                               struct CameraInfo* cameraInfo) {
112    const sp<ICameraService>& cs = getCameraService();
113    if (cs == 0) return UNKNOWN_ERROR;
114    return cs->getCameraInfo(cameraId, cameraInfo);
115}
116
117sp<Camera> Camera::connect(int cameraId)
118{
119    LOGV("connect");
120    sp<Camera> c = new Camera();
121    const sp<ICameraService>& cs = getCameraService();
122    if (cs != 0) {
123        c->mCamera = cs->connect(c, cameraId);
124    }
125    if (c->mCamera != 0) {
126        c->mCamera->asBinder()->linkToDeath(c);
127        c->mStatus = NO_ERROR;
128    } else {
129        c.clear();
130    }
131    return c;
132}
133
134void Camera::disconnect()
135{
136    LOGV("disconnect");
137    if (mCamera != 0) {
138        mCamera->disconnect();
139        mCamera->asBinder()->unlinkToDeath(this);
140        mCamera = 0;
141    }
142}
143
144status_t Camera::reconnect()
145{
146    LOGV("reconnect");
147    sp <ICamera> c = mCamera;
148    if (c == 0) return NO_INIT;
149    return c->connect(this);
150}
151
152sp<ICamera> Camera::remote()
153{
154    return mCamera;
155}
156
157status_t Camera::lock()
158{
159    sp <ICamera> c = mCamera;
160    if (c == 0) return NO_INIT;
161    return c->lock();
162}
163
164status_t Camera::unlock()
165{
166    sp <ICamera> c = mCamera;
167    if (c == 0) return NO_INIT;
168    return c->unlock();
169}
170
171// pass the buffered ISurface to the camera service
172status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
173{
174    LOGV("setPreviewDisplay");
175    sp <ICamera> c = mCamera;
176    if (c == 0) return NO_INIT;
177    if (surface != 0) {
178        return c->setPreviewDisplay(surface->getISurface());
179    } else {
180        LOGD("app passed NULL surface");
181        return c->setPreviewDisplay(0);
182    }
183}
184
185status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
186{
187    LOGV("setPreviewDisplay");
188    if (surface == 0) {
189        LOGD("app passed NULL surface");
190    }
191    sp <ICamera> c = mCamera;
192    if (c == 0) return NO_INIT;
193    return c->setPreviewDisplay(surface);
194}
195
196
197// start preview mode
198status_t Camera::startPreview()
199{
200    LOGV("startPreview");
201    sp <ICamera> c = mCamera;
202    if (c == 0) return NO_INIT;
203    return c->startPreview();
204}
205
206// start recording mode, must call setPreviewDisplay first
207status_t Camera::startRecording()
208{
209    LOGV("startRecording");
210    sp <ICamera> c = mCamera;
211    if (c == 0) return NO_INIT;
212    return c->startRecording();
213}
214
215// stop preview mode
216void Camera::stopPreview()
217{
218    LOGV("stopPreview");
219    sp <ICamera> c = mCamera;
220    if (c == 0) return;
221    c->stopPreview();
222}
223
224// stop recording mode
225void Camera::stopRecording()
226{
227    LOGV("stopRecording");
228    sp <ICamera> c = mCamera;
229    if (c == 0) return;
230    c->stopRecording();
231}
232
233// release a recording frame
234void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
235{
236    LOGV("releaseRecordingFrame");
237    sp <ICamera> c = mCamera;
238    if (c == 0) return;
239    c->releaseRecordingFrame(mem);
240}
241
242// get preview state
243bool Camera::previewEnabled()
244{
245    LOGV("previewEnabled");
246    sp <ICamera> c = mCamera;
247    if (c == 0) return false;
248    return c->previewEnabled();
249}
250
251// get recording state
252bool Camera::recordingEnabled()
253{
254    LOGV("recordingEnabled");
255    sp <ICamera> c = mCamera;
256    if (c == 0) return false;
257    return c->recordingEnabled();
258}
259
260status_t Camera::autoFocus()
261{
262    LOGV("autoFocus");
263    sp <ICamera> c = mCamera;
264    if (c == 0) return NO_INIT;
265    return c->autoFocus();
266}
267
268status_t Camera::cancelAutoFocus()
269{
270    LOGV("cancelAutoFocus");
271    sp <ICamera> c = mCamera;
272    if (c == 0) return NO_INIT;
273    return c->cancelAutoFocus();
274}
275
276// take a picture
277status_t Camera::takePicture()
278{
279    LOGV("takePicture");
280    sp <ICamera> c = mCamera;
281    if (c == 0) return NO_INIT;
282    return c->takePicture();
283}
284
285// set preview/capture parameters - key/value pairs
286status_t Camera::setParameters(const String8& params)
287{
288    LOGV("setParameters");
289    sp <ICamera> c = mCamera;
290    if (c == 0) return NO_INIT;
291    return c->setParameters(params);
292}
293
294// get preview/capture parameters - key/value pairs
295String8 Camera::getParameters() const
296{
297    LOGV("getParameters");
298    String8 params;
299    sp <ICamera> c = mCamera;
300    if (c != 0) params = mCamera->getParameters();
301    return params;
302}
303
304// send command to camera driver
305status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
306{
307    LOGV("sendCommand");
308    sp <ICamera> c = mCamera;
309    if (c == 0) return NO_INIT;
310    return c->sendCommand(cmd, arg1, arg2);
311}
312
313void Camera::setListener(const sp<CameraListener>& listener)
314{
315    Mutex::Autolock _l(mLock);
316    mListener = listener;
317}
318
319void Camera::setPreviewCallbackFlags(int flag)
320{
321    LOGV("setPreviewCallbackFlags");
322    sp <ICamera> c = mCamera;
323    if (c == 0) return;
324    mCamera->setPreviewCallbackFlag(flag);
325}
326
327// callback from camera service
328void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
329{
330    sp<CameraListener> listener;
331    {
332        Mutex::Autolock _l(mLock);
333        listener = mListener;
334    }
335    if (listener != NULL) {
336        listener->notify(msgType, ext1, ext2);
337    }
338}
339
340// callback from camera service when frame or image is ready
341void Camera::dataCallback(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->postData(msgType, dataPtr);
350    }
351}
352
353// callback from camera service when timestamped frame is ready
354void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
355{
356    sp<CameraListener> listener;
357    {
358        Mutex::Autolock _l(mLock);
359        listener = mListener;
360    }
361    if (listener != NULL) {
362        listener->postDataTimestamp(timestamp, msgType, dataPtr);
363    }
364}
365
366void Camera::binderDied(const wp<IBinder>& who) {
367    LOGW("ICamera died");
368    notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
369}
370
371void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
372    LOGV("binderDied");
373    Mutex::Autolock _l(Camera::mLock);
374    Camera::mCameraService.clear();
375    LOGW("Camera server died!");
376}
377
378}; // namespace android
379
380