blob: 22016a9f22005c5feb7291b60b4b86bbebce25f6 [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 McFadden8ba010212012-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
Ruben Brunk0f61d8f2013-08-08 13:07:18 -070042CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
43 &ICameraService::connect;
44
Mathias Agopian3cf61352010-02-09 17:46:37 -080045// construct a camera client from an existing camera remote
46sp<Camera> Camera::create(const sp<ICamera>& camera)
47{
Steve Block3856b092011-10-20 11:56:00 +010048 ALOGV("create");
Mathias Agopian3cf61352010-02-09 17:46:37 -080049 if (camera == 0) {
Steve Block29357bc2012-01-06 19:20:56 +000050 ALOGE("camera remote is a NULL pointer");
Mathias Agopian3cf61352010-02-09 17:46:37 -080051 return 0;
52 }
53
Igor Murashkinc073ba52013-02-26 14:32:34 -080054 sp<Camera> c = new Camera(-1);
Mathias Agopian3cf61352010-02-09 17:46:37 -080055 if (camera->connect(c) == NO_ERROR) {
56 c->mStatus = NO_ERROR;
57 c->mCamera = camera;
58 camera->asBinder()->linkToDeath(c);
Wu-cheng Li627baac2011-01-04 20:00:55 +080059 return c;
Mathias Agopian3cf61352010-02-09 17:46:37 -080060 }
Wu-cheng Li627baac2011-01-04 20:00:55 +080061 return 0;
Mathias Agopian3cf61352010-02-09 17:46:37 -080062}
63
Mathias Agopian3cf61352010-02-09 17:46:37 -080064Camera::~Camera()
65{
Chih-Chung Changd06618e2010-05-13 15:14:24 +080066 // We don't need to call disconnect() here because if the CameraService
67 // thinks we are the owner of the hardware, it will hold a (strong)
68 // reference to us, and we can't possibly be here. We also don't want to
69 // call disconnect() here if we are in the same process as mediaserver,
70 // because we may be invoked by CameraService::Client::connect() and will
71 // deadlock if we call any method of ICamera here.
Mathias Agopian3cf61352010-02-09 17:46:37 -080072}
73
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080074sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
75 int clientUid)
Mathias Agopian3cf61352010-02-09 17:46:37 -080076{
Igor Murashkinc073ba52013-02-26 14:32:34 -080077 return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
Mathias Agopian3cf61352010-02-09 17:46:37 -080078}
79
80status_t Camera::reconnect()
81{
Steve Block3856b092011-10-20 11:56:00 +010082 ALOGV("reconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -080083 sp <ICamera> c = mCamera;
84 if (c == 0) return NO_INIT;
85 return c->connect(this);
86}
87
Mathias Agopian3cf61352010-02-09 17:46:37 -080088status_t Camera::lock()
89{
90 sp <ICamera> c = mCamera;
91 if (c == 0) return NO_INIT;
92 return c->lock();
93}
94
95status_t Camera::unlock()
96{
97 sp <ICamera> c = mCamera;
98 if (c == 0) return NO_INIT;
99 return c->unlock();
100}
101
Andy McFadden8ba010212012-12-18 09:46:54 -0800102// pass the buffered IGraphicBufferProducer to the camera service
103status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800104{
Andy McFadden8ba010212012-12-18 09:46:54 -0800105 ALOGV("setPreviewTexture(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800106 sp <ICamera> c = mCamera;
107 if (c == 0) return NO_INIT;
Mathias Agopian99617ad2013-03-12 18:42:23 -0700108 ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
109 return c->setPreviewTexture(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800110}
111
Mathias Agopian3cf61352010-02-09 17:46:37 -0800112// start preview mode
113status_t Camera::startPreview()
114{
Steve Block3856b092011-10-20 11:56:00 +0100115 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800116 sp <ICamera> c = mCamera;
117 if (c == 0) return NO_INIT;
118 return c->startPreview();
119}
120
James Donge2ad6732010-10-18 20:42:51 -0700121status_t Camera::storeMetaDataInBuffers(bool enabled)
122{
Steve Block3856b092011-10-20 11:56:00 +0100123 ALOGV("storeMetaDataInBuffers: %s",
James Donge2ad6732010-10-18 20:42:51 -0700124 enabled? "true": "false");
125 sp <ICamera> c = mCamera;
126 if (c == 0) return NO_INIT;
127 return c->storeMetaDataInBuffers(enabled);
128}
129
Mathias Agopian3cf61352010-02-09 17:46:37 -0800130// start recording mode, must call setPreviewDisplay first
131status_t Camera::startRecording()
132{
Steve Block3856b092011-10-20 11:56:00 +0100133 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800134 sp <ICamera> c = mCamera;
135 if (c == 0) return NO_INIT;
136 return c->startRecording();
137}
138
139// stop preview mode
140void Camera::stopPreview()
141{
Steve Block3856b092011-10-20 11:56:00 +0100142 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800143 sp <ICamera> c = mCamera;
144 if (c == 0) return;
145 c->stopPreview();
146}
147
148// stop recording mode
149void Camera::stopRecording()
150{
Steve Block3856b092011-10-20 11:56:00 +0100151 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800152 {
153 Mutex::Autolock _l(mLock);
154 mRecordingProxyListener.clear();
155 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800156 sp <ICamera> c = mCamera;
157 if (c == 0) return;
158 c->stopRecording();
159}
160
161// release a recording frame
162void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
163{
Steve Block3856b092011-10-20 11:56:00 +0100164 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800165 sp <ICamera> c = mCamera;
166 if (c == 0) return;
167 c->releaseRecordingFrame(mem);
168}
169
170// get preview state
171bool Camera::previewEnabled()
172{
Steve Block3856b092011-10-20 11:56:00 +0100173 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800174 sp <ICamera> c = mCamera;
175 if (c == 0) return false;
176 return c->previewEnabled();
177}
178
179// get recording state
180bool Camera::recordingEnabled()
181{
Steve Block3856b092011-10-20 11:56:00 +0100182 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800183 sp <ICamera> c = mCamera;
184 if (c == 0) return false;
185 return c->recordingEnabled();
186}
187
188status_t Camera::autoFocus()
189{
Steve Block3856b092011-10-20 11:56:00 +0100190 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800191 sp <ICamera> c = mCamera;
192 if (c == 0) return NO_INIT;
193 return c->autoFocus();
194}
195
196status_t Camera::cancelAutoFocus()
197{
Steve Block3856b092011-10-20 11:56:00 +0100198 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800199 sp <ICamera> c = mCamera;
200 if (c == 0) return NO_INIT;
201 return c->cancelAutoFocus();
202}
203
204// take a picture
James Donge468ac52011-02-17 16:38:06 -0800205status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800206{
Steve Block3856b092011-10-20 11:56:00 +0100207 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800208 sp <ICamera> c = mCamera;
209 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800210 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800211}
212
213// set preview/capture parameters - key/value pairs
214status_t Camera::setParameters(const String8& params)
215{
Steve Block3856b092011-10-20 11:56:00 +0100216 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800217 sp <ICamera> c = mCamera;
218 if (c == 0) return NO_INIT;
219 return c->setParameters(params);
220}
221
222// get preview/capture parameters - key/value pairs
223String8 Camera::getParameters() const
224{
Steve Block3856b092011-10-20 11:56:00 +0100225 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800226 String8 params;
227 sp <ICamera> c = mCamera;
228 if (c != 0) params = mCamera->getParameters();
229 return params;
230}
231
232// send command to camera driver
233status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
234{
Steve Block3856b092011-10-20 11:56:00 +0100235 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800236 sp <ICamera> c = mCamera;
237 if (c == 0) return NO_INIT;
238 return c->sendCommand(cmd, arg1, arg2);
239}
240
241void Camera::setListener(const sp<CameraListener>& listener)
242{
243 Mutex::Autolock _l(mLock);
244 mListener = listener;
245}
246
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800247void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
248{
249 Mutex::Autolock _l(mLock);
250 mRecordingProxyListener = listener;
251}
252
Mathias Agopian3cf61352010-02-09 17:46:37 -0800253void Camera::setPreviewCallbackFlags(int flag)
254{
Steve Block3856b092011-10-20 11:56:00 +0100255 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800256 sp <ICamera> c = mCamera;
257 if (c == 0) return;
258 mCamera->setPreviewCallbackFlag(flag);
259}
260
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700261status_t Camera::setPreviewCallbackTarget(
262 const sp<IGraphicBufferProducer>& callbackProducer)
263{
264 sp <ICamera> c = mCamera;
265 if (c == 0) return NO_INIT;
266 return c->setPreviewCallbackTarget(callbackProducer);
267}
268
Mathias Agopian3cf61352010-02-09 17:46:37 -0800269// callback from camera service
270void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
271{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800272 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800273}
274
275// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800276void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
277 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800278{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800279 sp<CameraListener> listener;
280 {
281 Mutex::Autolock _l(mLock);
282 listener = mListener;
283 }
284 if (listener != NULL) {
285 listener->postData(msgType, dataPtr, metadata);
286 }
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 Murashkinfa4cf9d2013-03-04 16:14:23 -0800305 sp<CameraListener> listener;
306 {
307 Mutex::Autolock _l(mLock);
308 listener = mListener;
309 }
310
311 if (listener != NULL) {
312 listener->postDataTimestamp(timestamp, msgType, dataPtr);
313 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000314 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800315 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800316 }
317}
318
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800319sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100320 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800321 return new RecordingProxy(this);
322}
323
324status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
325{
Steve Block3856b092011-10-20 11:56:00 +0100326 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800327 mCamera->setRecordingProxyListener(listener);
328 mCamera->reconnect();
329 return mCamera->startRecording();
330}
331
332void Camera::RecordingProxy::stopRecording()
333{
Steve Block3856b092011-10-20 11:56:00 +0100334 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800335 mCamera->stopRecording();
336}
337
338void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
339{
Steve Block3856b092011-10-20 11:56:00 +0100340 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800341 mCamera->releaseRecordingFrame(mem);
342}
343
344Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
345{
346 mCamera = camera;
347}
348
Mathias Agopian3cf61352010-02-09 17:46:37 -0800349}; // namespace android