blob: 1b136de99f47e39ab89ee935d4be36823e31e138 [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>
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080022#include <utils/String16.h>
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +080023#include <binder/IPCThreadState.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080024#include <binder/IServiceManager.h>
25#include <binder/IMemory.h>
26
27#include <camera/Camera.h>
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +080028#include <camera/ICameraRecordingProxyListener.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080029#include <camera/ICameraService.h>
Igor Murashkinc073ba52013-02-26 14:32:34 -080030#include <camera/ICamera.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080031
Andy McFadden8ba01022012-12-18 09:46:54 -080032#include <gui/IGraphicBufferProducer.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080033#include <gui/Surface.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080034
35namespace android {
36
Igor Murashkinc073ba52013-02-26 14:32:34 -080037Camera::Camera(int cameraId)
38 : CameraBase(cameraId)
Mathias Agopian3cf61352010-02-09 17:46:37 -080039{
Mathias Agopian3cf61352010-02-09 17:46:37 -080040}
41
42// construct a camera client from an existing camera remote
43sp<Camera> Camera::create(const sp<ICamera>& camera)
44{
Steve Block3856b092011-10-20 11:56:00 +010045 ALOGV("create");
Mathias Agopian3cf61352010-02-09 17:46:37 -080046 if (camera == 0) {
Steve Block29357bc2012-01-06 19:20:56 +000047 ALOGE("camera remote is a NULL pointer");
Mathias Agopian3cf61352010-02-09 17:46:37 -080048 return 0;
49 }
50
Igor Murashkinc073ba52013-02-26 14:32:34 -080051 sp<Camera> c = new Camera(-1);
Mathias Agopian3cf61352010-02-09 17:46:37 -080052 if (camera->connect(c) == NO_ERROR) {
53 c->mStatus = NO_ERROR;
54 c->mCamera = camera;
55 camera->asBinder()->linkToDeath(c);
Wu-cheng Li627baac2011-01-04 20:00:55 +080056 return c;
Mathias Agopian3cf61352010-02-09 17:46:37 -080057 }
Wu-cheng Li627baac2011-01-04 20:00:55 +080058 return 0;
Mathias Agopian3cf61352010-02-09 17:46:37 -080059}
60
Mathias Agopian3cf61352010-02-09 17:46:37 -080061Camera::~Camera()
62{
Chih-Chung Changd06618e2010-05-13 15:14:24 +080063 // We don't need to call disconnect() here because if the CameraService
64 // thinks we are the owner of the hardware, it will hold a (strong)
65 // reference to us, and we can't possibly be here. We also don't want to
66 // call disconnect() here if we are in the same process as mediaserver,
67 // because we may be invoked by CameraService::Client::connect() and will
68 // deadlock if we call any method of ICamera here.
Mathias Agopian3cf61352010-02-09 17:46:37 -080069}
70
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080071sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
72 int clientUid)
Mathias Agopian3cf61352010-02-09 17:46:37 -080073{
Igor Murashkinc073ba52013-02-26 14:32:34 -080074 return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
Mathias Agopian3cf61352010-02-09 17:46:37 -080075}
76
77status_t Camera::reconnect()
78{
Steve Block3856b092011-10-20 11:56:00 +010079 ALOGV("reconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -080080 sp <ICamera> c = mCamera;
81 if (c == 0) return NO_INIT;
82 return c->connect(this);
83}
84
Mathias Agopian3cf61352010-02-09 17:46:37 -080085status_t Camera::lock()
86{
87 sp <ICamera> c = mCamera;
88 if (c == 0) return NO_INIT;
89 return c->lock();
90}
91
92status_t Camera::unlock()
93{
94 sp <ICamera> c = mCamera;
95 if (c == 0) return NO_INIT;
96 return c->unlock();
97}
98
Andy McFadden8ba01022012-12-18 09:46:54 -080099// pass the buffered IGraphicBufferProducer to the camera service
100status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800101{
Andy McFadden8ba01022012-12-18 09:46:54 -0800102 ALOGV("setPreviewTexture(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800103 sp <ICamera> c = mCamera;
104 if (c == 0) return NO_INIT;
Mathias Agopian99617ad2013-03-12 18:42:23 -0700105 ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
106 return c->setPreviewTexture(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800107}
108
Mathias Agopian3cf61352010-02-09 17:46:37 -0800109// start preview mode
110status_t Camera::startPreview()
111{
Steve Block3856b092011-10-20 11:56:00 +0100112 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800113 sp <ICamera> c = mCamera;
114 if (c == 0) return NO_INIT;
115 return c->startPreview();
116}
117
James Donge2ad6732010-10-18 20:42:51 -0700118status_t Camera::storeMetaDataInBuffers(bool enabled)
119{
Steve Block3856b092011-10-20 11:56:00 +0100120 ALOGV("storeMetaDataInBuffers: %s",
James Donge2ad6732010-10-18 20:42:51 -0700121 enabled? "true": "false");
122 sp <ICamera> c = mCamera;
123 if (c == 0) return NO_INIT;
124 return c->storeMetaDataInBuffers(enabled);
125}
126
Mathias Agopian3cf61352010-02-09 17:46:37 -0800127// start recording mode, must call setPreviewDisplay first
128status_t Camera::startRecording()
129{
Steve Block3856b092011-10-20 11:56:00 +0100130 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800131 sp <ICamera> c = mCamera;
132 if (c == 0) return NO_INIT;
133 return c->startRecording();
134}
135
136// stop preview mode
137void Camera::stopPreview()
138{
Steve Block3856b092011-10-20 11:56:00 +0100139 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800140 sp <ICamera> c = mCamera;
141 if (c == 0) return;
142 c->stopPreview();
143}
144
145// stop recording mode
146void Camera::stopRecording()
147{
Steve Block3856b092011-10-20 11:56:00 +0100148 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800149 {
150 Mutex::Autolock _l(mLock);
151 mRecordingProxyListener.clear();
152 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800153 sp <ICamera> c = mCamera;
154 if (c == 0) return;
155 c->stopRecording();
156}
157
158// release a recording frame
159void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
160{
Steve Block3856b092011-10-20 11:56:00 +0100161 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800162 sp <ICamera> c = mCamera;
163 if (c == 0) return;
164 c->releaseRecordingFrame(mem);
165}
166
167// get preview state
168bool Camera::previewEnabled()
169{
Steve Block3856b092011-10-20 11:56:00 +0100170 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800171 sp <ICamera> c = mCamera;
172 if (c == 0) return false;
173 return c->previewEnabled();
174}
175
176// get recording state
177bool Camera::recordingEnabled()
178{
Steve Block3856b092011-10-20 11:56:00 +0100179 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800180 sp <ICamera> c = mCamera;
181 if (c == 0) return false;
182 return c->recordingEnabled();
183}
184
185status_t Camera::autoFocus()
186{
Steve Block3856b092011-10-20 11:56:00 +0100187 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800188 sp <ICamera> c = mCamera;
189 if (c == 0) return NO_INIT;
190 return c->autoFocus();
191}
192
193status_t Camera::cancelAutoFocus()
194{
Steve Block3856b092011-10-20 11:56:00 +0100195 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800196 sp <ICamera> c = mCamera;
197 if (c == 0) return NO_INIT;
198 return c->cancelAutoFocus();
199}
200
201// take a picture
James Donge468ac52011-02-17 16:38:06 -0800202status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800203{
Steve Block3856b092011-10-20 11:56:00 +0100204 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800205 sp <ICamera> c = mCamera;
206 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800207 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800208}
209
210// set preview/capture parameters - key/value pairs
211status_t Camera::setParameters(const String8& params)
212{
Steve Block3856b092011-10-20 11:56:00 +0100213 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800214 sp <ICamera> c = mCamera;
215 if (c == 0) return NO_INIT;
216 return c->setParameters(params);
217}
218
219// get preview/capture parameters - key/value pairs
220String8 Camera::getParameters() const
221{
Steve Block3856b092011-10-20 11:56:00 +0100222 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800223 String8 params;
224 sp <ICamera> c = mCamera;
225 if (c != 0) params = mCamera->getParameters();
226 return params;
227}
228
229// send command to camera driver
230status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
231{
Steve Block3856b092011-10-20 11:56:00 +0100232 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800233 sp <ICamera> c = mCamera;
234 if (c == 0) return NO_INIT;
235 return c->sendCommand(cmd, arg1, arg2);
236}
237
238void Camera::setListener(const sp<CameraListener>& listener)
239{
240 Mutex::Autolock _l(mLock);
241 mListener = listener;
242}
243
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800244void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
245{
246 Mutex::Autolock _l(mLock);
247 mRecordingProxyListener = listener;
248}
249
Mathias Agopian3cf61352010-02-09 17:46:37 -0800250void Camera::setPreviewCallbackFlags(int flag)
251{
Steve Block3856b092011-10-20 11:56:00 +0100252 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800253 sp <ICamera> c = mCamera;
254 if (c == 0) return;
255 mCamera->setPreviewCallbackFlag(flag);
256}
257
258// callback from camera service
259void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
260{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800261 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800262}
263
264// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800265void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
266 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800267{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800268 sp<CameraListener> listener;
269 {
270 Mutex::Autolock _l(mLock);
271 listener = mListener;
272 }
273 if (listener != NULL) {
274 listener->postData(msgType, dataPtr, metadata);
275 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800276}
277
278// callback from camera service when timestamped frame is ready
279void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
280{
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800281 // If recording proxy listener is registered, forward the frame and return.
282 // The other listener (mListener) is ignored because the receiver needs to
283 // call releaseRecordingFrame.
284 sp<ICameraRecordingProxyListener> proxylistener;
285 {
286 Mutex::Autolock _l(mLock);
287 proxylistener = mRecordingProxyListener;
288 }
289 if (proxylistener != NULL) {
290 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
291 return;
292 }
293
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800294 sp<CameraListener> listener;
295 {
296 Mutex::Autolock _l(mLock);
297 listener = mListener;
298 }
299
300 if (listener != NULL) {
301 listener->postDataTimestamp(timestamp, msgType, dataPtr);
302 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000303 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800304 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800305 }
306}
307
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800308sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100309 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800310 return new RecordingProxy(this);
311}
312
313status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
314{
Steve Block3856b092011-10-20 11:56:00 +0100315 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800316 mCamera->setRecordingProxyListener(listener);
317 mCamera->reconnect();
318 return mCamera->startRecording();
319}
320
321void Camera::RecordingProxy::stopRecording()
322{
Steve Block3856b092011-10-20 11:56:00 +0100323 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800324 mCamera->stopRecording();
325}
326
327void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
328{
Steve Block3856b092011-10-20 11:56:00 +0100329 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800330 mCamera->releaseRecordingFrame(mem);
331}
332
333Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
334{
335 mCamera = camera;
336}
337
Mathias Agopian3cf61352010-02-09 17:46:37 -0800338}; // namespace android