blob: 6c60b853eac653ef524ba28984d454243bbde0c2 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2**
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -08003** Copyright (C) 2008, The Android Open Source Project
4** Copyright (C) 2008 HTC Inc.
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07005**
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -08006** 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
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07009**
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080010** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070011**
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080012** 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
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070016** limitations under the License.
17*/
18
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080019//#define LOG_NDEBUG 0
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070020#define LOG_TAG "Camera"
21#include <utils/Log.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070022#include <utils/IServiceManager.h>
23#include <utils/threads.h>
24#include <utils/IMemory.h>
25#include <ui/Surface.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070026#include <ui/Camera.h>
27#include <ui/ICameraService.h>
28
29namespace android {
30
31// client singleton for camera service binder interface
32Mutex Camera::mLock;
33sp<ICameraService> Camera::mCameraService;
34sp<Camera::DeathNotifier> Camera::mDeathNotifier;
35
36// establish binder interface to camera service
37const sp<ICameraService>& Camera::getCameraService()
38{
39 Mutex::Autolock _l(mLock);
40 if (mCameraService.get() == 0) {
41 sp<IServiceManager> sm = defaultServiceManager();
42 sp<IBinder> binder;
43 do {
44 binder = sm->getService(String16("media.camera"));
45 if (binder != 0)
46 break;
47 LOGW("CameraService not published, waiting...");
48 usleep(500000); // 0.5 s
49 } while(true);
50 if (mDeathNotifier == NULL) {
51 mDeathNotifier = new DeathNotifier();
52 }
53 binder->linkToDeath(mDeathNotifier);
54 mCameraService = interface_cast<ICameraService>(binder);
55 }
56 LOGE_IF(mCameraService==0, "no CameraService!?");
57 return mCameraService;
58}
59
60// ---------------------------------------------------------------------------
61
62Camera::Camera()
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070063{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080064 init();
65}
66
67Camera::Camera(const sp<ICamera>& camera)
68{
69 init();
70 // connect this client to existing camera remote
71 if (camera->connect(this) == NO_ERROR) {
72 mStatus = NO_ERROR;
73 mCamera = camera;
74 camera->asBinder()->linkToDeath(this);
75 }
76}
77
78void Camera::init()
79{
80 mStatus = UNKNOWN_ERROR;
81 mShutterCallback = 0;
82 mShutterCallbackCookie = 0;
83 mRawCallback = 0;
84 mRawCallbackCookie = 0;
85 mJpegCallback = 0;
86 mJpegCallbackCookie = 0;
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -080087 mPreviewCallback = 0;
88 mPreviewCallbackCookie = 0;
89 mRecordingCallback = 0;
90 mRecordingCallbackCookie = 0;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080091 mErrorCallback = 0;
92 mErrorCallbackCookie = 0;
93 mAutoFocusCallback = 0;
94 mAutoFocusCallbackCookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070095}
96
97Camera::~Camera()
98{
99 disconnect();
100}
101
102sp<Camera> Camera::connect()
103{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800104 LOGV("connect");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700105 sp<Camera> c = new Camera();
106 const sp<ICameraService>& cs = getCameraService();
107 if (cs != 0) {
108 c->mCamera = cs->connect(c);
109 }
110 if (c->mCamera != 0) {
111 c->mCamera->asBinder()->linkToDeath(c);
112 c->mStatus = NO_ERROR;
113 }
114 return c;
115}
116
117void Camera::disconnect()
118{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800119 LOGV("disconnect");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700120 if (mCamera != 0) {
121 mErrorCallback = 0;
122 mCamera->disconnect();
123 mCamera = 0;
124 }
125}
126
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800127status_t Camera::reconnect()
128{
129 LOGV("reconnect");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800130 sp <ICamera> c = mCamera;
131 if (c == 0) return NO_INIT;
132 return c->connect(this);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800133}
134
135sp<ICamera> Camera::remote()
136{
137 return mCamera;
138}
139
The Android Open Source Project27629322009-01-09 17:51:23 -0800140status_t Camera::lock()
141{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800142 sp <ICamera> c = mCamera;
143 if (c == 0) return NO_INIT;
144 return c->lock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800145}
146
147status_t Camera::unlock()
148{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800149 sp <ICamera> c = mCamera;
150 if (c == 0) return NO_INIT;
151 return c->unlock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800152}
153
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700154// pass the buffered ISurface to the camera service
155status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
156{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800157 LOGV("setPreviewDisplay");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700158 if (surface == 0) {
159 LOGE("app passed NULL surface");
160 return NO_INIT;
161 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800162 sp <ICamera> c = mCamera;
163 if (c == 0) return NO_INIT;
164 return c->setPreviewDisplay(surface->getISurface());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700165}
166
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800167status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
168{
169 LOGV("setPreviewDisplay");
170 if (surface == 0) {
171 LOGE("app passed NULL surface");
172 return NO_INIT;
173 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800174 sp <ICamera> c = mCamera;
175 if (c == 0) return NO_INIT;
176 return c->setPreviewDisplay(surface);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800177}
178
179
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700180// start preview mode, must call setPreviewDisplay first
181status_t Camera::startPreview()
182{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800183 LOGV("startPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800184 sp <ICamera> c = mCamera;
185 if (c == 0) return NO_INIT;
186 return c->startPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700187}
188
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800189// start recording mode, must call setPreviewDisplay first
190status_t Camera::startRecording()
191{
192 LOGV("startRecording");
193 sp <ICamera> c = mCamera;
194 if (c == 0) return NO_INIT;
195 return c->startRecording();
196}
197
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700198// stop preview mode
199void Camera::stopPreview()
200{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800201 LOGV("stopPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800202 sp <ICamera> c = mCamera;
203 if (c == 0) return;
204 c->stopPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700205}
206
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800207// stop recording mode
208void Camera::stopRecording()
209{
210 LOGV("stopRecording");
211 sp <ICamera> c = mCamera;
212 if (c == 0) return;
213 c->stopRecording();
214}
215
216// release a recording frame
217void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
218{
219 LOGV("releaseRecordingFrame");
220 sp <ICamera> c = mCamera;
221 if (c == 0) return;
222 c->releaseRecordingFrame(mem);
223}
224
The Android Open Source Project27629322009-01-09 17:51:23 -0800225// get preview state
226bool Camera::previewEnabled()
227{
228 LOGV("previewEnabled");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800229 sp <ICamera> c = mCamera;
230 if (c == 0) return false;
231 return c->previewEnabled();
The Android Open Source Project27629322009-01-09 17:51:23 -0800232}
233
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800234// get recording state
235bool Camera::recordingEnabled()
236{
237 LOGV("recordingEnabled");
238 sp <ICamera> c = mCamera;
239 if (c == 0) return false;
240 return c->recordingEnabled();
241}
242
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700243status_t Camera::autoFocus()
244{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800245 LOGV("autoFocus");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800246 sp <ICamera> c = mCamera;
247 if (c == 0) return NO_INIT;
248 return c->autoFocus();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700249}
250
251// take a picture
252status_t Camera::takePicture()
253{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800254 LOGV("takePicture");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800255 sp <ICamera> c = mCamera;
256 if (c == 0) return NO_INIT;
257 return c->takePicture();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700258}
259
260// set preview/capture parameters - key/value pairs
261status_t Camera::setParameters(const String8& params)
262{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800263 LOGV("setParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800264 sp <ICamera> c = mCamera;
265 if (c == 0) return NO_INIT;
266 return c->setParameters(params);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700267}
268
269// get preview/capture parameters - key/value pairs
270String8 Camera::getParameters() const
271{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800272 LOGV("getParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800273 String8 params;
274 sp <ICamera> c = mCamera;
275 if (c != 0) params = mCamera->getParameters();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700276 return params;
277}
278
279void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
280{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800281 LOGV("setAutoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700282 mAutoFocusCallback = cb;
283 mAutoFocusCallbackCookie = cookie;
284}
285
286void Camera::setShutterCallback(shutter_callback cb, void *cookie)
287{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800288 LOGV("setShutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700289 mShutterCallback = cb;
290 mShutterCallbackCookie = cookie;
291}
292
293void Camera::setRawCallback(frame_callback cb, void *cookie)
294{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800295 LOGV("setRawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700296 mRawCallback = cb;
297 mRawCallbackCookie = cookie;
298}
299
300void Camera::setJpegCallback(frame_callback cb, void *cookie)
301{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800302 LOGV("setJpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700303 mJpegCallback = cb;
304 mJpegCallbackCookie = cookie;
305}
306
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800307void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700308{
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800309 LOGV("setPreviewCallback");
310 mPreviewCallback = cb;
311 mPreviewCallbackCookie = cookie;
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800312 sp <ICamera> c = mCamera;
313 if (c == 0) return;
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800314 mCamera->setPreviewCallbackFlag(flag);
315}
316
317void Camera::setRecordingCallback(frame_callback cb, void *cookie)
318{
319 LOGV("setRecordingCallback");
320 mRecordingCallback = cb;
321 mRecordingCallbackCookie = cookie;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700322}
323
324void Camera::setErrorCallback(error_callback cb, void *cookie)
325{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800326 LOGV("setErrorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700327 mErrorCallback = cb;
328 mErrorCallbackCookie = cookie;
329}
330
331void Camera::autoFocusCallback(bool focused)
332{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800333 LOGV("autoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700334 if (mAutoFocusCallback) {
335 mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
336 }
337}
338
339void Camera::shutterCallback()
340{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800341 LOGV("shutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700342 if (mShutterCallback) {
343 mShutterCallback(mShutterCallbackCookie);
344 }
345}
346
347void Camera::rawCallback(const sp<IMemory>& picture)
348{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800349 LOGV("rawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700350 if (mRawCallback) {
351 mRawCallback(picture, mRawCallbackCookie);
352 }
353}
354
355// callback from camera service when image is ready
356void Camera::jpegCallback(const sp<IMemory>& picture)
357{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800358 LOGV("jpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700359 if (mJpegCallback) {
360 mJpegCallback(picture, mJpegCallbackCookie);
361 }
362}
363
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800364// callback from camera service when preview frame is ready
365void Camera::previewCallback(const sp<IMemory>& frame)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700366{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800367 LOGV("frameCallback");
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800368 if (mPreviewCallback) {
369 mPreviewCallback(frame, mPreviewCallbackCookie);
370 }
371}
372
373// callback from camera service when a recording frame is ready
374void Camera::recordingCallback(const sp<IMemory>& frame)
375{
376 LOGV("recordingCallback");
377 if (mRecordingCallback) {
378 mRecordingCallback(frame, mRecordingCallbackCookie);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700379 }
380}
381
382// callback from camera service when an error occurs in preview or takePicture
383void Camera::errorCallback(status_t error)
384{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800385 LOGV("errorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700386 if (mErrorCallback) {
387 mErrorCallback(error, mErrorCallbackCookie);
388 }
389}
390
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800391void Camera::binderDied(const wp<IBinder>& who) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700392 LOGW("ICamera died");
393 if (mErrorCallback) {
394 mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
395 }
396}
397
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800398void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
399 LOGV("binderDied");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700400 Mutex::Autolock _l(Camera::mLock);
401 Camera::mCameraService.clear();
402 LOGW("Camera server died!");
403}
404
405}; // namespace android
406