blob: f417c90000886101b7c4b7bfc16505e5276dd2db [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
Jamie Gennis4b791682010-08-10 16:37:53 -070099// pass the buffered Surface to the camera service
Mathias Agopian3cf61352010-02-09 17:46:37 -0800100status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
101{
Steve Block3856b092011-10-20 11:56:00 +0100102 ALOGV("setPreviewDisplay(%p)", surface.get());
Mathias Agopian3cf61352010-02-09 17:46:37 -0800103 sp <ICamera> c = mCamera;
104 if (c == 0) return NO_INIT;
105 if (surface != 0) {
Jamie Gennis4b791682010-08-10 16:37:53 -0700106 return c->setPreviewDisplay(surface);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800107 } else {
Steve Blockb8a80522011-12-20 16:23:08 +0000108 ALOGD("app passed NULL surface");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800109 return c->setPreviewDisplay(0);
110 }
111}
112
Andy McFadden8ba01022012-12-18 09:46:54 -0800113// pass the buffered IGraphicBufferProducer to the camera service
114status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800115{
Andy McFadden8ba01022012-12-18 09:46:54 -0800116 ALOGV("setPreviewTexture(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800117 sp <ICamera> c = mCamera;
118 if (c == 0) return NO_INIT;
Andy McFadden8ba01022012-12-18 09:46:54 -0800119 if (bufferProducer != 0) {
120 return c->setPreviewTexture(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800121 } else {
Steve Blockb8a80522011-12-20 16:23:08 +0000122 ALOGD("app passed NULL surface");
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800123 return c->setPreviewTexture(0);
124 }
125}
126
Mathias Agopian3cf61352010-02-09 17:46:37 -0800127// start preview mode
128status_t Camera::startPreview()
129{
Steve Block3856b092011-10-20 11:56:00 +0100130 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800131 sp <ICamera> c = mCamera;
132 if (c == 0) return NO_INIT;
133 return c->startPreview();
134}
135
James Donge2ad6732010-10-18 20:42:51 -0700136status_t Camera::storeMetaDataInBuffers(bool enabled)
137{
Steve Block3856b092011-10-20 11:56:00 +0100138 ALOGV("storeMetaDataInBuffers: %s",
James Donge2ad6732010-10-18 20:42:51 -0700139 enabled? "true": "false");
140 sp <ICamera> c = mCamera;
141 if (c == 0) return NO_INIT;
142 return c->storeMetaDataInBuffers(enabled);
143}
144
Mathias Agopian3cf61352010-02-09 17:46:37 -0800145// start recording mode, must call setPreviewDisplay first
146status_t Camera::startRecording()
147{
Steve Block3856b092011-10-20 11:56:00 +0100148 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800149 sp <ICamera> c = mCamera;
150 if (c == 0) return NO_INIT;
151 return c->startRecording();
152}
153
154// stop preview mode
155void Camera::stopPreview()
156{
Steve Block3856b092011-10-20 11:56:00 +0100157 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800158 sp <ICamera> c = mCamera;
159 if (c == 0) return;
160 c->stopPreview();
161}
162
163// stop recording mode
164void Camera::stopRecording()
165{
Steve Block3856b092011-10-20 11:56:00 +0100166 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800167 {
168 Mutex::Autolock _l(mLock);
169 mRecordingProxyListener.clear();
170 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800171 sp <ICamera> c = mCamera;
172 if (c == 0) return;
173 c->stopRecording();
174}
175
176// release a recording frame
177void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
178{
Steve Block3856b092011-10-20 11:56:00 +0100179 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800180 sp <ICamera> c = mCamera;
181 if (c == 0) return;
182 c->releaseRecordingFrame(mem);
183}
184
185// get preview state
186bool Camera::previewEnabled()
187{
Steve Block3856b092011-10-20 11:56:00 +0100188 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800189 sp <ICamera> c = mCamera;
190 if (c == 0) return false;
191 return c->previewEnabled();
192}
193
194// get recording state
195bool Camera::recordingEnabled()
196{
Steve Block3856b092011-10-20 11:56:00 +0100197 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800198 sp <ICamera> c = mCamera;
199 if (c == 0) return false;
200 return c->recordingEnabled();
201}
202
203status_t Camera::autoFocus()
204{
Steve Block3856b092011-10-20 11:56:00 +0100205 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800206 sp <ICamera> c = mCamera;
207 if (c == 0) return NO_INIT;
208 return c->autoFocus();
209}
210
211status_t Camera::cancelAutoFocus()
212{
Steve Block3856b092011-10-20 11:56:00 +0100213 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800214 sp <ICamera> c = mCamera;
215 if (c == 0) return NO_INIT;
216 return c->cancelAutoFocus();
217}
218
219// take a picture
James Donge468ac52011-02-17 16:38:06 -0800220status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800221{
Steve Block3856b092011-10-20 11:56:00 +0100222 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800223 sp <ICamera> c = mCamera;
224 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800225 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800226}
227
228// set preview/capture parameters - key/value pairs
229status_t Camera::setParameters(const String8& params)
230{
Steve Block3856b092011-10-20 11:56:00 +0100231 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800232 sp <ICamera> c = mCamera;
233 if (c == 0) return NO_INIT;
234 return c->setParameters(params);
235}
236
237// get preview/capture parameters - key/value pairs
238String8 Camera::getParameters() const
239{
Steve Block3856b092011-10-20 11:56:00 +0100240 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800241 String8 params;
242 sp <ICamera> c = mCamera;
243 if (c != 0) params = mCamera->getParameters();
244 return params;
245}
246
247// send command to camera driver
248status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
249{
Steve Block3856b092011-10-20 11:56:00 +0100250 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800251 sp <ICamera> c = mCamera;
252 if (c == 0) return NO_INIT;
253 return c->sendCommand(cmd, arg1, arg2);
254}
255
256void Camera::setListener(const sp<CameraListener>& listener)
257{
258 Mutex::Autolock _l(mLock);
259 mListener = listener;
260}
261
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800262void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
263{
264 Mutex::Autolock _l(mLock);
265 mRecordingProxyListener = listener;
266}
267
Mathias Agopian3cf61352010-02-09 17:46:37 -0800268void Camera::setPreviewCallbackFlags(int flag)
269{
Steve Block3856b092011-10-20 11:56:00 +0100270 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800271 sp <ICamera> c = mCamera;
272 if (c == 0) return;
273 mCamera->setPreviewCallbackFlag(flag);
274}
275
276// callback from camera service
277void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
278{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800279 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800280}
281
282// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800283void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
284 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800285{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800286 return CameraBaseT::dataCallback(msgType, dataPtr, metadata);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800287}
288
289// callback from camera service when timestamped frame is ready
290void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
291{
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800292 // If recording proxy listener is registered, forward the frame and return.
293 // The other listener (mListener) is ignored because the receiver needs to
294 // call releaseRecordingFrame.
295 sp<ICameraRecordingProxyListener> proxylistener;
296 {
297 Mutex::Autolock _l(mLock);
298 proxylistener = mRecordingProxyListener;
299 }
300 if (proxylistener != NULL) {
301 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
302 return;
303 }
304
Igor Murashkinc073ba52013-02-26 14:32:34 -0800305 if (!CameraBaseT::dataCallbackTimestamp(timestamp, msgType, dataPtr)) {
Steve Block5ff1dd52012-01-05 23:22:43 +0000306 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800307 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800308 }
309}
310
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800311sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100312 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800313 return new RecordingProxy(this);
314}
315
316status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
317{
Steve Block3856b092011-10-20 11:56:00 +0100318 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800319 mCamera->setRecordingProxyListener(listener);
320 mCamera->reconnect();
321 return mCamera->startRecording();
322}
323
324void Camera::RecordingProxy::stopRecording()
325{
Steve Block3856b092011-10-20 11:56:00 +0100326 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800327 mCamera->stopRecording();
328}
329
330void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
331{
Steve Block3856b092011-10-20 11:56:00 +0100332 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800333 mCamera->releaseRecordingFrame(mem);
334}
335
336Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
337{
338 mCamera = camera;
339}
340
Mathias Agopian3cf61352010-02-09 17:46:37 -0800341}; // namespace android