Camera.cpp revision d06618ee31c11ac7ac6698f95444041a4785a5ab
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
110sp<Camera> Camera::connect(int cameraId)
111{
112    LOGV("connect");
113    sp<Camera> c = new Camera();
114    const sp<ICameraService>& cs = getCameraService();
115    if (cs != 0) {
116        c->mCamera = cs->connect(c, cameraId);
117    }
118    if (c->mCamera != 0) {
119        c->mCamera->asBinder()->linkToDeath(c);
120        c->mStatus = NO_ERROR;
121    } else {
122        c.clear();
123    }
124    return c;
125}
126
127void Camera::disconnect()
128{
129    LOGV("disconnect");
130    if (mCamera != 0) {
131        mCamera->disconnect();
132        mCamera->asBinder()->unlinkToDeath(this);
133        mCamera = 0;
134    }
135}
136
137status_t Camera::reconnect()
138{
139    LOGV("reconnect");
140    sp <ICamera> c = mCamera;
141    if (c == 0) return NO_INIT;
142    return c->connect(this);
143}
144
145sp<ICamera> Camera::remote()
146{
147    return mCamera;
148}
149
150status_t Camera::lock()
151{
152    sp <ICamera> c = mCamera;
153    if (c == 0) return NO_INIT;
154    return c->lock();
155}
156
157status_t Camera::unlock()
158{
159    sp <ICamera> c = mCamera;
160    if (c == 0) return NO_INIT;
161    return c->unlock();
162}
163
164// pass the buffered ISurface to the camera service
165status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
166{
167    LOGV("setPreviewDisplay");
168    sp <ICamera> c = mCamera;
169    if (c == 0) return NO_INIT;
170    if (surface != 0) {
171        return c->setPreviewDisplay(surface->getISurface());
172    } else {
173        LOGD("app passed NULL surface");
174        return c->setPreviewDisplay(0);
175    }
176}
177
178status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
179{
180    LOGV("setPreviewDisplay");
181    if (surface == 0) {
182        LOGD("app passed NULL surface");
183    }
184    sp <ICamera> c = mCamera;
185    if (c == 0) return NO_INIT;
186    return c->setPreviewDisplay(surface);
187}
188
189
190// start preview mode
191status_t Camera::startPreview()
192{
193    LOGV("startPreview");
194    sp <ICamera> c = mCamera;
195    if (c == 0) return NO_INIT;
196    return c->startPreview();
197}
198
199// start recording mode, must call setPreviewDisplay first
200status_t Camera::startRecording()
201{
202    LOGV("startRecording");
203    sp <ICamera> c = mCamera;
204    if (c == 0) return NO_INIT;
205    return c->startRecording();
206}
207
208// stop preview mode
209void Camera::stopPreview()
210{
211    LOGV("stopPreview");
212    sp <ICamera> c = mCamera;
213    if (c == 0) return;
214    c->stopPreview();
215}
216
217// stop recording mode
218void Camera::stopRecording()
219{
220    LOGV("stopRecording");
221    sp <ICamera> c = mCamera;
222    if (c == 0) return;
223    c->stopRecording();
224}
225
226// release a recording frame
227void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
228{
229    LOGV("releaseRecordingFrame");
230    sp <ICamera> c = mCamera;
231    if (c == 0) return;
232    c->releaseRecordingFrame(mem);
233}
234
235// get preview state
236bool Camera::previewEnabled()
237{
238    LOGV("previewEnabled");
239    sp <ICamera> c = mCamera;
240    if (c == 0) return false;
241    return c->previewEnabled();
242}
243
244// get recording state
245bool Camera::recordingEnabled()
246{
247    LOGV("recordingEnabled");
248    sp <ICamera> c = mCamera;
249    if (c == 0) return false;
250    return c->recordingEnabled();
251}
252
253status_t Camera::autoFocus()
254{
255    LOGV("autoFocus");
256    sp <ICamera> c = mCamera;
257    if (c == 0) return NO_INIT;
258    return c->autoFocus();
259}
260
261status_t Camera::cancelAutoFocus()
262{
263    LOGV("cancelAutoFocus");
264    sp <ICamera> c = mCamera;
265    if (c == 0) return NO_INIT;
266    return c->cancelAutoFocus();
267}
268
269// take a picture
270status_t Camera::takePicture()
271{
272    LOGV("takePicture");
273    sp <ICamera> c = mCamera;
274    if (c == 0) return NO_INIT;
275    return c->takePicture();
276}
277
278// set preview/capture parameters - key/value pairs
279status_t Camera::setParameters(const String8& params)
280{
281    LOGV("setParameters");
282    sp <ICamera> c = mCamera;
283    if (c == 0) return NO_INIT;
284    return c->setParameters(params);
285}
286
287// get preview/capture parameters - key/value pairs
288String8 Camera::getParameters() const
289{
290    LOGV("getParameters");
291    String8 params;
292    sp <ICamera> c = mCamera;
293    if (c != 0) params = mCamera->getParameters();
294    return params;
295}
296
297// send command to camera driver
298status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
299{
300    LOGV("sendCommand");
301    sp <ICamera> c = mCamera;
302    if (c == 0) return NO_INIT;
303    return c->sendCommand(cmd, arg1, arg2);
304}
305
306void Camera::setListener(const sp<CameraListener>& listener)
307{
308    Mutex::Autolock _l(mLock);
309    mListener = listener;
310}
311
312void Camera::setPreviewCallbackFlags(int flag)
313{
314    LOGV("setPreviewCallbackFlags");
315    sp <ICamera> c = mCamera;
316    if (c == 0) return;
317    mCamera->setPreviewCallbackFlag(flag);
318}
319
320// callback from camera service
321void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
322{
323    sp<CameraListener> listener;
324    {
325        Mutex::Autolock _l(mLock);
326        listener = mListener;
327    }
328    if (listener != NULL) {
329        listener->notify(msgType, ext1, ext2);
330    }
331}
332
333// callback from camera service when frame or image is ready
334void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
335{
336    sp<CameraListener> listener;
337    {
338        Mutex::Autolock _l(mLock);
339        listener = mListener;
340    }
341    if (listener != NULL) {
342        listener->postData(msgType, dataPtr);
343    }
344}
345
346// callback from camera service when timestamped frame is ready
347void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
348{
349    sp<CameraListener> listener;
350    {
351        Mutex::Autolock _l(mLock);
352        listener = mListener;
353    }
354    if (listener != NULL) {
355        listener->postDataTimestamp(timestamp, msgType, dataPtr);
356    }
357}
358
359void Camera::binderDied(const wp<IBinder>& who) {
360    LOGW("ICamera died");
361    notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
362}
363
364void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
365    LOGV("binderDied");
366    Mutex::Autolock _l(Camera::mLock);
367    Camera::mCameraService.clear();
368    LOGW("Camera server died!");
369}
370
371}; // namespace android
372
373