blob: 84e0d1c7b376f3389a2913e44403daf5eae5525d [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
Svet Ganov32fa6d02015-05-01 20:47:20 -070074sp<Camera> Camera::connect(int cameraId, const String16& opPackageName, int clientUid)
Mathias Agopian3cf61352010-02-09 17:46:37 -080075{
Svet Ganov32fa6d02015-05-01 20:47:20 -070076 return CameraBaseT::connect(cameraId, opPackageName, clientUid);
Mathias Agopian3cf61352010-02-09 17:46:37 -080077}
78
Zhijun Heb10cdad2014-06-16 16:38:35 -070079status_t Camera::connectLegacy(int cameraId, int halVersion,
Svet Ganov32fa6d02015-05-01 20:47:20 -070080 const String16& opPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -070081 int clientUid,
82 sp<Camera>& camera)
83{
84 ALOGV("%s: connect legacy camera device", __FUNCTION__);
85 sp<Camera> c = new Camera(cameraId);
86 sp<ICameraClient> cl = c;
87 status_t status = NO_ERROR;
88 const sp<ICameraService>& cs = CameraBaseT::getCameraService();
89
90 if (cs != 0) {
Svet Ganov32fa6d02015-05-01 20:47:20 -070091 status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName,
Zhijun Heb10cdad2014-06-16 16:38:35 -070092 clientUid, /*out*/c->mCamera);
93 }
94 if (status == OK && c->mCamera != 0) {
Marco Nelissen06b46062014-11-14 07:58:25 -080095 IInterface::asBinder(c->mCamera)->linkToDeath(c);
Zhijun Heb10cdad2014-06-16 16:38:35 -070096 c->mStatus = NO_ERROR;
97 camera = c;
98 } else {
99 ALOGW("An error occurred while connecting to camera: %d", cameraId);
100 c.clear();
101 }
102 return status;
103}
104
Mathias Agopian3cf61352010-02-09 17:46:37 -0800105status_t Camera::reconnect()
106{
Steve Block3856b092011-10-20 11:56:00 +0100107 ALOGV("reconnect");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800108 sp <ICamera> c = mCamera;
109 if (c == 0) return NO_INIT;
110 return c->connect(this);
111}
112
Mathias Agopian3cf61352010-02-09 17:46:37 -0800113status_t Camera::lock()
114{
115 sp <ICamera> c = mCamera;
116 if (c == 0) return NO_INIT;
117 return c->lock();
118}
119
120status_t Camera::unlock()
121{
122 sp <ICamera> c = mCamera;
123 if (c == 0) return NO_INIT;
124 return c->unlock();
125}
126
Andy McFadden8ba01022012-12-18 09:46:54 -0800127// pass the buffered IGraphicBufferProducer to the camera service
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700128status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800129{
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700130 ALOGV("setPreviewTarget(%p)", bufferProducer.get());
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800131 sp <ICamera> c = mCamera;
132 if (c == 0) return NO_INIT;
Mathias Agopian99617ad2013-03-12 18:42:23 -0700133 ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700134 return c->setPreviewTarget(bufferProducer);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800135}
136
Mathias Agopian3cf61352010-02-09 17:46:37 -0800137// start preview mode
138status_t Camera::startPreview()
139{
Steve Block3856b092011-10-20 11:56:00 +0100140 ALOGV("startPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800141 sp <ICamera> c = mCamera;
142 if (c == 0) return NO_INIT;
143 return c->startPreview();
144}
145
James Donge2ad6732010-10-18 20:42:51 -0700146status_t Camera::storeMetaDataInBuffers(bool enabled)
147{
Steve Block3856b092011-10-20 11:56:00 +0100148 ALOGV("storeMetaDataInBuffers: %s",
James Donge2ad6732010-10-18 20:42:51 -0700149 enabled? "true": "false");
150 sp <ICamera> c = mCamera;
151 if (c == 0) return NO_INIT;
152 return c->storeMetaDataInBuffers(enabled);
153}
154
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700155// start recording mode, must call setPreviewTarget first
Mathias Agopian3cf61352010-02-09 17:46:37 -0800156status_t Camera::startRecording()
157{
Steve Block3856b092011-10-20 11:56:00 +0100158 ALOGV("startRecording");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800159 sp <ICamera> c = mCamera;
160 if (c == 0) return NO_INIT;
161 return c->startRecording();
162}
163
164// stop preview mode
165void Camera::stopPreview()
166{
Steve Block3856b092011-10-20 11:56:00 +0100167 ALOGV("stopPreview");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800168 sp <ICamera> c = mCamera;
169 if (c == 0) return;
170 c->stopPreview();
171}
172
173// stop recording mode
174void Camera::stopRecording()
175{
Steve Block3856b092011-10-20 11:56:00 +0100176 ALOGV("stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800177 {
178 Mutex::Autolock _l(mLock);
179 mRecordingProxyListener.clear();
180 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800181 sp <ICamera> c = mCamera;
182 if (c == 0) return;
183 c->stopRecording();
184}
185
186// release a recording frame
187void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
188{
Steve Block3856b092011-10-20 11:56:00 +0100189 ALOGV("releaseRecordingFrame");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800190 sp <ICamera> c = mCamera;
191 if (c == 0) return;
192 c->releaseRecordingFrame(mem);
193}
194
195// get preview state
196bool Camera::previewEnabled()
197{
Steve Block3856b092011-10-20 11:56:00 +0100198 ALOGV("previewEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800199 sp <ICamera> c = mCamera;
200 if (c == 0) return false;
201 return c->previewEnabled();
202}
203
204// get recording state
205bool Camera::recordingEnabled()
206{
Steve Block3856b092011-10-20 11:56:00 +0100207 ALOGV("recordingEnabled");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800208 sp <ICamera> c = mCamera;
209 if (c == 0) return false;
210 return c->recordingEnabled();
211}
212
213status_t Camera::autoFocus()
214{
Steve Block3856b092011-10-20 11:56:00 +0100215 ALOGV("autoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800216 sp <ICamera> c = mCamera;
217 if (c == 0) return NO_INIT;
218 return c->autoFocus();
219}
220
221status_t Camera::cancelAutoFocus()
222{
Steve Block3856b092011-10-20 11:56:00 +0100223 ALOGV("cancelAutoFocus");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800224 sp <ICamera> c = mCamera;
225 if (c == 0) return NO_INIT;
226 return c->cancelAutoFocus();
227}
228
229// take a picture
James Donge468ac52011-02-17 16:38:06 -0800230status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800231{
Steve Block3856b092011-10-20 11:56:00 +0100232 ALOGV("takePicture: 0x%x", msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800233 sp <ICamera> c = mCamera;
234 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800235 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800236}
237
238// set preview/capture parameters - key/value pairs
239status_t Camera::setParameters(const String8& params)
240{
Steve Block3856b092011-10-20 11:56:00 +0100241 ALOGV("setParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800242 sp <ICamera> c = mCamera;
243 if (c == 0) return NO_INIT;
244 return c->setParameters(params);
245}
246
247// get preview/capture parameters - key/value pairs
248String8 Camera::getParameters() const
249{
Steve Block3856b092011-10-20 11:56:00 +0100250 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800251 String8 params;
252 sp <ICamera> c = mCamera;
253 if (c != 0) params = mCamera->getParameters();
254 return params;
255}
256
257// send command to camera driver
258status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
259{
Steve Block3856b092011-10-20 11:56:00 +0100260 ALOGV("sendCommand");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800261 sp <ICamera> c = mCamera;
262 if (c == 0) return NO_INIT;
263 return c->sendCommand(cmd, arg1, arg2);
264}
265
266void Camera::setListener(const sp<CameraListener>& listener)
267{
268 Mutex::Autolock _l(mLock);
269 mListener = listener;
270}
271
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800272void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
273{
274 Mutex::Autolock _l(mLock);
275 mRecordingProxyListener = listener;
276}
277
Mathias Agopian3cf61352010-02-09 17:46:37 -0800278void Camera::setPreviewCallbackFlags(int flag)
279{
Steve Block3856b092011-10-20 11:56:00 +0100280 ALOGV("setPreviewCallbackFlags");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800281 sp <ICamera> c = mCamera;
282 if (c == 0) return;
283 mCamera->setPreviewCallbackFlag(flag);
284}
285
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700286status_t Camera::setPreviewCallbackTarget(
287 const sp<IGraphicBufferProducer>& callbackProducer)
288{
289 sp <ICamera> c = mCamera;
290 if (c == 0) return NO_INIT;
291 return c->setPreviewCallbackTarget(callbackProducer);
292}
293
Mathias Agopian3cf61352010-02-09 17:46:37 -0800294// callback from camera service
295void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
296{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800297 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800298}
299
300// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800301void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
302 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800303{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800304 sp<CameraListener> listener;
305 {
306 Mutex::Autolock _l(mLock);
307 listener = mListener;
308 }
309 if (listener != NULL) {
310 listener->postData(msgType, dataPtr, metadata);
311 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800312}
313
314// callback from camera service when timestamped frame is ready
315void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
316{
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800317 // If recording proxy listener is registered, forward the frame and return.
318 // The other listener (mListener) is ignored because the receiver needs to
319 // call releaseRecordingFrame.
320 sp<ICameraRecordingProxyListener> proxylistener;
321 {
322 Mutex::Autolock _l(mLock);
323 proxylistener = mRecordingProxyListener;
324 }
325 if (proxylistener != NULL) {
326 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
327 return;
328 }
329
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800330 sp<CameraListener> listener;
331 {
332 Mutex::Autolock _l(mLock);
333 listener = mListener;
334 }
335
336 if (listener != NULL) {
337 listener->postDataTimestamp(timestamp, msgType, dataPtr);
338 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000339 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800340 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800341 }
342}
343
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800344sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100345 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800346 return new RecordingProxy(this);
347}
348
349status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
350{
Steve Block3856b092011-10-20 11:56:00 +0100351 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800352 mCamera->setRecordingProxyListener(listener);
353 mCamera->reconnect();
354 return mCamera->startRecording();
355}
356
357void Camera::RecordingProxy::stopRecording()
358{
Steve Block3856b092011-10-20 11:56:00 +0100359 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800360 mCamera->stopRecording();
361}
362
363void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
364{
Steve Block3856b092011-10-20 11:56:00 +0100365 ALOGV("RecordingProxy::releaseRecordingFrame");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800366 mCamera->releaseRecordingFrame(mem);
367}
368
369Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
370{
371 mCamera = camera;
372}
373
Mathias Agopian3cf61352010-02-09 17:46:37 -0800374}; // namespace android