blob: 50c60084adf7f595fbc5bcc348297e6c4d0f65a4 [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;
87 mFrameCallback = 0;
88 mFrameCallbackCookie = 0;
89 mErrorCallback = 0;
90 mErrorCallbackCookie = 0;
91 mAutoFocusCallback = 0;
92 mAutoFocusCallbackCookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070093}
94
95Camera::~Camera()
96{
97 disconnect();
98}
99
100sp<Camera> Camera::connect()
101{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800102 LOGV("connect");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700103 sp<Camera> c = new Camera();
104 const sp<ICameraService>& cs = getCameraService();
105 if (cs != 0) {
106 c->mCamera = cs->connect(c);
107 }
108 if (c->mCamera != 0) {
109 c->mCamera->asBinder()->linkToDeath(c);
110 c->mStatus = NO_ERROR;
111 }
112 return c;
113}
114
115void Camera::disconnect()
116{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800117 LOGV("disconnect");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700118 if (mCamera != 0) {
119 mErrorCallback = 0;
120 mCamera->disconnect();
121 mCamera = 0;
122 }
123}
124
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800125status_t Camera::reconnect()
126{
127 LOGV("reconnect");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800128 sp <ICamera> c = mCamera;
129 if (c == 0) return NO_INIT;
130 return c->connect(this);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800131}
132
133sp<ICamera> Camera::remote()
134{
135 return mCamera;
136}
137
The Android Open Source Project27629322009-01-09 17:51:23 -0800138status_t Camera::lock()
139{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800140 sp <ICamera> c = mCamera;
141 if (c == 0) return NO_INIT;
142 return c->lock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800143}
144
145status_t Camera::unlock()
146{
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800147 sp <ICamera> c = mCamera;
148 if (c == 0) return NO_INIT;
149 return c->unlock();
The Android Open Source Project27629322009-01-09 17:51:23 -0800150}
151
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700152// pass the buffered ISurface to the camera service
153status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
154{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800155 LOGV("setPreviewDisplay");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700156 if (surface == 0) {
157 LOGE("app passed NULL surface");
158 return NO_INIT;
159 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800160 sp <ICamera> c = mCamera;
161 if (c == 0) return NO_INIT;
162 return c->setPreviewDisplay(surface->getISurface());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700163}
164
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800165status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
166{
167 LOGV("setPreviewDisplay");
168 if (surface == 0) {
169 LOGE("app passed NULL surface");
170 return NO_INIT;
171 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800172 sp <ICamera> c = mCamera;
173 if (c == 0) return NO_INIT;
174 return c->setPreviewDisplay(surface);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800175}
176
177
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700178// start preview mode, must call setPreviewDisplay first
179status_t Camera::startPreview()
180{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800181 LOGV("startPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800182 sp <ICamera> c = mCamera;
183 if (c == 0) return NO_INIT;
184 return c->startPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700185}
186
187// stop preview mode
188void Camera::stopPreview()
189{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800190 LOGV("stopPreview");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800191 sp <ICamera> c = mCamera;
192 if (c == 0) return;
193 c->stopPreview();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700194}
195
The Android Open Source Project27629322009-01-09 17:51:23 -0800196// get preview state
197bool Camera::previewEnabled()
198{
199 LOGV("previewEnabled");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800200 sp <ICamera> c = mCamera;
201 if (c == 0) return false;
202 return c->previewEnabled();
The Android Open Source Project27629322009-01-09 17:51:23 -0800203}
204
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700205status_t Camera::autoFocus()
206{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800207 LOGV("autoFocus");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800208 sp <ICamera> c = mCamera;
209 if (c == 0) return NO_INIT;
210 return c->autoFocus();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700211}
212
213// take a picture
214status_t Camera::takePicture()
215{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800216 LOGV("takePicture");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800217 sp <ICamera> c = mCamera;
218 if (c == 0) return NO_INIT;
219 return c->takePicture();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700220}
221
222// set preview/capture parameters - key/value pairs
223status_t Camera::setParameters(const String8& params)
224{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800225 LOGV("setParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800226 sp <ICamera> c = mCamera;
227 if (c == 0) return NO_INIT;
228 return c->setParameters(params);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700229}
230
231// get preview/capture parameters - key/value pairs
232String8 Camera::getParameters() const
233{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800234 LOGV("getParameters");
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800235 String8 params;
236 sp <ICamera> c = mCamera;
237 if (c != 0) params = mCamera->getParameters();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700238 return params;
239}
240
241void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
242{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800243 LOGV("setAutoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700244 mAutoFocusCallback = cb;
245 mAutoFocusCallbackCookie = cookie;
246}
247
248void Camera::setShutterCallback(shutter_callback cb, void *cookie)
249{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800250 LOGV("setShutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700251 mShutterCallback = cb;
252 mShutterCallbackCookie = cookie;
253}
254
255void Camera::setRawCallback(frame_callback cb, void *cookie)
256{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800257 LOGV("setRawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700258 mRawCallback = cb;
259 mRawCallbackCookie = cookie;
260}
261
262void Camera::setJpegCallback(frame_callback cb, void *cookie)
263{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800264 LOGV("setJpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700265 mJpegCallback = cb;
266 mJpegCallbackCookie = cookie;
267}
268
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800269void Camera::setFrameCallback(frame_callback cb, void *cookie, int frame_callback_flag)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700270{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800271 LOGV("setFrameCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700272 mFrameCallback = cb;
273 mFrameCallbackCookie = cookie;
The Android Open Source Project5f78a482009-01-20 14:03:58 -0800274 sp <ICamera> c = mCamera;
275 if (c == 0) return;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800276 mCamera->setFrameCallbackFlag(frame_callback_flag);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700277}
278
279void Camera::setErrorCallback(error_callback cb, void *cookie)
280{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800281 LOGV("setErrorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700282 mErrorCallback = cb;
283 mErrorCallbackCookie = cookie;
284}
285
286void Camera::autoFocusCallback(bool focused)
287{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800288 LOGV("autoFocusCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700289 if (mAutoFocusCallback) {
290 mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
291 }
292}
293
294void Camera::shutterCallback()
295{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800296 LOGV("shutterCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700297 if (mShutterCallback) {
298 mShutterCallback(mShutterCallbackCookie);
299 }
300}
301
302void Camera::rawCallback(const sp<IMemory>& picture)
303{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800304 LOGV("rawCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700305 if (mRawCallback) {
306 mRawCallback(picture, mRawCallbackCookie);
307 }
308}
309
310// callback from camera service when image is ready
311void Camera::jpegCallback(const sp<IMemory>& picture)
312{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800313 LOGV("jpegCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700314 if (mJpegCallback) {
315 mJpegCallback(picture, mJpegCallbackCookie);
316 }
317}
318
319// callback from camera service when video frame is ready
320void Camera::frameCallback(const sp<IMemory>& frame)
321{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800322 LOGV("frameCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700323 if (mFrameCallback) {
324 mFrameCallback(frame, mFrameCallbackCookie);
325 }
326}
327
328// callback from camera service when an error occurs in preview or takePicture
329void Camera::errorCallback(status_t error)
330{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800331 LOGV("errorCallback");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700332 if (mErrorCallback) {
333 mErrorCallback(error, mErrorCallbackCookie);
334 }
335}
336
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800337void Camera::binderDied(const wp<IBinder>& who) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700338 LOGW("ICamera died");
339 if (mErrorCallback) {
340 mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
341 }
342}
343
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800344void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
345 LOGV("binderDied");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700346 Mutex::Autolock _l(Camera::mLock);
347 Camera::mCameraService.clear();
348 LOGW("Camera server died!");
349}
350
351}; // namespace android
352