1/* 2** 3** Copyright (C) 2008, The Android Open Source Project 4** 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> 22#include <utils/String16.h> 23#include <binder/IPCThreadState.h> 24#include <binder/IServiceManager.h> 25#include <binder/IMemory.h> 26 27#include <Camera.h> 28#include <ICameraRecordingProxyListener.h> 29#include <android/hardware/ICameraService.h> 30#include <android/hardware/ICamera.h> 31 32#include <gui/IGraphicBufferProducer.h> 33#include <gui/Surface.h> 34 35namespace android { 36 37Camera::Camera(int cameraId) 38 : CameraBase(cameraId) 39{ 40} 41 42CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = 43 &::android::hardware::ICameraService::connect; 44 45// construct a camera client from an existing camera remote 46sp<Camera> Camera::create(const sp<::android::hardware::ICamera>& camera) 47{ 48 ALOGV("create"); 49 if (camera == 0) { 50 ALOGE("camera remote is a NULL pointer"); 51 return 0; 52 } 53 54 sp<Camera> c = new Camera(-1); 55 if (camera->connect(c) == NO_ERROR) { 56 c->mStatus = NO_ERROR; 57 c->mCamera = camera; 58 IInterface::asBinder(camera)->linkToDeath(c); 59 return c; 60 } 61 return 0; 62} 63 64Camera::~Camera() 65{ 66 // 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. 72} 73 74sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName, 75 int clientUid, int clientPid) 76{ 77 return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid); 78} 79 80status_t Camera::connectLegacy(int cameraId, int halVersion, 81 const String16& clientPackageName, 82 int clientUid, 83 sp<Camera>& camera) 84{ 85 ALOGV("%s: connect legacy camera device", __FUNCTION__); 86 sp<Camera> c = new Camera(cameraId); 87 sp<::android::hardware::ICameraClient> cl = c; 88 status_t status = NO_ERROR; 89 const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService(); 90 91 binder::Status ret; 92 if (cs != nullptr) { 93 ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName, 94 clientUid, /*out*/&(c->mCamera)); 95 } 96 if (ret.isOk() && c->mCamera != nullptr) { 97 IInterface::asBinder(c->mCamera)->linkToDeath(c); 98 c->mStatus = NO_ERROR; 99 camera = c; 100 } else { 101 switch(ret.serviceSpecificErrorCode()) { 102 case hardware::ICameraService::ERROR_DISCONNECTED: 103 status = -ENODEV; 104 break; 105 case hardware::ICameraService::ERROR_CAMERA_IN_USE: 106 status = -EBUSY; 107 break; 108 case hardware::ICameraService::ERROR_INVALID_OPERATION: 109 status = -EINVAL; 110 break; 111 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE: 112 status = -EUSERS; 113 break; 114 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT: 115 status = BAD_VALUE; 116 break; 117 case hardware::ICameraService::ERROR_DEPRECATED_HAL: 118 status = -EOPNOTSUPP; 119 break; 120 case hardware::ICameraService::ERROR_DISABLED: 121 status = -EACCES; 122 break; 123 case hardware::ICameraService::ERROR_PERMISSION_DENIED: 124 status = PERMISSION_DENIED; 125 break; 126 default: 127 status = -EINVAL; 128 ALOGW("An error occurred while connecting to camera %d: %s", cameraId, 129 (cs != nullptr) ? "Service not available" : ret.toString8().string()); 130 break; 131 } 132 c.clear(); 133 } 134 return status; 135} 136 137status_t Camera::reconnect() 138{ 139 ALOGV("reconnect"); 140 sp <::android::hardware::ICamera> c = mCamera; 141 if (c == 0) return NO_INIT; 142 return c->connect(this); 143} 144 145status_t Camera::lock() 146{ 147 sp <::android::hardware::ICamera> c = mCamera; 148 if (c == 0) return NO_INIT; 149 return c->lock(); 150} 151 152status_t Camera::unlock() 153{ 154 sp <::android::hardware::ICamera> c = mCamera; 155 if (c == 0) return NO_INIT; 156 return c->unlock(); 157} 158 159// pass the buffered IGraphicBufferProducer to the camera service 160status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) 161{ 162 ALOGV("setPreviewTarget(%p)", bufferProducer.get()); 163 sp <::android::hardware::ICamera> c = mCamera; 164 if (c == 0) return NO_INIT; 165 ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); 166 return c->setPreviewTarget(bufferProducer); 167} 168 169status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) 170{ 171 ALOGV("setVideoTarget(%p)", bufferProducer.get()); 172 sp <::android::hardware::ICamera> c = mCamera; 173 if (c == 0) return NO_INIT; 174 ALOGD_IF(bufferProducer == 0, "app passed NULL video surface"); 175 return c->setVideoTarget(bufferProducer); 176} 177 178// start preview mode 179status_t Camera::startPreview() 180{ 181 ALOGV("startPreview"); 182 sp <::android::hardware::ICamera> c = mCamera; 183 if (c == 0) return NO_INIT; 184 return c->startPreview(); 185} 186 187status_t Camera::setVideoBufferMode(int32_t videoBufferMode) 188{ 189 ALOGV("setVideoBufferMode: %d", videoBufferMode); 190 sp <::android::hardware::ICamera> c = mCamera; 191 if (c == 0) return NO_INIT; 192 return c->setVideoBufferMode(videoBufferMode); 193} 194 195// start recording mode, must call setPreviewTarget first 196status_t Camera::startRecording() 197{ 198 ALOGV("startRecording"); 199 sp <::android::hardware::ICamera> c = mCamera; 200 if (c == 0) return NO_INIT; 201 return c->startRecording(); 202} 203 204// stop preview mode 205void Camera::stopPreview() 206{ 207 ALOGV("stopPreview"); 208 sp <::android::hardware::ICamera> c = mCamera; 209 if (c == 0) return; 210 c->stopPreview(); 211} 212 213// stop recording mode 214void Camera::stopRecording() 215{ 216 ALOGV("stopRecording"); 217 { 218 Mutex::Autolock _l(mLock); 219 mRecordingProxyListener.clear(); 220 } 221 sp <::android::hardware::ICamera> c = mCamera; 222 if (c == 0) return; 223 c->stopRecording(); 224} 225 226// release a recording frame 227void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 228{ 229 ALOGV("releaseRecordingFrame"); 230 sp <::android::hardware::ICamera> c = mCamera; 231 if (c == 0) return; 232 c->releaseRecordingFrame(mem); 233} 234 235void Camera::releaseRecordingFrameHandle(native_handle_t* handle) 236{ 237 ALOGV("releaseRecordingFrameHandle"); 238 sp <::android::hardware::ICamera> c = mCamera; 239 if (c == 0) return; 240 c->releaseRecordingFrameHandle(handle); 241} 242 243// get preview state 244bool Camera::previewEnabled() 245{ 246 ALOGV("previewEnabled"); 247 sp <::android::hardware::ICamera> c = mCamera; 248 if (c == 0) return false; 249 return c->previewEnabled(); 250} 251 252// get recording state 253bool Camera::recordingEnabled() 254{ 255 ALOGV("recordingEnabled"); 256 sp <::android::hardware::ICamera> c = mCamera; 257 if (c == 0) return false; 258 return c->recordingEnabled(); 259} 260 261status_t Camera::autoFocus() 262{ 263 ALOGV("autoFocus"); 264 sp <::android::hardware::ICamera> c = mCamera; 265 if (c == 0) return NO_INIT; 266 return c->autoFocus(); 267} 268 269status_t Camera::cancelAutoFocus() 270{ 271 ALOGV("cancelAutoFocus"); 272 sp <::android::hardware::ICamera> c = mCamera; 273 if (c == 0) return NO_INIT; 274 return c->cancelAutoFocus(); 275} 276 277// take a picture 278status_t Camera::takePicture(int msgType) 279{ 280 ALOGV("takePicture: 0x%x", msgType); 281 sp <::android::hardware::ICamera> c = mCamera; 282 if (c == 0) return NO_INIT; 283 return c->takePicture(msgType); 284} 285 286// set preview/capture parameters - key/value pairs 287status_t Camera::setParameters(const String8& params) 288{ 289 ALOGV("setParameters"); 290 sp <::android::hardware::ICamera> c = mCamera; 291 if (c == 0) return NO_INIT; 292 return c->setParameters(params); 293} 294 295// get preview/capture parameters - key/value pairs 296String8 Camera::getParameters() const 297{ 298 ALOGV("getParameters"); 299 String8 params; 300 sp <::android::hardware::ICamera> c = mCamera; 301 if (c != 0) params = mCamera->getParameters(); 302 return params; 303} 304 305// send command to camera driver 306status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 307{ 308 ALOGV("sendCommand"); 309 sp <::android::hardware::ICamera> c = mCamera; 310 if (c == 0) return NO_INIT; 311 return c->sendCommand(cmd, arg1, arg2); 312} 313 314void Camera::setListener(const sp<CameraListener>& listener) 315{ 316 Mutex::Autolock _l(mLock); 317 mListener = listener; 318} 319 320void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 321{ 322 Mutex::Autolock _l(mLock); 323 mRecordingProxyListener = listener; 324} 325 326void Camera::setPreviewCallbackFlags(int flag) 327{ 328 ALOGV("setPreviewCallbackFlags"); 329 sp <::android::hardware::ICamera> c = mCamera; 330 if (c == 0) return; 331 mCamera->setPreviewCallbackFlag(flag); 332} 333 334status_t Camera::setPreviewCallbackTarget( 335 const sp<IGraphicBufferProducer>& callbackProducer) 336{ 337 sp <::android::hardware::ICamera> c = mCamera; 338 if (c == 0) return NO_INIT; 339 return c->setPreviewCallbackTarget(callbackProducer); 340} 341 342// callback from camera service 343void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 344{ 345 return CameraBaseT::notifyCallback(msgType, ext1, ext2); 346} 347 348// callback from camera service when frame or image is ready 349void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 350 camera_frame_metadata_t *metadata) 351{ 352 sp<CameraListener> listener; 353 { 354 Mutex::Autolock _l(mLock); 355 listener = mListener; 356 } 357 if (listener != NULL) { 358 listener->postData(msgType, dataPtr, metadata); 359 } 360} 361 362// callback from camera service when timestamped frame is ready 363void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 364{ 365 // If recording proxy listener is registered, forward the frame and return. 366 // The other listener (mListener) is ignored because the receiver needs to 367 // call releaseRecordingFrame. 368 sp<ICameraRecordingProxyListener> proxylistener; 369 { 370 Mutex::Autolock _l(mLock); 371 proxylistener = mRecordingProxyListener; 372 } 373 if (proxylistener != NULL) { 374 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 375 return; 376 } 377 378 sp<CameraListener> listener; 379 { 380 Mutex::Autolock _l(mLock); 381 listener = mListener; 382 } 383 384 if (listener != NULL) { 385 listener->postDataTimestamp(timestamp, msgType, dataPtr); 386 } else { 387 ALOGW("No listener was set. Drop a recording frame."); 388 releaseRecordingFrame(dataPtr); 389 } 390} 391 392void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) 393{ 394 // If recording proxy listener is registered, forward the frame and return. 395 // The other listener (mListener) is ignored because the receiver needs to 396 // call releaseRecordingFrameHandle. 397 sp<ICameraRecordingProxyListener> proxylistener; 398 { 399 Mutex::Autolock _l(mLock); 400 proxylistener = mRecordingProxyListener; 401 } 402 if (proxylistener != NULL) { 403 proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle); 404 return; 405 } 406 407 sp<CameraListener> listener; 408 { 409 Mutex::Autolock _l(mLock); 410 listener = mListener; 411 } 412 413 if (listener != NULL) { 414 listener->postRecordingFrameHandleTimestamp(timestamp, handle); 415 } else { 416 ALOGW("No listener was set. Drop a recording frame."); 417 releaseRecordingFrameHandle(handle); 418 } 419} 420 421sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 422 ALOGV("getProxy"); 423 return new RecordingProxy(this); 424} 425 426status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 427{ 428 ALOGV("RecordingProxy::startRecording"); 429 mCamera->setRecordingProxyListener(listener); 430 mCamera->reconnect(); 431 return mCamera->startRecording(); 432} 433 434void Camera::RecordingProxy::stopRecording() 435{ 436 ALOGV("RecordingProxy::stopRecording"); 437 mCamera->stopRecording(); 438} 439 440void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 441{ 442 ALOGV("RecordingProxy::releaseRecordingFrame"); 443 mCamera->releaseRecordingFrame(mem); 444} 445 446void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) { 447 ALOGV("RecordingProxy::releaseRecordingFrameHandle"); 448 mCamera->releaseRecordingFrameHandle(handle); 449} 450 451Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 452{ 453 mCamera = camera; 454} 455 456}; // namespace android 457