blob: 0fba82c74d4916094de33d98f22f73c608fd9d27 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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/IServiceManager.h>
23#include <utils/threads.h>
24#include <utils/IMemory.h>
25#include <ui/Surface.h>
26#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()
63{
64 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
James Dong2adc2db2009-04-23 14:07:23 -070078
79sp<Camera> Camera::create(const sp<ICamera>& camera)
80{
81 sp<Camera> c = new Camera();
82 // connect this client to existing camera remote
83 if (camera->connect(c) == NO_ERROR) {
84 c->mStatus = NO_ERROR;
85 c->mCamera = camera;
86 camera->asBinder()->linkToDeath(c);
87 }
88 return c;
89}
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091void Camera::init()
92{
93 mStatus = UNKNOWN_ERROR;
94 mShutterCallback = 0;
95 mShutterCallbackCookie = 0;
96 mRawCallback = 0;
97 mRawCallbackCookie = 0;
98 mJpegCallback = 0;
99 mJpegCallbackCookie = 0;
100 mPreviewCallback = 0;
101 mPreviewCallbackCookie = 0;
102 mRecordingCallback = 0;
103 mRecordingCallbackCookie = 0;
104 mErrorCallback = 0;
105 mErrorCallbackCookie = 0;
106 mAutoFocusCallback = 0;
107 mAutoFocusCallbackCookie = 0;
108}
109
110Camera::~Camera()
111{
112 disconnect();
113}
114
115sp<Camera> Camera::connect()
116{
117 LOGV("connect");
118 sp<Camera> c = new Camera();
119 const sp<ICameraService>& cs = getCameraService();
120 if (cs != 0) {
121 c->mCamera = cs->connect(c);
122 }
123 if (c->mCamera != 0) {
124 c->mCamera->asBinder()->linkToDeath(c);
125 c->mStatus = NO_ERROR;
126 } else {
127 c.clear();
128 }
129 return c;
130}
131
132void Camera::disconnect()
133{
134 LOGV("disconnect");
135 if (mCamera != 0) {
136 mErrorCallback = 0;
137 mCamera->disconnect();
138 mCamera = 0;
139 }
140}
141
142status_t Camera::reconnect()
143{
144 LOGV("reconnect");
145 sp <ICamera> c = mCamera;
146 if (c == 0) return NO_INIT;
147 return c->connect(this);
148}
149
150sp<ICamera> Camera::remote()
151{
152 return mCamera;
153}
154
155status_t Camera::lock()
156{
157 sp <ICamera> c = mCamera;
158 if (c == 0) return NO_INIT;
159 return c->lock();
160}
161
162status_t Camera::unlock()
163{
164 sp <ICamera> c = mCamera;
165 if (c == 0) return NO_INIT;
166 return c->unlock();
167}
168
169// pass the buffered ISurface to the camera service
170status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
171{
172 LOGV("setPreviewDisplay");
173 if (surface == 0) {
174 LOGE("app passed NULL surface");
175 return NO_INIT;
176 }
177 sp <ICamera> c = mCamera;
178 if (c == 0) return NO_INIT;
179 return c->setPreviewDisplay(surface->getISurface());
180}
181
182status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
183{
184 LOGV("setPreviewDisplay");
185 if (surface == 0) {
186 LOGE("app passed NULL surface");
187 return NO_INIT;
188 }
189 sp <ICamera> c = mCamera;
190 if (c == 0) return NO_INIT;
191 return c->setPreviewDisplay(surface);
192}
193
194
195// start preview mode, must call setPreviewDisplay first
196status_t Camera::startPreview()
197{
198 LOGV("startPreview");
199 sp <ICamera> c = mCamera;
200 if (c == 0) return NO_INIT;
201 return c->startPreview();
202}
203
204// start recording mode, must call setPreviewDisplay first
205status_t Camera::startRecording()
206{
207 LOGV("startRecording");
208 sp <ICamera> c = mCamera;
209 if (c == 0) return NO_INIT;
210 return c->startRecording();
211}
212
213// stop preview mode
214void Camera::stopPreview()
215{
216 LOGV("stopPreview");
217 sp <ICamera> c = mCamera;
218 if (c == 0) return;
219 c->stopPreview();
220}
221
222// stop recording mode
223void Camera::stopRecording()
224{
225 LOGV("stopRecording");
226 sp <ICamera> c = mCamera;
227 if (c == 0) return;
228 c->stopRecording();
229}
230
231// release a recording frame
232void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
233{
234 LOGV("releaseRecordingFrame");
235 sp <ICamera> c = mCamera;
236 if (c == 0) return;
237 c->releaseRecordingFrame(mem);
238}
239
240// get preview state
241bool Camera::previewEnabled()
242{
243 LOGV("previewEnabled");
244 sp <ICamera> c = mCamera;
245 if (c == 0) return false;
246 return c->previewEnabled();
247}
248
249// get recording state
250bool Camera::recordingEnabled()
251{
252 LOGV("recordingEnabled");
253 sp <ICamera> c = mCamera;
254 if (c == 0) return false;
255 return c->recordingEnabled();
256}
257
258status_t Camera::autoFocus()
259{
260 LOGV("autoFocus");
261 sp <ICamera> c = mCamera;
262 if (c == 0) return NO_INIT;
263 return c->autoFocus();
264}
265
266// take a picture
267status_t Camera::takePicture()
268{
269 LOGV("takePicture");
270 sp <ICamera> c = mCamera;
271 if (c == 0) return NO_INIT;
272 return c->takePicture();
273}
274
275// set preview/capture parameters - key/value pairs
276status_t Camera::setParameters(const String8& params)
277{
278 LOGV("setParameters");
279 sp <ICamera> c = mCamera;
280 if (c == 0) return NO_INIT;
281 return c->setParameters(params);
282}
283
284// get preview/capture parameters - key/value pairs
285String8 Camera::getParameters() const
286{
287 LOGV("getParameters");
288 String8 params;
289 sp <ICamera> c = mCamera;
290 if (c != 0) params = mCamera->getParameters();
291 return params;
292}
293
294void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
295{
296 LOGV("setAutoFocusCallback");
297 mAutoFocusCallback = cb;
298 mAutoFocusCallbackCookie = cookie;
299}
300
301void Camera::setShutterCallback(shutter_callback cb, void *cookie)
302{
303 LOGV("setShutterCallback");
304 mShutterCallback = cb;
305 mShutterCallbackCookie = cookie;
306}
307
308void Camera::setRawCallback(frame_callback cb, void *cookie)
309{
310 LOGV("setRawCallback");
311 mRawCallback = cb;
312 mRawCallbackCookie = cookie;
313}
314
315void Camera::setJpegCallback(frame_callback cb, void *cookie)
316{
317 LOGV("setJpegCallback");
318 mJpegCallback = cb;
319 mJpegCallbackCookie = cookie;
320}
321
322void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
323{
324 LOGV("setPreviewCallback");
325 mPreviewCallback = cb;
326 mPreviewCallbackCookie = cookie;
327 sp <ICamera> c = mCamera;
328 if (c == 0) return;
329 mCamera->setPreviewCallbackFlag(flag);
330}
331
332void Camera::setRecordingCallback(frame_callback cb, void *cookie)
333{
334 LOGV("setRecordingCallback");
335 mRecordingCallback = cb;
336 mRecordingCallbackCookie = cookie;
337}
338
339void Camera::setErrorCallback(error_callback cb, void *cookie)
340{
341 LOGV("setErrorCallback");
342 mErrorCallback = cb;
343 mErrorCallbackCookie = cookie;
344}
345
346void Camera::autoFocusCallback(bool focused)
347{
348 LOGV("autoFocusCallback");
349 if (mAutoFocusCallback) {
350 mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
351 }
352}
353
354void Camera::shutterCallback()
355{
356 LOGV("shutterCallback");
357 if (mShutterCallback) {
358 mShutterCallback(mShutterCallbackCookie);
359 }
360}
361
362void Camera::rawCallback(const sp<IMemory>& picture)
363{
364 LOGV("rawCallback");
365 if (mRawCallback) {
366 mRawCallback(picture, mRawCallbackCookie);
367 }
368}
369
370// callback from camera service when image is ready
371void Camera::jpegCallback(const sp<IMemory>& picture)
372{
373 LOGV("jpegCallback");
374 if (mJpegCallback) {
375 mJpegCallback(picture, mJpegCallbackCookie);
376 }
377}
378
379// callback from camera service when preview frame is ready
380void Camera::previewCallback(const sp<IMemory>& frame)
381{
382 LOGV("frameCallback");
383 if (mPreviewCallback) {
384 mPreviewCallback(frame, mPreviewCallbackCookie);
385 }
386}
387
388// callback from camera service when a recording frame is ready
389void Camera::recordingCallback(const sp<IMemory>& frame)
390{
391 LOGV("recordingCallback");
392 if (mRecordingCallback) {
393 mRecordingCallback(frame, mRecordingCallbackCookie);
394 }
395}
396
397// callback from camera service when an error occurs in preview or takePicture
398void Camera::errorCallback(status_t error)
399{
400 LOGV("errorCallback");
401 if (mErrorCallback) {
402 mErrorCallback(error, mErrorCallbackCookie);
403 }
404}
405
406void Camera::binderDied(const wp<IBinder>& who) {
407 LOGW("ICamera died");
408 if (mErrorCallback) {
409 mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
410 }
411}
412
413void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
414 LOGV("binderDied");
415 Mutex::Autolock _l(Camera::mLock);
416 Camera::mCameraService.clear();
417 LOGW("Camera server died!");
418}
419
420}; // namespace android
421