blob: cd3b84c40f39eac2d7bd8cd2ef4b8e78ab8bcb22 [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
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;
Marco Nelissen06b46062014-11-14 07:58:25 -080058 IInterface::asBinder(camera)->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
Svetoslav Ganov280405a2015-05-12 02:19:27 +000074sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
75 int clientUid)
Mathias Agopian3cf61352010-02-09 17:46:37 -080076{
Svetoslav Ganov280405a2015-05-12 02:19:27 +000077 return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
Mathias Agopian3cf61352010-02-09 17:46:37 -080078}
79
Zhijun Heb10cdad2014-06-16 16:38:35 -070080status_t Camera::connectLegacy(int cameraId, int halVersion,
Svetoslav Ganov280405a2015-05-12 02:19:27 +000081 const String16& clientPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -070082 int clientUid,
83 sp<Camera>& camera)
84{
85 ALOGV("%s: connect legacy camera device", __FUNCTION__);
86 sp<Camera> c = new Camera(cameraId);
87 sp<ICameraClient> cl = c;
88 status_t status = NO_ERROR;
89 const sp<ICameraService>& cs = CameraBaseT::getCameraService();
90
91 if (cs != 0) {
Svetoslav Ganov280405a2015-05-12 02:19:27 +000092 status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -070093 clientUid, /*out*/c->mCamera);
94 }
95 if (status == OK && c->mCamera != 0) {
Marco Nelissen06b46062014-11-14 07:58:25 -080096 IInterface::asBinder(c->mCamera)->linkToDeath(c);
Zhijun Heb10cdad2014-06-16 16:38:35 -070097 c->mStatus = NO_ERROR;
98 camera = c;
99 } else {
Eino-Ville Talvalae3afb2c2015-06-03 16:03:30 -0700100 ALOGW("An error occurred while connecting to camera %d: %d (%s)",
101 cameraId, status, strerror(-status));
Zhijun Heb10cdad2014-06-16 16:38:35 -0700102 c.clear();
103 }
104 return status;
105}
106
Mathias Agopian3cf61352010-02-09 17:46:37 -0800107status_t Camera::reconnect()
108{
Steve Block3856b092011-10-20 11:56:00 +0100109 ALOGV("reconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800110 sp <ICamera> c = mCamera;
111 if (c == 0) return NO_INIT;
112 return c->connect(this);
113}
114
Mathias Agopian3cf61352010-02-09 17:46:37 -0800115status_t Camera::lock()
116{
117 sp <ICamera> c = mCamera;
118 if (c == 0) return NO_INIT;
119 return c->lock();
120}
121
122status_t Camera::unlock()
123{
124 sp <ICamera> c = mCamera;
125 if (c == 0) return NO_INIT;
126 return c->unlock();
127}
128
Andy McFadden8ba01022012-12-18 09:46:54 -0800129// pass the buffered IGraphicBufferProducer to the camera service
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700130status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800131{
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700132 ALOGV("setPreviewTarget(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800133 sp <ICamera> c = mCamera;
134 if (c == 0) return NO_INIT;
Mathias Agopian99617ad2013-03-12 18:42:23 -0700135 ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700136 return c->setPreviewTarget(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800137}
138
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800139status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer)
140{
141 ALOGV("setVideoTarget(%p)", bufferProducer.get());
142 sp <ICamera> c = mCamera;
143 if (c == 0) return NO_INIT;
144 ALOGD_IF(bufferProducer == 0, "app passed NULL video surface");
145 return c->setVideoTarget(bufferProducer);
146}
147
Mathias Agopian3cf61352010-02-09 17:46:37 -0800148// start preview mode
149status_t Camera::startPreview()
150{
Steve Block3856b092011-10-20 11:56:00 +0100151 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800152 sp <ICamera> c = mCamera;
153 if (c == 0) return NO_INIT;
154 return c->startPreview();
155}
156
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800157status_t Camera::setVideoBufferMode(int32_t videoBufferMode)
James Donge2ad6732010-10-18 20:42:51 -0700158{
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800159 ALOGV("setVideoBufferMode: %d", videoBufferMode);
James Donge2ad6732010-10-18 20:42:51 -0700160 sp <ICamera> c = mCamera;
161 if (c == 0) return NO_INIT;
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800162 return c->setVideoBufferMode(videoBufferMode);
James Donge2ad6732010-10-18 20:42:51 -0700163}
164
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700165// start recording mode, must call setPreviewTarget first
Mathias Agopian3cf61352010-02-09 17:46:37 -0800166status_t Camera::startRecording()
167{
Steve Block3856b092011-10-20 11:56:00 +0100168 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800169 sp <ICamera> c = mCamera;
170 if (c == 0) return NO_INIT;
171 return c->startRecording();
172}
173
174// stop preview mode
175void Camera::stopPreview()
176{
Steve Block3856b092011-10-20 11:56:00 +0100177 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800178 sp <ICamera> c = mCamera;
179 if (c == 0) return;
180 c->stopPreview();
181}
182
183// stop recording mode
184void Camera::stopRecording()
185{
Steve Block3856b092011-10-20 11:56:00 +0100186 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800187 {
188 Mutex::Autolock _l(mLock);
189 mRecordingProxyListener.clear();
190 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800191 sp <ICamera> c = mCamera;
192 if (c == 0) return;
193 c->stopRecording();
194}
195
196// release a recording frame
197void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
198{
Steve Block3856b092011-10-20 11:56:00 +0100199 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800200 sp <ICamera> c = mCamera;
201 if (c == 0) return;
202 c->releaseRecordingFrame(mem);
203}
204
205// get preview state
206bool Camera::previewEnabled()
207{
Steve Block3856b092011-10-20 11:56:00 +0100208 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800209 sp <ICamera> c = mCamera;
210 if (c == 0) return false;
211 return c->previewEnabled();
212}
213
214// get recording state
215bool Camera::recordingEnabled()
216{
Steve Block3856b092011-10-20 11:56:00 +0100217 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800218 sp <ICamera> c = mCamera;
219 if (c == 0) return false;
220 return c->recordingEnabled();
221}
222
223status_t Camera::autoFocus()
224{
Steve Block3856b092011-10-20 11:56:00 +0100225 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800226 sp <ICamera> c = mCamera;
227 if (c == 0) return NO_INIT;
228 return c->autoFocus();
229}
230
231status_t Camera::cancelAutoFocus()
232{
Steve Block3856b092011-10-20 11:56:00 +0100233 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800234 sp <ICamera> c = mCamera;
235 if (c == 0) return NO_INIT;
236 return c->cancelAutoFocus();
237}
238
239// take a picture
James Donge468ac52011-02-17 16:38:06 -0800240status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800241{
Steve Block3856b092011-10-20 11:56:00 +0100242 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800243 sp <ICamera> c = mCamera;
244 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800245 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800246}
247
248// set preview/capture parameters - key/value pairs
249status_t Camera::setParameters(const String8& params)
250{
Steve Block3856b092011-10-20 11:56:00 +0100251 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800252 sp <ICamera> c = mCamera;
253 if (c == 0) return NO_INIT;
254 return c->setParameters(params);
255}
256
257// get preview/capture parameters - key/value pairs
258String8 Camera::getParameters() const
259{
Steve Block3856b092011-10-20 11:56:00 +0100260 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800261 String8 params;
262 sp <ICamera> c = mCamera;
263 if (c != 0) params = mCamera->getParameters();
264 return params;
265}
266
267// send command to camera driver
268status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
269{
Steve Block3856b092011-10-20 11:56:00 +0100270 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800271 sp <ICamera> c = mCamera;
272 if (c == 0) return NO_INIT;
273 return c->sendCommand(cmd, arg1, arg2);
274}
275
276void Camera::setListener(const sp<CameraListener>& listener)
277{
278 Mutex::Autolock _l(mLock);
279 mListener = listener;
280}
281
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800282void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
283{
284 Mutex::Autolock _l(mLock);
285 mRecordingProxyListener = listener;
286}
287
Mathias Agopian3cf61352010-02-09 17:46:37 -0800288void Camera::setPreviewCallbackFlags(int flag)
289{
Steve Block3856b092011-10-20 11:56:00 +0100290 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800291 sp <ICamera> c = mCamera;
292 if (c == 0) return;
293 mCamera->setPreviewCallbackFlag(flag);
294}
295
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700296status_t Camera::setPreviewCallbackTarget(
297 const sp<IGraphicBufferProducer>& callbackProducer)
298{
299 sp <ICamera> c = mCamera;
300 if (c == 0) return NO_INIT;
301 return c->setPreviewCallbackTarget(callbackProducer);
302}
303
Mathias Agopian3cf61352010-02-09 17:46:37 -0800304// callback from camera service
305void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
306{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800307 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800308}
309
310// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800311void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
312 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800313{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800314 sp<CameraListener> listener;
315 {
316 Mutex::Autolock _l(mLock);
317 listener = mListener;
318 }
319 if (listener != NULL) {
320 listener->postData(msgType, dataPtr, metadata);
321 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800322}
323
324// callback from camera service when timestamped frame is ready
325void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
326{
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800327 // If recording proxy listener is registered, forward the frame and return.
328 // The other listener (mListener) is ignored because the receiver needs to
329 // call releaseRecordingFrame.
330 sp<ICameraRecordingProxyListener> proxylistener;
331 {
332 Mutex::Autolock _l(mLock);
333 proxylistener = mRecordingProxyListener;
334 }
335 if (proxylistener != NULL) {
336 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
337 return;
338 }
339
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800340 sp<CameraListener> listener;
341 {
342 Mutex::Autolock _l(mLock);
343 listener = mListener;
344 }
345
346 if (listener != NULL) {
347 listener->postDataTimestamp(timestamp, msgType, dataPtr);
348 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000349 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800350 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800351 }
352}
353
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800354sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100355 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800356 return new RecordingProxy(this);
357}
358
359status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
360{
Steve Block3856b092011-10-20 11:56:00 +0100361 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800362 mCamera->setRecordingProxyListener(listener);
363 mCamera->reconnect();
364 return mCamera->startRecording();
365}
366
367void Camera::RecordingProxy::stopRecording()
368{
Steve Block3856b092011-10-20 11:56:00 +0100369 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800370 mCamera->stopRecording();
371}
372
373void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
374{
Steve Block3856b092011-10-20 11:56:00 +0100375 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800376 mCamera->releaseRecordingFrame(mem);
377}
378
379Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
380{
381 mCamera = camera;
382}
383
Mathias Agopian3cf61352010-02-09 17:46:37 -0800384}; // namespace android