blob: b3cbda14fb06fa11043f39b90f6c8d24df3cebb6 [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;
The Android Open Source Project0bb03402009-03-02 22:54:33 -0800113 } else {
114 c.clear();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700115 }
116 return c;
117}
118
119void Camera::disconnect()
120{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800121 LOGV("disconnect");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700122 if (mCamera != 0) {
123 mErrorCallback = 0;
124 mCamera->disconnect();
125 mCamera = 0;
126 }
127}
128
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800129status_t Camera::reconnect()
130{
131 LOGV("reconnect");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800132 sp <ICamera> c = mCamera;
133 if (c == 0) return NO_INIT;
134 return c->connect(this);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800135}
136
137sp<ICamera> Camera::remote()
138{
139 return mCamera;
140}
141
The Android Open Source Project27629322009-01-09 17:51:23 -0800142status_t Camera::lock()
143{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800144 sp <ICamera> c = mCamera;
145 if (c == 0) return NO_INIT;
146 return c->lock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800147}
148
149status_t Camera::unlock()
150{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800151 sp <ICamera> c = mCamera;
152 if (c == 0) return NO_INIT;
153 return c->unlock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800154}
155
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700156// pass the buffered ISurface to the camera service
157status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
158{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800159 LOGV("setPreviewDisplay");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700160 if (surface == 0) {
161 LOGE("app passed NULL surface");
162 return NO_INIT;
163 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800164 sp <ICamera> c = mCamera;
165 if (c == 0) return NO_INIT;
166 return c->setPreviewDisplay(surface->getISurface());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700167}
168
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800169status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
170{
171 LOGV("setPreviewDisplay");
172 if (surface == 0) {
173 LOGE("app passed NULL surface");
174 return NO_INIT;
175 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800176 sp <ICamera> c = mCamera;
177 if (c == 0) return NO_INIT;
178 return c->setPreviewDisplay(surface);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800179}
180
181
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700182// start preview mode, must call setPreviewDisplay first
183status_t Camera::startPreview()
184{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800185 LOGV("startPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800186 sp <ICamera> c = mCamera;
187 if (c == 0) return NO_INIT;
188 return c->startPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700189}
190
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800191// start recording mode, must call setPreviewDisplay first
192status_t Camera::startRecording()
193{
194 LOGV("startRecording");
195 sp <ICamera> c = mCamera;
196 if (c == 0) return NO_INIT;
197 return c->startRecording();
198}
199
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700200// stop preview mode
201void Camera::stopPreview()
202{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800203 LOGV("stopPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800204 sp <ICamera> c = mCamera;
205 if (c == 0) return;
206 c->stopPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700207}
208
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800209// stop recording mode
210void Camera::stopRecording()
211{
212 LOGV("stopRecording");
213 sp <ICamera> c = mCamera;
214 if (c == 0) return;
215 c->stopRecording();
216}
217
218// release a recording frame
219void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
220{
221 LOGV("releaseRecordingFrame");
222 sp <ICamera> c = mCamera;
223 if (c == 0) return;
224 c->releaseRecordingFrame(mem);
225}
226
The Android Open Source Project27629322009-01-09 17:51:23 -0800227// get preview state
228bool Camera::previewEnabled()
229{
230 LOGV("previewEnabled");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800231 sp <ICamera> c = mCamera;
232 if (c == 0) return false;
233 return c->previewEnabled();
The Android Open Source Project27629322009-01-09 17:51:23 -0800234}
235
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800236// get recording state
237bool Camera::recordingEnabled()
238{
239 LOGV("recordingEnabled");
240 sp <ICamera> c = mCamera;
241 if (c == 0) return false;
242 return c->recordingEnabled();
243}
244
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700245status_t Camera::autoFocus()
246{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800247 LOGV("autoFocus");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800248 sp <ICamera> c = mCamera;
249 if (c == 0) return NO_INIT;
250 return c->autoFocus();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700251}
252
253// take a picture
254status_t Camera::takePicture()
255{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800256 LOGV("takePicture");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800257 sp <ICamera> c = mCamera;
258 if (c == 0) return NO_INIT;
259 return c->takePicture();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700260}
261
262// set preview/capture parameters - key/value pairs
263status_t Camera::setParameters(const String8& params)
264{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800265 LOGV("setParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800266 sp <ICamera> c = mCamera;
267 if (c == 0) return NO_INIT;
268 return c->setParameters(params);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700269}
270
271// get preview/capture parameters - key/value pairs
272String8 Camera::getParameters() const
273{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800274 LOGV("getParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800275 String8 params;
276 sp <ICamera> c = mCamera;
277 if (c != 0) params = mCamera->getParameters();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700278 return params;
279}
280
281void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
282{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800283 LOGV("setAutoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700284 mAutoFocusCallback = cb;
285 mAutoFocusCallbackCookie = cookie;
286}
287
288void Camera::setShutterCallback(shutter_callback cb, void *cookie)
289{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800290 LOGV("setShutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700291 mShutterCallback = cb;
292 mShutterCallbackCookie = cookie;
293}
294
295void Camera::setRawCallback(frame_callback cb, void *cookie)
296{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800297 LOGV("setRawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700298 mRawCallback = cb;
299 mRawCallbackCookie = cookie;
300}
301
302void Camera::setJpegCallback(frame_callback cb, void *cookie)
303{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800304 LOGV("setJpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700305 mJpegCallback = cb;
306 mJpegCallbackCookie = cookie;
307}
308
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800309void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700310{
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800311 LOGV("setPreviewCallback");
312 mPreviewCallback = cb;
313 mPreviewCallbackCookie = cookie;
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800314 sp <ICamera> c = mCamera;
315 if (c == 0) return;
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800316 mCamera->setPreviewCallbackFlag(flag);
317}
318
319void Camera::setRecordingCallback(frame_callback cb, void *cookie)
320{
321 LOGV("setRecordingCallback");
322 mRecordingCallback = cb;
323 mRecordingCallbackCookie = cookie;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700324}
325
326void Camera::setErrorCallback(error_callback cb, void *cookie)
327{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800328 LOGV("setErrorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700329 mErrorCallback = cb;
330 mErrorCallbackCookie = cookie;
331}
332
333void Camera::autoFocusCallback(bool focused)
334{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800335 LOGV("autoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700336 if (mAutoFocusCallback) {
337 mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
338 }
339}
340
341void Camera::shutterCallback()
342{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800343 LOGV("shutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700344 if (mShutterCallback) {
345 mShutterCallback(mShutterCallbackCookie);
346 }
347}
348
349void Camera::rawCallback(const sp<IMemory>& picture)
350{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800351 LOGV("rawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700352 if (mRawCallback) {
353 mRawCallback(picture, mRawCallbackCookie);
354 }
355}
356
357// callback from camera service when image is ready
358void Camera::jpegCallback(const sp<IMemory>& picture)
359{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800360 LOGV("jpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700361 if (mJpegCallback) {
362 mJpegCallback(picture, mJpegCallbackCookie);
363 }
364}
365
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800366// callback from camera service when preview frame is ready
367void Camera::previewCallback(const sp<IMemory>& frame)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700368{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800369 LOGV("frameCallback");
The Android Open Source Projecta6938ba2009-02-10 15:44:00 -0800370 if (mPreviewCallback) {
371 mPreviewCallback(frame, mPreviewCallbackCookie);
372 }
373}
374
375// callback from camera service when a recording frame is ready
376void Camera::recordingCallback(const sp<IMemory>& frame)
377{
378 LOGV("recordingCallback");
379 if (mRecordingCallback) {
380 mRecordingCallback(frame, mRecordingCallbackCookie);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700381 }
382}
383
384// callback from camera service when an error occurs in preview or takePicture
385void Camera::errorCallback(status_t error)
386{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800387 LOGV("errorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700388 if (mErrorCallback) {
389 mErrorCallback(error, mErrorCallbackCookie);
390 }
391}
392
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800393void Camera::binderDied(const wp<IBinder>& who) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700394 LOGW("ICamera died");
395 if (mErrorCallback) {
396 mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
397 }
398}
399
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800400void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
401 LOGV("binderDied");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700402 Mutex::Autolock _l(Camera::mLock);
403 Camera::mCameraService.clear();
404 LOGW("Camera server died!");
405}
406
407}; // namespace android
408