blob: 148e86407e4e6e0b1fdb28f28fa2bdb1c023cc16 [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>
Mathias Agopian000479f2010-02-09 17:46:37 -080022
23#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>
27#include <camera/ICameraService.h>
28
29#include <surfaceflinger/Surface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31namespace android {
32
33// client singleton for camera service binder interface
34Mutex Camera::mLock;
35sp<ICameraService> Camera::mCameraService;
36sp<Camera::DeathNotifier> Camera::mDeathNotifier;
37
38// establish binder interface to camera service
39const sp<ICameraService>& Camera::getCameraService()
40{
41 Mutex::Autolock _l(mLock);
42 if (mCameraService.get() == 0) {
43 sp<IServiceManager> sm = defaultServiceManager();
44 sp<IBinder> binder;
45 do {
46 binder = sm->getService(String16("media.camera"));
47 if (binder != 0)
48 break;
49 LOGW("CameraService not published, waiting...");
50 usleep(500000); // 0.5 s
51 } while(true);
52 if (mDeathNotifier == NULL) {
53 mDeathNotifier = new DeathNotifier();
54 }
55 binder->linkToDeath(mDeathNotifier);
56 mCameraService = interface_cast<ICameraService>(binder);
57 }
58 LOGE_IF(mCameraService==0, "no CameraService!?");
59 return mCameraService;
60}
61
62// ---------------------------------------------------------------------------
63
64Camera::Camera()
65{
66 init();
67}
68
James Dong325ac472009-04-27 12:01:59 -070069// construct a camera client from an existing camera remote
James Dong2adc2db2009-04-23 14:07:23 -070070sp<Camera> Camera::create(const sp<ICamera>& camera)
71{
James Dong325ac472009-04-27 12:01:59 -070072 LOGV("create");
73 if (camera == 0) {
74 LOGE("camera remote is a NULL pointer");
75 return 0;
76 }
77
James Dong2adc2db2009-04-23 14:07:23 -070078 sp<Camera> c = new Camera();
James Dong2adc2db2009-04-23 14:07:23 -070079 if (camera->connect(c) == NO_ERROR) {
80 c->mStatus = NO_ERROR;
81 c->mCamera = camera;
82 camera->asBinder()->linkToDeath(c);
83 }
84 return c;
85}
86
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087void Camera::init()
88{
89 mStatus = UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090}
91
92Camera::~Camera()
93{
Chih-Chung Chang553447b2010-05-13 15:14:24 +080094 // We don't need to call disconnect() here because if the CameraService
95 // thinks we are the owner of the hardware, it will hold a (strong)
96 // reference to us, and we can't possibly be here. We also don't want to
97 // call disconnect() here if we are in the same process as mediaserver,
98 // because we may be invoked by CameraService::Client::connect() and will
99 // deadlock if we call any method of ICamera here.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100}
101
Chih-Chung Change25cc652010-05-06 16:36:58 +0800102int32_t Camera::getNumberOfCameras()
103{
104 const sp<ICameraService>& cs = getCameraService();
105 if (cs == 0) return 0;
106 return cs->getNumberOfCameras();
107}
108
Chih-Chung Changb8bb78f2010-06-10 13:32:16 +0800109status_t Camera::getCameraInfo(int cameraId,
110 struct CameraInfo* cameraInfo) {
111 const sp<ICameraService>& cs = getCameraService();
112 if (cs == 0) return UNKNOWN_ERROR;
113 return cs->getCameraInfo(cameraId, cameraInfo);
114}
115
Chih-Chung Change25cc652010-05-06 16:36:58 +0800116sp<Camera> Camera::connect(int cameraId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117{
118 LOGV("connect");
119 sp<Camera> c = new Camera();
120 const sp<ICameraService>& cs = getCameraService();
121 if (cs != 0) {
Chih-Chung Change25cc652010-05-06 16:36:58 +0800122 c->mCamera = cs->connect(c, cameraId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 }
124 if (c->mCamera != 0) {
125 c->mCamera->asBinder()->linkToDeath(c);
126 c->mStatus = NO_ERROR;
127 } else {
128 c.clear();
129 }
130 return c;
131}
132
133void Camera::disconnect()
134{
135 LOGV("disconnect");
136 if (mCamera != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 mCamera->disconnect();
Chih-Chung Changcfea8fd2010-03-24 16:38:02 -0700138 mCamera->asBinder()->unlinkToDeath(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 mCamera = 0;
140 }
141}
142
143status_t Camera::reconnect()
144{
145 LOGV("reconnect");
146 sp <ICamera> c = mCamera;
147 if (c == 0) return NO_INIT;
148 return c->connect(this);
149}
150
151sp<ICamera> Camera::remote()
152{
153 return mCamera;
154}
155
156status_t Camera::lock()
157{
158 sp <ICamera> c = mCamera;
159 if (c == 0) return NO_INIT;
160 return c->lock();
161}
162
163status_t Camera::unlock()
164{
165 sp <ICamera> c = mCamera;
166 if (c == 0) return NO_INIT;
167 return c->unlock();
168}
169
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700170// pass the buffered Surface to the camera service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
172{
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700173 LOGV("setPreviewDisplay(%p)", surface.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 sp <ICamera> c = mCamera;
175 if (c == 0) return NO_INIT;
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800176 if (surface != 0) {
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700177 return c->setPreviewDisplay(surface);
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800178 } else {
179 LOGD("app passed NULL surface");
180 return c->setPreviewDisplay(0);
181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182}
183
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800184// start preview mode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185status_t Camera::startPreview()
186{
187 LOGV("startPreview");
188 sp <ICamera> c = mCamera;
189 if (c == 0) return NO_INIT;
190 return c->startPreview();
191}
192
James Dong38311852010-10-18 20:42:51 -0700193int32_t Camera::getNumberOfVideoBuffers() const
194{
195 LOGV("getNumberOfVideoBuffers");
196 sp <ICamera> c = mCamera;
197 if (c == 0) return 0;
198 return c->getNumberOfVideoBuffers();
199}
200
201sp<IMemory> Camera::getVideoBuffer(int32_t index) const
202{
203 LOGV("getVideoBuffer: %d", index);
204 sp <ICamera> c = mCamera;
205 if (c == 0) return 0;
206 return c->getVideoBuffer(index);
207}
208
209status_t Camera::storeMetaDataInBuffers(bool enabled)
210{
211 LOGV("storeMetaDataInBuffers: %s",
212 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{
221 LOGV("startRecording");
222 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{
230 LOGV("stopPreview");
231 sp <ICamera> c = mCamera;
232 if (c == 0) return;
233 c->stopPreview();
234}
235
236// stop recording mode
237void Camera::stopRecording()
238{
239 LOGV("stopRecording");
240 sp <ICamera> c = mCamera;
241 if (c == 0) return;
242 c->stopRecording();
243}
244
245// release a recording frame
246void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
247{
248 LOGV("releaseRecordingFrame");
249 sp <ICamera> c = mCamera;
250 if (c == 0) return;
251 c->releaseRecordingFrame(mem);
252}
253
254// get preview state
255bool Camera::previewEnabled()
256{
257 LOGV("previewEnabled");
258 sp <ICamera> c = mCamera;
259 if (c == 0) return false;
260 return c->previewEnabled();
261}
262
263// get recording state
264bool Camera::recordingEnabled()
265{
266 LOGV("recordingEnabled");
267 sp <ICamera> c = mCamera;
268 if (c == 0) return false;
269 return c->recordingEnabled();
270}
271
272status_t Camera::autoFocus()
273{
274 LOGV("autoFocus");
275 sp <ICamera> c = mCamera;
276 if (c == 0) return NO_INIT;
277 return c->autoFocus();
278}
279
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800280status_t Camera::cancelAutoFocus()
281{
282 LOGV("cancelAutoFocus");
283 sp <ICamera> c = mCamera;
284 if (c == 0) return NO_INIT;
285 return c->cancelAutoFocus();
286}
287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288// take a picture
289status_t Camera::takePicture()
290{
291 LOGV("takePicture");
292 sp <ICamera> c = mCamera;
293 if (c == 0) return NO_INIT;
294 return c->takePicture();
295}
296
297// set preview/capture parameters - key/value pairs
298status_t Camera::setParameters(const String8& params)
299{
300 LOGV("setParameters");
301 sp <ICamera> c = mCamera;
302 if (c == 0) return NO_INIT;
303 return c->setParameters(params);
304}
305
306// get preview/capture parameters - key/value pairs
307String8 Camera::getParameters() const
308{
309 LOGV("getParameters");
310 String8 params;
311 sp <ICamera> c = mCamera;
312 if (c != 0) params = mCamera->getParameters();
313 return params;
314}
315
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700316// send command to camera driver
317status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
318{
Wu-cheng Lica9d9dc2010-02-10 13:01:48 +0800319 LOGV("sendCommand");
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700320 sp <ICamera> c = mCamera;
321 if (c == 0) return NO_INIT;
322 return c->sendCommand(cmd, arg1, arg2);
323}
324
Dave Sparks5e271152009-06-23 17:30:11 -0700325void Camera::setListener(const sp<CameraListener>& listener)
326{
327 Mutex::Autolock _l(mLock);
328 mListener = listener;
329}
330
331void Camera::setPreviewCallbackFlags(int flag)
332{
333 LOGV("setPreviewCallbackFlags");
334 sp <ICamera> c = mCamera;
335 if (c == 0) return;
336 mCamera->setPreviewCallbackFlag(flag);
337}
338
Dave Sparks2a04aef2009-05-07 12:25:25 -0700339// callback from camera service
340void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
341{
Dave Sparks5e271152009-06-23 17:30:11 -0700342 sp<CameraListener> listener;
343 {
344 Mutex::Autolock _l(mLock);
345 listener = mListener;
346 }
347 if (listener != NULL) {
348 listener->notify(msgType, ext1, ext2);
349 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700350}
351
Dave Sparksd6289b12009-05-07 19:27:32 -0700352// callback from camera service when frame or image is ready
353void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700354{
Dave Sparks5e271152009-06-23 17:30:11 -0700355 sp<CameraListener> listener;
356 {
357 Mutex::Autolock _l(mLock);
358 listener = mListener;
359 }
360 if (listener != NULL) {
361 listener->postData(msgType, dataPtr);
362 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700363}
364
Dave Sparks59c1a932009-07-08 15:56:53 -0700365// callback from camera service when timestamped frame is ready
366void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
367{
368 sp<CameraListener> listener;
369 {
370 Mutex::Autolock _l(mLock);
371 listener = mListener;
372 }
373 if (listener != NULL) {
374 listener->postDataTimestamp(timestamp, msgType, dataPtr);
375 }
376}
377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378void Camera::binderDied(const wp<IBinder>& who) {
379 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700380 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381}
382
383void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
384 LOGV("binderDied");
385 Mutex::Autolock _l(Camera::mLock);
386 Camera::mCameraService.clear();
387 LOGW("Camera server died!");
388}
389
390}; // namespace android