blob: eef1dd2ef2c1e0c89d8ccf9c1253000aedcbd07f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2**
3** Copyright (C) 2008, The Android Open Source Project
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004**
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>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <utils/threads.h>
Wu-cheng Li42419ce2011-06-01 17:22:24 +080022#include <binder/IPCThreadState.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080023#include <binder/IServiceManager.h>
Mathias Agopian07952722009-05-19 19:08:10 -070024#include <binder/IMemory.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080025
26#include <camera/Camera.h>
Wu-cheng Li42419ce2011-06-01 17:22:24 +080027#include <camera/ICameraRecordingProxyListener.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080028#include <camera/ICameraService.h>
29
30#include <surfaceflinger/Surface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
32namespace android {
33
34// client singleton for camera service binder interface
35Mutex Camera::mLock;
36sp<ICameraService> Camera::mCameraService;
37sp<Camera::DeathNotifier> Camera::mDeathNotifier;
38
39// establish binder interface to camera service
40const sp<ICameraService>& Camera::getCameraService()
41{
42 Mutex::Autolock _l(mLock);
43 if (mCameraService.get() == 0) {
44 sp<IServiceManager> sm = defaultServiceManager();
45 sp<IBinder> binder;
46 do {
47 binder = sm->getService(String16("media.camera"));
48 if (binder != 0)
49 break;
50 LOGW("CameraService not published, waiting...");
51 usleep(500000); // 0.5 s
52 } while(true);
53 if (mDeathNotifier == NULL) {
54 mDeathNotifier = new DeathNotifier();
55 }
56 binder->linkToDeath(mDeathNotifier);
57 mCameraService = interface_cast<ICameraService>(binder);
58 }
59 LOGE_IF(mCameraService==0, "no CameraService!?");
60 return mCameraService;
61}
62
63// ---------------------------------------------------------------------------
64
65Camera::Camera()
66{
67 init();
68}
69
James Dong325ac472009-04-27 12:01:59 -070070// construct a camera client from an existing camera remote
James Dong2adc2db2009-04-23 14:07:23 -070071sp<Camera> Camera::create(const sp<ICamera>& camera)
72{
Steve Block71f2cf12011-10-20 11:56:00 +010073 ALOGV("create");
James Dong325ac472009-04-27 12:01:59 -070074 if (camera == 0) {
75 LOGE("camera remote is a NULL pointer");
76 return 0;
77 }
78
James Dong2adc2db2009-04-23 14:07:23 -070079 sp<Camera> c = new Camera();
James Dong2adc2db2009-04-23 14:07:23 -070080 if (camera->connect(c) == NO_ERROR) {
81 c->mStatus = NO_ERROR;
82 c->mCamera = camera;
83 camera->asBinder()->linkToDeath(c);
Wu-cheng Li0e73cdc2011-01-04 20:00:55 +080084 return c;
James Dong2adc2db2009-04-23 14:07:23 -070085 }
Wu-cheng Li0e73cdc2011-01-04 20:00:55 +080086 return 0;
James Dong2adc2db2009-04-23 14:07:23 -070087}
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089void Camera::init()
90{
91 mStatus = UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092}
93
94Camera::~Camera()
95{
Chih-Chung Chang553447b2010-05-13 15:14:24 +080096 // We don't need to call disconnect() here because if the CameraService
97 // thinks we are the owner of the hardware, it will hold a (strong)
98 // reference to us, and we can't possibly be here. We also don't want to
99 // call disconnect() here if we are in the same process as mediaserver,
100 // because we may be invoked by CameraService::Client::connect() and will
101 // deadlock if we call any method of ICamera here.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102}
103
Chih-Chung Change25cc652010-05-06 16:36:58 +0800104int32_t Camera::getNumberOfCameras()
105{
106 const sp<ICameraService>& cs = getCameraService();
107 if (cs == 0) return 0;
108 return cs->getNumberOfCameras();
109}
110
Chih-Chung Changb8bb78f2010-06-10 13:32:16 +0800111status_t Camera::getCameraInfo(int cameraId,
112 struct CameraInfo* cameraInfo) {
113 const sp<ICameraService>& cs = getCameraService();
114 if (cs == 0) return UNKNOWN_ERROR;
115 return cs->getCameraInfo(cameraId, cameraInfo);
116}
117
Chih-Chung Change25cc652010-05-06 16:36:58 +0800118sp<Camera> Camera::connect(int cameraId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119{
Steve Block71f2cf12011-10-20 11:56:00 +0100120 ALOGV("connect");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 sp<Camera> c = new Camera();
122 const sp<ICameraService>& cs = getCameraService();
123 if (cs != 0) {
Chih-Chung Change25cc652010-05-06 16:36:58 +0800124 c->mCamera = cs->connect(c, cameraId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 }
126 if (c->mCamera != 0) {
127 c->mCamera->asBinder()->linkToDeath(c);
128 c->mStatus = NO_ERROR;
129 } else {
130 c.clear();
131 }
132 return c;
133}
134
135void Camera::disconnect()
136{
Steve Block71f2cf12011-10-20 11:56:00 +0100137 ALOGV("disconnect");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 if (mCamera != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 mCamera->disconnect();
Chih-Chung Changcfea8fd2010-03-24 16:38:02 -0700140 mCamera->asBinder()->unlinkToDeath(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 mCamera = 0;
142 }
143}
144
145status_t Camera::reconnect()
146{
Steve Block71f2cf12011-10-20 11:56:00 +0100147 ALOGV("reconnect");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 sp <ICamera> c = mCamera;
149 if (c == 0) return NO_INIT;
150 return c->connect(this);
151}
152
153sp<ICamera> Camera::remote()
154{
155 return mCamera;
156}
157
158status_t Camera::lock()
159{
160 sp <ICamera> c = mCamera;
161 if (c == 0) return NO_INIT;
162 return c->lock();
163}
164
165status_t Camera::unlock()
166{
167 sp <ICamera> c = mCamera;
168 if (c == 0) return NO_INIT;
169 return c->unlock();
170}
171
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700172// pass the buffered Surface to the camera service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
174{
Steve Block71f2cf12011-10-20 11:56:00 +0100175 ALOGV("setPreviewDisplay(%p)", surface.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 sp <ICamera> c = mCamera;
177 if (c == 0) return NO_INIT;
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800178 if (surface != 0) {
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700179 return c->setPreviewDisplay(surface);
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800180 } else {
Steve Block5baa3a62011-12-20 16:23:08 +0000181 ALOGD("app passed NULL surface");
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800182 return c->setPreviewDisplay(0);
183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184}
185
Jamie Gennisff2dc462010-12-20 11:51:31 -0800186// pass the buffered ISurfaceTexture to the camera service
187status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
188{
Steve Block71f2cf12011-10-20 11:56:00 +0100189 ALOGV("setPreviewTexture(%p)", surfaceTexture.get());
Jamie Gennisff2dc462010-12-20 11:51:31 -0800190 sp <ICamera> c = mCamera;
191 if (c == 0) return NO_INIT;
192 if (surfaceTexture != 0) {
193 return c->setPreviewTexture(surfaceTexture);
194 } else {
Steve Block5baa3a62011-12-20 16:23:08 +0000195 ALOGD("app passed NULL surface");
Jamie Gennisff2dc462010-12-20 11:51:31 -0800196 return c->setPreviewTexture(0);
197 }
198}
199
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800200// start preview mode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201status_t Camera::startPreview()
202{
Steve Block71f2cf12011-10-20 11:56:00 +0100203 ALOGV("startPreview");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 sp <ICamera> c = mCamera;
205 if (c == 0) return NO_INIT;
206 return c->startPreview();
207}
208
James Dong38311852010-10-18 20:42:51 -0700209status_t Camera::storeMetaDataInBuffers(bool enabled)
210{
Steve Block71f2cf12011-10-20 11:56:00 +0100211 ALOGV("storeMetaDataInBuffers: %s",
James Dong38311852010-10-18 20:42:51 -0700212 enabled? "true": "false");
213 sp <ICamera> c = mCamera;
214 if (c == 0) return NO_INIT;
215 return c->storeMetaDataInBuffers(enabled);
216}
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218// start recording mode, must call setPreviewDisplay first
219status_t Camera::startRecording()
220{
Steve Block71f2cf12011-10-20 11:56:00 +0100221 ALOGV("startRecording");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 sp <ICamera> c = mCamera;
223 if (c == 0) return NO_INIT;
224 return c->startRecording();
225}
226
227// stop preview mode
228void Camera::stopPreview()
229{
Steve Block71f2cf12011-10-20 11:56:00 +0100230 ALOGV("stopPreview");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 sp <ICamera> c = mCamera;
232 if (c == 0) return;
233 c->stopPreview();
234}
235
236// stop recording mode
237void Camera::stopRecording()
238{
Steve Block71f2cf12011-10-20 11:56:00 +0100239 ALOGV("stopRecording");
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800240 {
241 Mutex::Autolock _l(mLock);
242 mRecordingProxyListener.clear();
243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 sp <ICamera> c = mCamera;
245 if (c == 0) return;
246 c->stopRecording();
247}
248
249// release a recording frame
250void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
251{
Steve Block71f2cf12011-10-20 11:56:00 +0100252 ALOGV("releaseRecordingFrame");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 sp <ICamera> c = mCamera;
254 if (c == 0) return;
255 c->releaseRecordingFrame(mem);
256}
257
258// get preview state
259bool Camera::previewEnabled()
260{
Steve Block71f2cf12011-10-20 11:56:00 +0100261 ALOGV("previewEnabled");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 sp <ICamera> c = mCamera;
263 if (c == 0) return false;
264 return c->previewEnabled();
265}
266
267// get recording state
268bool Camera::recordingEnabled()
269{
Steve Block71f2cf12011-10-20 11:56:00 +0100270 ALOGV("recordingEnabled");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 sp <ICamera> c = mCamera;
272 if (c == 0) return false;
273 return c->recordingEnabled();
274}
275
276status_t Camera::autoFocus()
277{
Steve Block71f2cf12011-10-20 11:56:00 +0100278 ALOGV("autoFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 sp <ICamera> c = mCamera;
280 if (c == 0) return NO_INIT;
281 return c->autoFocus();
282}
283
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800284status_t Camera::cancelAutoFocus()
285{
Steve Block71f2cf12011-10-20 11:56:00 +0100286 ALOGV("cancelAutoFocus");
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800287 sp <ICamera> c = mCamera;
288 if (c == 0) return NO_INIT;
289 return c->cancelAutoFocus();
290}
291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292// take a picture
James Donge00cab72011-02-17 16:38:06 -0800293status_t Camera::takePicture(int msgType)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294{
Steve Block71f2cf12011-10-20 11:56:00 +0100295 ALOGV("takePicture: 0x%x", msgType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 sp <ICamera> c = mCamera;
297 if (c == 0) return NO_INIT;
James Donge00cab72011-02-17 16:38:06 -0800298 return c->takePicture(msgType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299}
300
301// set preview/capture parameters - key/value pairs
302status_t Camera::setParameters(const String8& params)
303{
Steve Block71f2cf12011-10-20 11:56:00 +0100304 ALOGV("setParameters");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 sp <ICamera> c = mCamera;
306 if (c == 0) return NO_INIT;
307 return c->setParameters(params);
308}
309
310// get preview/capture parameters - key/value pairs
311String8 Camera::getParameters() const
312{
Steve Block71f2cf12011-10-20 11:56:00 +0100313 ALOGV("getParameters");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 String8 params;
315 sp <ICamera> c = mCamera;
316 if (c != 0) params = mCamera->getParameters();
317 return params;
318}
319
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700320// send command to camera driver
321status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
322{
Steve Block71f2cf12011-10-20 11:56:00 +0100323 ALOGV("sendCommand");
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700324 sp <ICamera> c = mCamera;
325 if (c == 0) return NO_INIT;
326 return c->sendCommand(cmd, arg1, arg2);
327}
328
Dave Sparks5e271152009-06-23 17:30:11 -0700329void Camera::setListener(const sp<CameraListener>& listener)
330{
331 Mutex::Autolock _l(mLock);
332 mListener = listener;
333}
334
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800335void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
336{
337 Mutex::Autolock _l(mLock);
338 mRecordingProxyListener = listener;
339}
340
Dave Sparks5e271152009-06-23 17:30:11 -0700341void Camera::setPreviewCallbackFlags(int flag)
342{
Steve Block71f2cf12011-10-20 11:56:00 +0100343 ALOGV("setPreviewCallbackFlags");
Dave Sparks5e271152009-06-23 17:30:11 -0700344 sp <ICamera> c = mCamera;
345 if (c == 0) return;
346 mCamera->setPreviewCallbackFlag(flag);
347}
348
Dave Sparks2a04aef2009-05-07 12:25:25 -0700349// callback from camera service
350void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
351{
Dave Sparks5e271152009-06-23 17:30:11 -0700352 sp<CameraListener> listener;
353 {
354 Mutex::Autolock _l(mLock);
355 listener = mListener;
356 }
357 if (listener != NULL) {
358 listener->notify(msgType, ext1, ext2);
359 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700360}
361
Dave Sparksd6289b12009-05-07 19:27:32 -0700362// callback from camera service when frame or image is ready
Wu-cheng Libb1e2752011-07-30 05:00:37 +0800363void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
364 camera_frame_metadata_t *metadata)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700365{
Dave Sparks5e271152009-06-23 17:30:11 -0700366 sp<CameraListener> listener;
367 {
368 Mutex::Autolock _l(mLock);
369 listener = mListener;
370 }
371 if (listener != NULL) {
Wu-cheng Libb1e2752011-07-30 05:00:37 +0800372 listener->postData(msgType, dataPtr, metadata);
Dave Sparks5e271152009-06-23 17:30:11 -0700373 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700374}
375
Dave Sparks59c1a932009-07-08 15:56:53 -0700376// callback from camera service when timestamped frame is ready
377void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
378{
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800379 // If recording proxy listener is registered, forward the frame and return.
380 // The other listener (mListener) is ignored because the receiver needs to
381 // call releaseRecordingFrame.
382 sp<ICameraRecordingProxyListener> proxylistener;
383 {
384 Mutex::Autolock _l(mLock);
385 proxylistener = mRecordingProxyListener;
386 }
387 if (proxylistener != NULL) {
388 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
389 return;
390 }
391
Dave Sparks59c1a932009-07-08 15:56:53 -0700392 sp<CameraListener> listener;
393 {
394 Mutex::Autolock _l(mLock);
395 listener = mListener;
396 }
397 if (listener != NULL) {
398 listener->postDataTimestamp(timestamp, msgType, dataPtr);
James Dongdf7a8562010-11-15 10:38:37 -0800399 } else {
400 LOGW("No listener was set. Drop a recording frame.");
401 releaseRecordingFrame(dataPtr);
Dave Sparks59c1a932009-07-08 15:56:53 -0700402 }
403}
404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405void Camera::binderDied(const wp<IBinder>& who) {
406 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700407 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408}
409
410void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
Steve Block71f2cf12011-10-20 11:56:00 +0100411 ALOGV("binderDied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 Mutex::Autolock _l(Camera::mLock);
413 Camera::mCameraService.clear();
414 LOGW("Camera server died!");
415}
416
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800417sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block71f2cf12011-10-20 11:56:00 +0100418 ALOGV("getProxy");
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800419 return new RecordingProxy(this);
420}
421
422status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
423{
Steve Block71f2cf12011-10-20 11:56:00 +0100424 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800425 mCamera->setRecordingProxyListener(listener);
426 mCamera->reconnect();
427 return mCamera->startRecording();
428}
429
430void Camera::RecordingProxy::stopRecording()
431{
Steve Block71f2cf12011-10-20 11:56:00 +0100432 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800433 mCamera->stopRecording();
434}
435
436void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
437{
Steve Block71f2cf12011-10-20 11:56:00 +0100438 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li42419ce2011-06-01 17:22:24 +0800439 mCamera->releaseRecordingFrame(mem);
440}
441
442Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
443{
444 mCamera = camera;
445}
446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447}; // namespace android