blob: be395ba0b11be9cb255b65063eca69056c51a108 [file] [log] [blame]
Mathias Agopian3cf61352010-02-09 17:46:37 -08001/*
2**
3** Copyright (C) 2008, The Android Open Source Project
Mathias Agopian3cf61352010-02-09 17:46:37 -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>
21#include <utils/threads.h>
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +080022#include <binder/IPCThreadState.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080023#include <binder/IServiceManager.h>
24#include <binder/IMemory.h>
25
26#include <camera/Camera.h>
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +080027#include <camera/ICameraRecordingProxyListener.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080028#include <camera/ICameraService.h>
29
Andy McFadden8ba01022012-12-18 09:46:54 -080030#include <gui/IGraphicBufferProducer.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080031#include <gui/Surface.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080032
33namespace android {
34
35// client singleton for camera service binder interface
36Mutex Camera::mLock;
37sp<ICameraService> Camera::mCameraService;
38sp<Camera::DeathNotifier> Camera::mDeathNotifier;
39
40// establish binder interface to camera service
41const sp<ICameraService>& Camera::getCameraService()
42{
43 Mutex::Autolock _l(mLock);
44 if (mCameraService.get() == 0) {
45 sp<IServiceManager> sm = defaultServiceManager();
46 sp<IBinder> binder;
47 do {
48 binder = sm->getService(String16("media.camera"));
49 if (binder != 0)
50 break;
Steve Block5ff1dd52012-01-05 23:22:43 +000051 ALOGW("CameraService not published, waiting...");
Mathias Agopian3cf61352010-02-09 17:46:37 -080052 usleep(500000); // 0.5 s
53 } while(true);
54 if (mDeathNotifier == NULL) {
55 mDeathNotifier = new DeathNotifier();
56 }
57 binder->linkToDeath(mDeathNotifier);
58 mCameraService = interface_cast<ICameraService>(binder);
59 }
Steve Block29357bc2012-01-06 19:20:56 +000060 ALOGE_IF(mCameraService==0, "no CameraService!?");
Mathias Agopian3cf61352010-02-09 17:46:37 -080061 return mCameraService;
62}
63
64// ---------------------------------------------------------------------------
65
66Camera::Camera()
67{
68 init();
69}
70
71// construct a camera client from an existing camera remote
72sp<Camera> Camera::create(const sp<ICamera>& camera)
73{
Steve Block3856b092011-10-20 11:56:00 +010074 ALOGV("create");
Mathias Agopian3cf61352010-02-09 17:46:37 -080075 if (camera == 0) {
Steve Block29357bc2012-01-06 19:20:56 +000076 ALOGE("camera remote is a NULL pointer");
Mathias Agopian3cf61352010-02-09 17:46:37 -080077 return 0;
78 }
79
80 sp<Camera> c = new Camera();
81 if (camera->connect(c) == NO_ERROR) {
82 c->mStatus = NO_ERROR;
83 c->mCamera = camera;
84 camera->asBinder()->linkToDeath(c);
Wu-cheng Li627baac2011-01-04 20:00:55 +080085 return c;
Mathias Agopian3cf61352010-02-09 17:46:37 -080086 }
Wu-cheng Li627baac2011-01-04 20:00:55 +080087 return 0;
Mathias Agopian3cf61352010-02-09 17:46:37 -080088}
89
90void Camera::init()
91{
92 mStatus = UNKNOWN_ERROR;
93}
94
95Camera::~Camera()
96{
Chih-Chung Changd06618e2010-05-13 15:14:24 +080097 // We don't need to call disconnect() here because if the CameraService
98 // thinks we are the owner of the hardware, it will hold a (strong)
99 // reference to us, and we can't possibly be here. We also don't want to
100 // call disconnect() here if we are in the same process as mediaserver,
101 // because we may be invoked by CameraService::Client::connect() and will
102 // deadlock if we call any method of ICamera here.
Mathias Agopian3cf61352010-02-09 17:46:37 -0800103}
104
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800105int32_t Camera::getNumberOfCameras()
106{
107 const sp<ICameraService>& cs = getCameraService();
108 if (cs == 0) return 0;
109 return cs->getNumberOfCameras();
110}
111
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800112status_t Camera::getCameraInfo(int cameraId,
113 struct CameraInfo* cameraInfo) {
114 const sp<ICameraService>& cs = getCameraService();
115 if (cs == 0) return UNKNOWN_ERROR;
116 return cs->getCameraInfo(cameraId, cameraInfo);
117}
118
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800119sp<Camera> Camera::connect(int cameraId)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800120{
Steve Block3856b092011-10-20 11:56:00 +0100121 ALOGV("connect");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800122 sp<Camera> c = new Camera();
Igor Murashkin634a5152013-02-20 17:15:11 -0800123 sp<ICameraClient> cl = c;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800124 const sp<ICameraService>& cs = getCameraService();
125 if (cs != 0) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800126 c->mCamera = cs->connect(cl, cameraId);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800127 }
128 if (c->mCamera != 0) {
129 c->mCamera->asBinder()->linkToDeath(c);
130 c->mStatus = NO_ERROR;
131 } else {
132 c.clear();
133 }
134 return c;
135}
136
137void Camera::disconnect()
138{
Steve Block3856b092011-10-20 11:56:00 +0100139 ALOGV("disconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800140 if (mCamera != 0) {
141 mCamera->disconnect();
Chih-Chung Changf8ed70a2010-03-24 16:38:02 -0700142 mCamera->asBinder()->unlinkToDeath(this);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800143 mCamera = 0;
144 }
145}
146
147status_t Camera::reconnect()
148{
Steve Block3856b092011-10-20 11:56:00 +0100149 ALOGV("reconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800150 sp <ICamera> c = mCamera;
151 if (c == 0) return NO_INIT;
152 return c->connect(this);
153}
154
155sp<ICamera> Camera::remote()
156{
157 return mCamera;
158}
159
160status_t Camera::lock()
161{
162 sp <ICamera> c = mCamera;
163 if (c == 0) return NO_INIT;
164 return c->lock();
165}
166
167status_t Camera::unlock()
168{
169 sp <ICamera> c = mCamera;
170 if (c == 0) return NO_INIT;
171 return c->unlock();
172}
173
Jamie Gennis4b791682010-08-10 16:37:53 -0700174// pass the buffered Surface to the camera service
Mathias Agopian3cf61352010-02-09 17:46:37 -0800175status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
176{
Steve Block3856b092011-10-20 11:56:00 +0100177 ALOGV("setPreviewDisplay(%p)", surface.get());
Mathias Agopian3cf61352010-02-09 17:46:37 -0800178 sp <ICamera> c = mCamera;
179 if (c == 0) return NO_INIT;
180 if (surface != 0) {
Jamie Gennis4b791682010-08-10 16:37:53 -0700181 return c->setPreviewDisplay(surface);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800182 } else {
Steve Blockb8a80522011-12-20 16:23:08 +0000183 ALOGD("app passed NULL surface");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800184 return c->setPreviewDisplay(0);
185 }
186}
187
Andy McFadden8ba01022012-12-18 09:46:54 -0800188// pass the buffered IGraphicBufferProducer to the camera service
189status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800190{
Andy McFadden8ba01022012-12-18 09:46:54 -0800191 ALOGV("setPreviewTexture(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800192 sp <ICamera> c = mCamera;
193 if (c == 0) return NO_INIT;
Andy McFadden8ba01022012-12-18 09:46:54 -0800194 if (bufferProducer != 0) {
195 return c->setPreviewTexture(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800196 } else {
Steve Blockb8a80522011-12-20 16:23:08 +0000197 ALOGD("app passed NULL surface");
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800198 return c->setPreviewTexture(0);
199 }
200}
201
Mathias Agopian3cf61352010-02-09 17:46:37 -0800202// start preview mode
203status_t Camera::startPreview()
204{
Steve Block3856b092011-10-20 11:56:00 +0100205 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800206 sp <ICamera> c = mCamera;
207 if (c == 0) return NO_INIT;
208 return c->startPreview();
209}
210
James Donge2ad6732010-10-18 20:42:51 -0700211status_t Camera::storeMetaDataInBuffers(bool enabled)
212{
Steve Block3856b092011-10-20 11:56:00 +0100213 ALOGV("storeMetaDataInBuffers: %s",
James Donge2ad6732010-10-18 20:42:51 -0700214 enabled? "true": "false");
215 sp <ICamera> c = mCamera;
216 if (c == 0) return NO_INIT;
217 return c->storeMetaDataInBuffers(enabled);
218}
219
Mathias Agopian3cf61352010-02-09 17:46:37 -0800220// start recording mode, must call setPreviewDisplay first
221status_t Camera::startRecording()
222{
Steve Block3856b092011-10-20 11:56:00 +0100223 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800224 sp <ICamera> c = mCamera;
225 if (c == 0) return NO_INIT;
226 return c->startRecording();
227}
228
229// stop preview mode
230void Camera::stopPreview()
231{
Steve Block3856b092011-10-20 11:56:00 +0100232 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800233 sp <ICamera> c = mCamera;
234 if (c == 0) return;
235 c->stopPreview();
236}
237
238// stop recording mode
239void Camera::stopRecording()
240{
Steve Block3856b092011-10-20 11:56:00 +0100241 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800242 {
243 Mutex::Autolock _l(mLock);
244 mRecordingProxyListener.clear();
245 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800246 sp <ICamera> c = mCamera;
247 if (c == 0) return;
248 c->stopRecording();
249}
250
251// release a recording frame
252void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
253{
Steve Block3856b092011-10-20 11:56:00 +0100254 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800255 sp <ICamera> c = mCamera;
256 if (c == 0) return;
257 c->releaseRecordingFrame(mem);
258}
259
260// get preview state
261bool Camera::previewEnabled()
262{
Steve Block3856b092011-10-20 11:56:00 +0100263 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800264 sp <ICamera> c = mCamera;
265 if (c == 0) return false;
266 return c->previewEnabled();
267}
268
269// get recording state
270bool Camera::recordingEnabled()
271{
Steve Block3856b092011-10-20 11:56:00 +0100272 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800273 sp <ICamera> c = mCamera;
274 if (c == 0) return false;
275 return c->recordingEnabled();
276}
277
278status_t Camera::autoFocus()
279{
Steve Block3856b092011-10-20 11:56:00 +0100280 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800281 sp <ICamera> c = mCamera;
282 if (c == 0) return NO_INIT;
283 return c->autoFocus();
284}
285
286status_t Camera::cancelAutoFocus()
287{
Steve Block3856b092011-10-20 11:56:00 +0100288 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800289 sp <ICamera> c = mCamera;
290 if (c == 0) return NO_INIT;
291 return c->cancelAutoFocus();
292}
293
294// take a picture
James Donge468ac52011-02-17 16:38:06 -0800295status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800296{
Steve Block3856b092011-10-20 11:56:00 +0100297 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800298 sp <ICamera> c = mCamera;
299 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800300 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800301}
302
303// set preview/capture parameters - key/value pairs
304status_t Camera::setParameters(const String8& params)
305{
Steve Block3856b092011-10-20 11:56:00 +0100306 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800307 sp <ICamera> c = mCamera;
308 if (c == 0) return NO_INIT;
309 return c->setParameters(params);
310}
311
312// get preview/capture parameters - key/value pairs
313String8 Camera::getParameters() const
314{
Steve Block3856b092011-10-20 11:56:00 +0100315 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800316 String8 params;
317 sp <ICamera> c = mCamera;
318 if (c != 0) params = mCamera->getParameters();
319 return params;
320}
321
322// send command to camera driver
323status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
324{
Steve Block3856b092011-10-20 11:56:00 +0100325 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800326 sp <ICamera> c = mCamera;
327 if (c == 0) return NO_INIT;
328 return c->sendCommand(cmd, arg1, arg2);
329}
330
331void Camera::setListener(const sp<CameraListener>& listener)
332{
333 Mutex::Autolock _l(mLock);
334 mListener = listener;
335}
336
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800337void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
338{
339 Mutex::Autolock _l(mLock);
340 mRecordingProxyListener = listener;
341}
342
Mathias Agopian3cf61352010-02-09 17:46:37 -0800343void Camera::setPreviewCallbackFlags(int flag)
344{
Steve Block3856b092011-10-20 11:56:00 +0100345 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800346 sp <ICamera> c = mCamera;
347 if (c == 0) return;
348 mCamera->setPreviewCallbackFlag(flag);
349}
350
351// callback from camera service
352void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
353{
354 sp<CameraListener> listener;
355 {
356 Mutex::Autolock _l(mLock);
357 listener = mListener;
358 }
359 if (listener != NULL) {
360 listener->notify(msgType, ext1, ext2);
361 }
362}
363
364// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800365void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
366 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800367{
368 sp<CameraListener> listener;
369 {
370 Mutex::Autolock _l(mLock);
371 listener = mListener;
372 }
373 if (listener != NULL) {
Wu-cheng Li57c86182011-07-30 05:00:37 +0800374 listener->postData(msgType, dataPtr, metadata);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800375 }
376}
377
378// callback from camera service when timestamped frame is ready
379void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
380{
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800381 // If recording proxy listener is registered, forward the frame and return.
382 // The other listener (mListener) is ignored because the receiver needs to
383 // call releaseRecordingFrame.
384 sp<ICameraRecordingProxyListener> proxylistener;
385 {
386 Mutex::Autolock _l(mLock);
387 proxylistener = mRecordingProxyListener;
388 }
389 if (proxylistener != NULL) {
390 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
391 return;
392 }
393
Mathias Agopian3cf61352010-02-09 17:46:37 -0800394 sp<CameraListener> listener;
395 {
396 Mutex::Autolock _l(mLock);
397 listener = mListener;
398 }
399 if (listener != NULL) {
400 listener->postDataTimestamp(timestamp, msgType, dataPtr);
James Dongc42478e2010-11-15 10:38:37 -0800401 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000402 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800403 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800404 }
405}
406
407void Camera::binderDied(const wp<IBinder>& who) {
Steve Block5ff1dd52012-01-05 23:22:43 +0000408 ALOGW("ICamera died");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800409 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
410}
411
412void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
Steve Block3856b092011-10-20 11:56:00 +0100413 ALOGV("binderDied");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800414 Mutex::Autolock _l(Camera::mLock);
415 Camera::mCameraService.clear();
Steve Block5ff1dd52012-01-05 23:22:43 +0000416 ALOGW("Camera server died!");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800417}
418
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800419sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100420 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800421 return new RecordingProxy(this);
422}
423
424status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
425{
Steve Block3856b092011-10-20 11:56:00 +0100426 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800427 mCamera->setRecordingProxyListener(listener);
428 mCamera->reconnect();
429 return mCamera->startRecording();
430}
431
432void Camera::RecordingProxy::stopRecording()
433{
Steve Block3856b092011-10-20 11:56:00 +0100434 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800435 mCamera->stopRecording();
436}
437
438void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
439{
Steve Block3856b092011-10-20 11:56:00 +0100440 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800441 mCamera->releaseRecordingFrame(mem);
442}
443
444Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
445{
446 mCamera = camera;
447}
448
Mathias Agopian3cf61352010-02-09 17:46:37 -0800449}; // namespace android