blob: 1da4fa699eae7939e4f7f716224f342ccab156d6 [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>
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +080022#include <binder/IPCThreadState.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080023#include <binder/IServiceManager.h>
24#include <binder/IMemory.h>
25
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080026#include <Camera.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080027#include <android/hardware/ICameraService.h>
28#include <android/hardware/ICamera.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080029#include <gui/Surface.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080030
31namespace android {
32
Igor Murashkinc073ba52013-02-26 14:32:34 -080033Camera::Camera(int cameraId)
34 : CameraBase(cameraId)
Mathias Agopian3cf61352010-02-09 17:46:37 -080035{
Mathias Agopian3cf61352010-02-09 17:46:37 -080036}
37
Ruben Brunk0f61d8f2013-08-08 13:07:18 -070038CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080039 &::android::hardware::ICameraService::connect;
Ruben Brunk0f61d8f2013-08-08 13:07:18 -070040
Mathias Agopian3cf61352010-02-09 17:46:37 -080041// construct a camera client from an existing camera remote
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080042sp<Camera> Camera::create(const sp<::android::hardware::ICamera>& camera)
Mathias Agopian3cf61352010-02-09 17:46:37 -080043{
Steve Block3856b092011-10-20 11:56:00 +010044 ALOGV("create");
Mathias Agopian3cf61352010-02-09 17:46:37 -080045 if (camera == 0) {
Steve Block29357bc2012-01-06 19:20:56 +000046 ALOGE("camera remote is a NULL pointer");
Mathias Agopian3cf61352010-02-09 17:46:37 -080047 return 0;
48 }
49
Igor Murashkinc073ba52013-02-26 14:32:34 -080050 sp<Camera> c = new Camera(-1);
Mathias Agopian3cf61352010-02-09 17:46:37 -080051 if (camera->connect(c) == NO_ERROR) {
52 c->mStatus = NO_ERROR;
53 c->mCamera = camera;
Marco Nelissen06b46062014-11-14 07:58:25 -080054 IInterface::asBinder(camera)->linkToDeath(c);
Wu-cheng Li627baac2011-01-04 20:00:55 +080055 return c;
Mathias Agopian3cf61352010-02-09 17:46:37 -080056 }
Wu-cheng Li627baac2011-01-04 20:00:55 +080057 return 0;
Mathias Agopian3cf61352010-02-09 17:46:37 -080058}
59
Mathias Agopian3cf61352010-02-09 17:46:37 -080060Camera::~Camera()
61{
Chih-Chung Changd06618e2010-05-13 15:14:24 +080062 // We don't need to call disconnect() here because if the CameraService
63 // thinks we are the owner of the hardware, it will hold a (strong)
64 // reference to us, and we can't possibly be here. We also don't want to
65 // call disconnect() here if we are in the same process as mediaserver,
66 // because we may be invoked by CameraService::Client::connect() and will
67 // deadlock if we call any method of ICamera here.
Mathias Agopian3cf61352010-02-09 17:46:37 -080068}
69
Austin Borgerd1ad6c62024-07-01 11:28:31 -070070sp<Camera> Camera::connect(int cameraId, int targetSdkVersion, int rotationOverride,
Austin Borger65e64642024-06-11 15:58:23 -070071 bool forceSlowJpegMode, const AttributionSourceState& clientAttribution,
72 int32_t devicePolicy)
Mathias Agopian3cf61352010-02-09 17:46:37 -080073{
Austin Borgerd1ad6c62024-07-01 11:28:31 -070074 return CameraBaseT::connect(cameraId, targetSdkVersion, rotationOverride,
Austin Borger65e64642024-06-11 15:58:23 -070075 forceSlowJpegMode, clientAttribution, devicePolicy);
Mathias Agopian3cf61352010-02-09 17:46:37 -080076}
77
78status_t Camera::reconnect()
79{
Steve Block3856b092011-10-20 11:56:00 +010080 ALOGV("reconnect");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080081 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -080082 if (c == 0) return NO_INIT;
83 return c->connect(this);
84}
85
Mathias Agopian3cf61352010-02-09 17:46:37 -080086status_t Camera::lock()
87{
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080088 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -080089 if (c == 0) return NO_INIT;
90 return c->lock();
91}
92
93status_t Camera::unlock()
94{
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080095 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -080096 if (c == 0) return NO_INIT;
97 return c->unlock();
98}
99
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700100// pass the Surface to the camera service
101status_t Camera::setPreviewTarget(const sp<SurfaceType>& target) {
102 ALOGV("setPreviewTarget(%p)", target.get());
103 sp<::android::hardware::ICamera> c = mCamera;
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800104 if (c == 0) return NO_INIT;
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700105 ALOGD_IF(target == 0, "app passed NULL surface");
106 return c->setPreviewTarget(target);
Jamie Gennisbfa33aa2010-12-20 11:51:31 -0800107}
108
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700109status_t Camera::setVideoTarget(const sp<SurfaceType>& target) {
110 ALOGV("setVideoTarget(%p)", target.get());
111 sp<::android::hardware::ICamera> c = mCamera;
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800112 if (c == 0) return NO_INIT;
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700113 ALOGD_IF(target == 0, "app passed NULL video surface");
114 return c->setVideoTarget(target);
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800115}
116
Mathias Agopian3cf61352010-02-09 17:46:37 -0800117// start preview mode
118status_t Camera::startPreview()
119{
Steve Block3856b092011-10-20 11:56:00 +0100120 ALOGV("startPreview");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800121 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800122 if (c == 0) return NO_INIT;
123 return c->startPreview();
124}
125
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800126status_t Camera::setVideoBufferMode(int32_t videoBufferMode)
James Donge2ad6732010-10-18 20:42:51 -0700127{
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800128 ALOGV("setVideoBufferMode: %d", videoBufferMode);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800129 sp <::android::hardware::ICamera> c = mCamera;
James Donge2ad6732010-10-18 20:42:51 -0700130 if (c == 0) return NO_INIT;
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800131 return c->setVideoBufferMode(videoBufferMode);
James Donge2ad6732010-10-18 20:42:51 -0700132}
133
Eino-Ville Talvala4b820b02013-08-21 14:39:05 -0700134// start recording mode, must call setPreviewTarget first
Mathias Agopian3cf61352010-02-09 17:46:37 -0800135status_t Camera::startRecording()
136{
Steve Block3856b092011-10-20 11:56:00 +0100137 ALOGV("startRecording");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800138 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800139 if (c == 0) return NO_INIT;
140 return c->startRecording();
141}
142
143// stop preview mode
144void Camera::stopPreview()
145{
Steve Block3856b092011-10-20 11:56:00 +0100146 ALOGV("stopPreview");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800147 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800148 if (c == 0) return;
149 c->stopPreview();
150}
151
152// stop recording mode
153void Camera::stopRecording()
154{
Steve Block3856b092011-10-20 11:56:00 +0100155 ALOGV("stopRecording");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800156 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800157 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");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800165 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800166 if (c == 0) return;
167 c->releaseRecordingFrame(mem);
168}
169
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700170void Camera::releaseRecordingFrameHandle(native_handle_t* handle)
171{
172 ALOGV("releaseRecordingFrameHandle");
173 sp <::android::hardware::ICamera> c = mCamera;
174 if (c == 0) return;
175 c->releaseRecordingFrameHandle(handle);
176}
177
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700178void Camera::releaseRecordingFrameHandleBatch(
179 const std::vector<native_handle_t*> handles) {
180 ALOGV("releaseRecordingFrameHandleBatch");
181 sp <::android::hardware::ICamera> c = mCamera;
182 if (c == 0) return;
183 c->releaseRecordingFrameHandleBatch(handles);
184}
185
Mathias Agopian3cf61352010-02-09 17:46:37 -0800186// get preview state
187bool Camera::previewEnabled()
188{
Steve Block3856b092011-10-20 11:56:00 +0100189 ALOGV("previewEnabled");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800190 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800191 if (c == 0) return false;
192 return c->previewEnabled();
193}
194
195// get recording state
196bool Camera::recordingEnabled()
197{
Steve Block3856b092011-10-20 11:56:00 +0100198 ALOGV("recordingEnabled");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800199 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800200 if (c == 0) return false;
201 return c->recordingEnabled();
202}
203
204status_t Camera::autoFocus()
205{
Steve Block3856b092011-10-20 11:56:00 +0100206 ALOGV("autoFocus");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800207 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800208 if (c == 0) return NO_INIT;
209 return c->autoFocus();
210}
211
212status_t Camera::cancelAutoFocus()
213{
Steve Block3856b092011-10-20 11:56:00 +0100214 ALOGV("cancelAutoFocus");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800215 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800216 if (c == 0) return NO_INIT;
217 return c->cancelAutoFocus();
218}
219
220// take a picture
James Donge468ac52011-02-17 16:38:06 -0800221status_t Camera::takePicture(int msgType)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800222{
Steve Block3856b092011-10-20 11:56:00 +0100223 ALOGV("takePicture: 0x%x", msgType);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800224 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800225 if (c == 0) return NO_INIT;
James Donge468ac52011-02-17 16:38:06 -0800226 return c->takePicture(msgType);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800227}
228
229// set preview/capture parameters - key/value pairs
230status_t Camera::setParameters(const String8& params)
231{
Steve Block3856b092011-10-20 11:56:00 +0100232 ALOGV("setParameters");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800233 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800234 if (c == 0) return NO_INIT;
235 return c->setParameters(params);
236}
237
238// get preview/capture parameters - key/value pairs
239String8 Camera::getParameters() const
240{
Steve Block3856b092011-10-20 11:56:00 +0100241 ALOGV("getParameters");
Mathias Agopian3cf61352010-02-09 17:46:37 -0800242 String8 params;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800243 sp <::android::hardware::ICamera> c = mCamera;
Tony Guo3966c1f2023-09-07 03:46:05 +0000244 if (c != 0) params = c->getParameters();
Mathias Agopian3cf61352010-02-09 17:46:37 -0800245 return params;
246}
247
248// send command to camera driver
249status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
250{
Steve Block3856b092011-10-20 11:56:00 +0100251 ALOGV("sendCommand");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800252 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800253 if (c == 0) return NO_INIT;
254 return c->sendCommand(cmd, arg1, arg2);
255}
256
257void Camera::setListener(const sp<CameraListener>& listener)
258{
259 Mutex::Autolock _l(mLock);
260 mListener = listener;
261}
262
263void Camera::setPreviewCallbackFlags(int flag)
264{
Steve Block3856b092011-10-20 11:56:00 +0100265 ALOGV("setPreviewCallbackFlags");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800266 sp <::android::hardware::ICamera> c = mCamera;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800267 if (c == 0) return;
Tony Guo3966c1f2023-09-07 03:46:05 +0000268 c->setPreviewCallbackFlag(flag);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800269}
270
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700271status_t Camera::setPreviewCallbackTarget(const sp<SurfaceType>& target) {
272 sp<::android::hardware::ICamera> c = mCamera;
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700273 if (c == 0) return NO_INIT;
Carlos Martinez Romeroca0ff172024-09-12 08:45:52 -0700274 return c->setPreviewCallbackTarget(target);
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700275}
276
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -0700277status_t Camera::setAudioRestriction(int32_t mode)
Yin-Chia Yehdba03232019-08-19 15:54:28 -0700278{
279 sp <::android::hardware::ICamera> c = mCamera;
280 if (c == 0) return NO_INIT;
281 return c->setAudioRestriction(mode);
282}
283
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -0700284int32_t Camera::getGlobalAudioRestriction()
285{
286 sp <::android::hardware::ICamera> c = mCamera;
287 if (c == 0) return NO_INIT;
288 return c->getGlobalAudioRestriction();
289}
290
Mathias Agopian3cf61352010-02-09 17:46:37 -0800291// callback from camera service
292void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
293{
Igor Murashkinc073ba52013-02-26 14:32:34 -0800294 return CameraBaseT::notifyCallback(msgType, ext1, ext2);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800295}
296
297// callback from camera service when frame or image is ready
Wu-cheng Li57c86182011-07-30 05:00:37 +0800298void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
299 camera_frame_metadata_t *metadata)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800300{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800301 sp<CameraListener> listener;
302 {
303 Mutex::Autolock _l(mLock);
304 listener = mListener;
305 }
306 if (listener != NULL) {
307 listener->postData(msgType, dataPtr, metadata);
308 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800309}
310
311// callback from camera service when timestamped frame is ready
312void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
313{
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800314 sp<CameraListener> listener;
315 {
316 Mutex::Autolock _l(mLock);
317 listener = mListener;
318 }
319
320 if (listener != NULL) {
321 listener->postDataTimestamp(timestamp, msgType, dataPtr);
322 } else {
Steve Block5ff1dd52012-01-05 23:22:43 +0000323 ALOGW("No listener was set. Drop a recording frame.");
James Dongc42478e2010-11-15 10:38:37 -0800324 releaseRecordingFrame(dataPtr);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800325 }
326}
327
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700328void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle)
329{
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700330 sp<CameraListener> listener;
331 {
332 Mutex::Autolock _l(mLock);
333 listener = mListener;
334 }
335
336 if (listener != NULL) {
337 listener->postRecordingFrameHandleTimestamp(timestamp, handle);
338 } else {
339 ALOGW("No listener was set. Drop a recording frame.");
340 releaseRecordingFrameHandle(handle);
341 }
342}
343
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700344void Camera::recordingFrameHandleCallbackTimestampBatch(
345 const std::vector<nsecs_t>& timestamps,
346 const std::vector<native_handle_t*>& handles)
347{
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700348 sp<CameraListener> listener;
349 {
350 Mutex::Autolock _l(mLock);
351 listener = mListener;
352 }
353
354 if (listener != NULL) {
355 listener->postRecordingFrameHandleTimestampBatch(timestamps, handles);
356 } else {
357 ALOGW("No listener was set. Drop a batch of recording frames.");
358 releaseRecordingFrameHandleBatch(handles);
359 }
360}
361
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800362sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
Steve Block3856b092011-10-20 11:56:00 +0100363 ALOGV("getProxy");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800364 return new RecordingProxy(this);
365}
366
Eino-Ville Talvalab8ed8ef2020-06-22 16:59:48 -0700367status_t Camera::RecordingProxy::startRecording()
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800368{
Steve Block3856b092011-10-20 11:56:00 +0100369 ALOGV("RecordingProxy::startRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800370 mCamera->reconnect();
371 return mCamera->startRecording();
372}
373
374void Camera::RecordingProxy::stopRecording()
375{
Steve Block3856b092011-10-20 11:56:00 +0100376 ALOGV("RecordingProxy::stopRecording");
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800377 mCamera->stopRecording();
378}
379
Wu-cheng Li4ca2c7c2011-06-01 17:22:24 +0800380Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
381{
382 mCamera = camera;
383}
384
Mathias Agopian3cf61352010-02-09 17:46:37 -0800385}; // namespace android