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