blob: e2883121e497417cf9a910e3ec455aa5c146943f [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);
Wu-cheng Li0e73cdc2011-01-04 20:00:55 +080083 return c;
James Dong2adc2db2009-04-23 14:07:23 -070084 }
Wu-cheng Li0e73cdc2011-01-04 20:00:55 +080085 return 0;
James Dong2adc2db2009-04-23 14:07:23 -070086}
87
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088void Camera::init()
89{
90 mStatus = UNKNOWN_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091}
92
93Camera::~Camera()
94{
Chih-Chung Chang553447b2010-05-13 15:14:24 +080095 // We don't need to call disconnect() here because if the CameraService
96 // thinks we are the owner of the hardware, it will hold a (strong)
97 // reference to us, and we can't possibly be here. We also don't want to
98 // call disconnect() here if we are in the same process as mediaserver,
99 // because we may be invoked by CameraService::Client::connect() and will
100 // deadlock if we call any method of ICamera here.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101}
102
Chih-Chung Change25cc652010-05-06 16:36:58 +0800103int32_t Camera::getNumberOfCameras()
104{
105 const sp<ICameraService>& cs = getCameraService();
106 if (cs == 0) return 0;
107 return cs->getNumberOfCameras();
108}
109
Chih-Chung Changb8bb78f2010-06-10 13:32:16 +0800110status_t Camera::getCameraInfo(int cameraId,
111 struct CameraInfo* cameraInfo) {
112 const sp<ICameraService>& cs = getCameraService();
113 if (cs == 0) return UNKNOWN_ERROR;
114 return cs->getCameraInfo(cameraId, cameraInfo);
115}
116
Chih-Chung Change25cc652010-05-06 16:36:58 +0800117sp<Camera> Camera::connect(int cameraId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118{
119 LOGV("connect");
120 sp<Camera> c = new Camera();
121 const sp<ICameraService>& cs = getCameraService();
122 if (cs != 0) {
Chih-Chung Change25cc652010-05-06 16:36:58 +0800123 c->mCamera = cs->connect(c, cameraId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 }
125 if (c->mCamera != 0) {
126 c->mCamera->asBinder()->linkToDeath(c);
127 c->mStatus = NO_ERROR;
128 } else {
129 c.clear();
130 }
131 return c;
132}
133
134void Camera::disconnect()
135{
136 LOGV("disconnect");
137 if (mCamera != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 mCamera->disconnect();
Chih-Chung Changcfea8fd2010-03-24 16:38:02 -0700139 mCamera->asBinder()->unlinkToDeath(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 mCamera = 0;
141 }
142}
143
144status_t Camera::reconnect()
145{
146 LOGV("reconnect");
147 sp <ICamera> c = mCamera;
148 if (c == 0) return NO_INIT;
149 return c->connect(this);
150}
151
152sp<ICamera> Camera::remote()
153{
154 return mCamera;
155}
156
157status_t Camera::lock()
158{
159 sp <ICamera> c = mCamera;
160 if (c == 0) return NO_INIT;
161 return c->lock();
162}
163
164status_t Camera::unlock()
165{
166 sp <ICamera> c = mCamera;
167 if (c == 0) return NO_INIT;
168 return c->unlock();
169}
170
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700171// pass the buffered Surface to the camera service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
173{
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700174 LOGV("setPreviewDisplay(%p)", surface.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 sp <ICamera> c = mCamera;
176 if (c == 0) return NO_INIT;
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800177 if (surface != 0) {
Jamie Gennis85cfdd02010-08-10 16:37:53 -0700178 return c->setPreviewDisplay(surface);
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800179 } else {
180 LOGD("app passed NULL surface");
181 return c->setPreviewDisplay(0);
182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183}
184
Jamie Gennisff2dc462010-12-20 11:51:31 -0800185// pass the buffered ISurfaceTexture to the camera service
186status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
187{
188 LOGV("setPreviewTexture(%p)", surfaceTexture.get());
189 sp <ICamera> c = mCamera;
190 if (c == 0) return NO_INIT;
191 if (surfaceTexture != 0) {
192 return c->setPreviewTexture(surfaceTexture);
193 } else {
194 LOGD("app passed NULL surface");
195 return c->setPreviewTexture(0);
196 }
197}
198
Wu-cheng Lib8a10fe2009-06-23 23:37:36 +0800199// start preview mode
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200status_t Camera::startPreview()
201{
202 LOGV("startPreview");
203 sp <ICamera> c = mCamera;
204 if (c == 0) return NO_INIT;
205 return c->startPreview();
206}
207
James Dong38311852010-10-18 20:42:51 -0700208int32_t Camera::getNumberOfVideoBuffers() const
209{
210 LOGV("getNumberOfVideoBuffers");
211 sp <ICamera> c = mCamera;
212 if (c == 0) return 0;
213 return c->getNumberOfVideoBuffers();
214}
215
216sp<IMemory> Camera::getVideoBuffer(int32_t index) const
217{
218 LOGV("getVideoBuffer: %d", index);
219 sp <ICamera> c = mCamera;
220 if (c == 0) return 0;
221 return c->getVideoBuffer(index);
222}
223
224status_t Camera::storeMetaDataInBuffers(bool enabled)
225{
226 LOGV("storeMetaDataInBuffers: %s",
227 enabled? "true": "false");
228 sp <ICamera> c = mCamera;
229 if (c == 0) return NO_INIT;
230 return c->storeMetaDataInBuffers(enabled);
231}
232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233// start recording mode, must call setPreviewDisplay first
234status_t Camera::startRecording()
235{
236 LOGV("startRecording");
237 sp <ICamera> c = mCamera;
238 if (c == 0) return NO_INIT;
239 return c->startRecording();
240}
241
242// stop preview mode
243void Camera::stopPreview()
244{
245 LOGV("stopPreview");
246 sp <ICamera> c = mCamera;
247 if (c == 0) return;
248 c->stopPreview();
249}
250
251// stop recording mode
252void Camera::stopRecording()
253{
254 LOGV("stopRecording");
255 sp <ICamera> c = mCamera;
256 if (c == 0) return;
257 c->stopRecording();
258}
259
260// release a recording frame
261void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
262{
263 LOGV("releaseRecordingFrame");
264 sp <ICamera> c = mCamera;
265 if (c == 0) return;
266 c->releaseRecordingFrame(mem);
267}
268
269// get preview state
270bool Camera::previewEnabled()
271{
272 LOGV("previewEnabled");
273 sp <ICamera> c = mCamera;
274 if (c == 0) return false;
275 return c->previewEnabled();
276}
277
278// get recording state
279bool Camera::recordingEnabled()
280{
281 LOGV("recordingEnabled");
282 sp <ICamera> c = mCamera;
283 if (c == 0) return false;
284 return c->recordingEnabled();
285}
286
287status_t Camera::autoFocus()
288{
289 LOGV("autoFocus");
290 sp <ICamera> c = mCamera;
291 if (c == 0) return NO_INIT;
292 return c->autoFocus();
293}
294
Chih-Chung Chang244f8c22009-09-15 14:51:56 +0800295status_t Camera::cancelAutoFocus()
296{
297 LOGV("cancelAutoFocus");
298 sp <ICamera> c = mCamera;
299 if (c == 0) return NO_INIT;
300 return c->cancelAutoFocus();
301}
302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303// take a picture
James Donge00cab72011-02-17 16:38:06 -0800304status_t Camera::takePicture(int msgType)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305{
James Donge00cab72011-02-17 16:38:06 -0800306 LOGV("takePicture: 0x%x", msgType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 sp <ICamera> c = mCamera;
308 if (c == 0) return NO_INIT;
James Donge00cab72011-02-17 16:38:06 -0800309 return c->takePicture(msgType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310}
311
312// set preview/capture parameters - key/value pairs
313status_t Camera::setParameters(const String8& params)
314{
315 LOGV("setParameters");
316 sp <ICamera> c = mCamera;
317 if (c == 0) return NO_INIT;
318 return c->setParameters(params);
319}
320
321// get preview/capture parameters - key/value pairs
322String8 Camera::getParameters() const
323{
324 LOGV("getParameters");
325 String8 params;
326 sp <ICamera> c = mCamera;
327 if (c != 0) params = mCamera->getParameters();
328 return params;
329}
330
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700331// send command to camera driver
332status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
333{
Wu-cheng Lica9d9dc2010-02-10 13:01:48 +0800334 LOGV("sendCommand");
Wu-cheng Li36f68b82009-09-28 16:14:58 -0700335 sp <ICamera> c = mCamera;
336 if (c == 0) return NO_INIT;
337 return c->sendCommand(cmd, arg1, arg2);
338}
339
Dave Sparks5e271152009-06-23 17:30:11 -0700340void Camera::setListener(const sp<CameraListener>& listener)
341{
342 Mutex::Autolock _l(mLock);
343 mListener = listener;
344}
345
346void Camera::setPreviewCallbackFlags(int flag)
347{
348 LOGV("setPreviewCallbackFlags");
349 sp <ICamera> c = mCamera;
350 if (c == 0) return;
351 mCamera->setPreviewCallbackFlag(flag);
352}
353
Dave Sparks2a04aef2009-05-07 12:25:25 -0700354// callback from camera service
355void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
356{
Dave Sparks5e271152009-06-23 17:30:11 -0700357 sp<CameraListener> listener;
358 {
359 Mutex::Autolock _l(mLock);
360 listener = mListener;
361 }
362 if (listener != NULL) {
363 listener->notify(msgType, ext1, ext2);
364 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700365}
366
Dave Sparksd6289b12009-05-07 19:27:32 -0700367// callback from camera service when frame or image is ready
368void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
Dave Sparks2a04aef2009-05-07 12:25:25 -0700369{
Dave Sparks5e271152009-06-23 17:30:11 -0700370 sp<CameraListener> listener;
371 {
372 Mutex::Autolock _l(mLock);
373 listener = mListener;
374 }
375 if (listener != NULL) {
376 listener->postData(msgType, dataPtr);
377 }
Dave Sparks2a04aef2009-05-07 12:25:25 -0700378}
379
Dave Sparks59c1a932009-07-08 15:56:53 -0700380// callback from camera service when timestamped frame is ready
381void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
382{
383 sp<CameraListener> listener;
384 {
385 Mutex::Autolock _l(mLock);
386 listener = mListener;
387 }
388 if (listener != NULL) {
389 listener->postDataTimestamp(timestamp, msgType, dataPtr);
James Dongdf7a8562010-11-15 10:38:37 -0800390 } else {
391 LOGW("No listener was set. Drop a recording frame.");
392 releaseRecordingFrame(dataPtr);
Dave Sparks59c1a932009-07-08 15:56:53 -0700393 }
394}
395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396void Camera::binderDied(const wp<IBinder>& who) {
397 LOGW("ICamera died");
James Donga1b653d2009-07-02 10:04:20 -0700398 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399}
400
401void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
402 LOGV("binderDied");
403 Mutex::Autolock _l(Camera::mLock);
404 Camera::mCameraService.clear();
405 LOGW("Camera server died!");
406}
407
408}; // namespace android