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 35 namespace android { 36 37 Camera::Camera(int cameraId) 38 : CameraBase(cameraId) 39 { 40 } 41 42 CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = 43 &::android::hardware::ICameraService::connect; 44 45 // construct a camera client from an existing camera remote 46 sp<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 64 Camera::~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 74 sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName, 75 int clientUid, int clientPid) 76 { 77 return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid); 78 } 79 80 status_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 137 status_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 145 status_t Camera::lock() 146 { 147 sp <::android::hardware::ICamera> c = mCamera; 148 if (c == 0) return NO_INIT; 149 return c->lock(); 150 } 151 152 status_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 160 status_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 169 status_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 179 status_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 187 status_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 196 status_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 205 void 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 214 void 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 227 void 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 235 void 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 void Camera::releaseRecordingFrameHandleBatch( 244 const std::vector<native_handle_t*> handles) { 245 ALOGV("releaseRecordingFrameHandleBatch"); 246 sp <::android::hardware::ICamera> c = mCamera; 247 if (c == 0) return; 248 c->releaseRecordingFrameHandleBatch(handles); 249 } 250 251 // get preview state 252 bool Camera::previewEnabled() 253 { 254 ALOGV("previewEnabled"); 255 sp <::android::hardware::ICamera> c = mCamera; 256 if (c == 0) return false; 257 return c->previewEnabled(); 258 } 259 260 // get recording state 261 bool Camera::recordingEnabled() 262 { 263 ALOGV("recordingEnabled"); 264 sp <::android::hardware::ICamera> c = mCamera; 265 if (c == 0) return false; 266 return c->recordingEnabled(); 267 } 268 269 status_t Camera::autoFocus() 270 { 271 ALOGV("autoFocus"); 272 sp <::android::hardware::ICamera> c = mCamera; 273 if (c == 0) return NO_INIT; 274 return c->autoFocus(); 275 } 276 277 status_t Camera::cancelAutoFocus() 278 { 279 ALOGV("cancelAutoFocus"); 280 sp <::android::hardware::ICamera> c = mCamera; 281 if (c == 0) return NO_INIT; 282 return c->cancelAutoFocus(); 283 } 284 285 // take a picture 286 status_t Camera::takePicture(int msgType) 287 { 288 ALOGV("takePicture: 0x%x", msgType); 289 sp <::android::hardware::ICamera> c = mCamera; 290 if (c == 0) return NO_INIT; 291 return c->takePicture(msgType); 292 } 293 294 // set preview/capture parameters - key/value pairs 295 status_t Camera::setParameters(const String8& params) 296 { 297 ALOGV("setParameters"); 298 sp <::android::hardware::ICamera> c = mCamera; 299 if (c == 0) return NO_INIT; 300 return c->setParameters(params); 301 } 302 303 // get preview/capture parameters - key/value pairs 304 String8 Camera::getParameters() const 305 { 306 ALOGV("getParameters"); 307 String8 params; 308 sp <::android::hardware::ICamera> c = mCamera; 309 if (c != 0) params = mCamera->getParameters(); 310 return params; 311 } 312 313 // send command to camera driver 314 status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 315 { 316 ALOGV("sendCommand"); 317 sp <::android::hardware::ICamera> c = mCamera; 318 if (c == 0) return NO_INIT; 319 return c->sendCommand(cmd, arg1, arg2); 320 } 321 322 void Camera::setListener(const sp<CameraListener>& listener) 323 { 324 Mutex::Autolock _l(mLock); 325 mListener = listener; 326 } 327 328 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 329 { 330 Mutex::Autolock _l(mLock); 331 mRecordingProxyListener = listener; 332 } 333 334 void Camera::setPreviewCallbackFlags(int flag) 335 { 336 ALOGV("setPreviewCallbackFlags"); 337 sp <::android::hardware::ICamera> c = mCamera; 338 if (c == 0) return; 339 mCamera->setPreviewCallbackFlag(flag); 340 } 341 342 status_t Camera::setPreviewCallbackTarget( 343 const sp<IGraphicBufferProducer>& callbackProducer) 344 { 345 sp <::android::hardware::ICamera> c = mCamera; 346 if (c == 0) return NO_INIT; 347 return c->setPreviewCallbackTarget(callbackProducer); 348 } 349 350 // callback from camera service 351 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 352 { 353 return CameraBaseT::notifyCallback(msgType, ext1, ext2); 354 } 355 356 // callback from camera service when frame or image is ready 357 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 358 camera_frame_metadata_t *metadata) 359 { 360 sp<CameraListener> listener; 361 { 362 Mutex::Autolock _l(mLock); 363 listener = mListener; 364 } 365 if (listener != NULL) { 366 listener->postData(msgType, dataPtr, metadata); 367 } 368 } 369 370 // callback from camera service when timestamped frame is ready 371 void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 372 { 373 // If recording proxy listener is registered, forward the frame and return. 374 // The other listener (mListener) is ignored because the receiver needs to 375 // call releaseRecordingFrame. 376 sp<ICameraRecordingProxyListener> proxylistener; 377 { 378 Mutex::Autolock _l(mLock); 379 proxylistener = mRecordingProxyListener; 380 } 381 if (proxylistener != NULL) { 382 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 383 return; 384 } 385 386 sp<CameraListener> listener; 387 { 388 Mutex::Autolock _l(mLock); 389 listener = mListener; 390 } 391 392 if (listener != NULL) { 393 listener->postDataTimestamp(timestamp, msgType, dataPtr); 394 } else { 395 ALOGW("No listener was set. Drop a recording frame."); 396 releaseRecordingFrame(dataPtr); 397 } 398 } 399 400 void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) 401 { 402 // If recording proxy listener is registered, forward the frame and return. 403 // The other listener (mListener) is ignored because the receiver needs to 404 // call releaseRecordingFrameHandle. 405 sp<ICameraRecordingProxyListener> proxylistener; 406 { 407 Mutex::Autolock _l(mLock); 408 proxylistener = mRecordingProxyListener; 409 } 410 if (proxylistener != NULL) { 411 proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle); 412 return; 413 } 414 415 sp<CameraListener> listener; 416 { 417 Mutex::Autolock _l(mLock); 418 listener = mListener; 419 } 420 421 if (listener != NULL) { 422 listener->postRecordingFrameHandleTimestamp(timestamp, handle); 423 } else { 424 ALOGW("No listener was set. Drop a recording frame."); 425 releaseRecordingFrameHandle(handle); 426 } 427 } 428 429 void Camera::recordingFrameHandleCallbackTimestampBatch( 430 const std::vector<nsecs_t>& timestamps, 431 const std::vector<native_handle_t*>& handles) 432 { 433 // If recording proxy listener is registered, forward the frame and return. 434 // The other listener (mListener) is ignored because the receiver needs to 435 // call releaseRecordingFrameHandle. 436 sp<ICameraRecordingProxyListener> proxylistener; 437 { 438 Mutex::Autolock _l(mLock); 439 proxylistener = mRecordingProxyListener; 440 } 441 if (proxylistener != NULL) { 442 proxylistener->recordingFrameHandleCallbackTimestampBatch(timestamps, handles); 443 return; 444 } 445 446 sp<CameraListener> listener; 447 { 448 Mutex::Autolock _l(mLock); 449 listener = mListener; 450 } 451 452 if (listener != NULL) { 453 listener->postRecordingFrameHandleTimestampBatch(timestamps, handles); 454 } else { 455 ALOGW("No listener was set. Drop a batch of recording frames."); 456 releaseRecordingFrameHandleBatch(handles); 457 } 458 } 459 460 sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 461 ALOGV("getProxy"); 462 return new RecordingProxy(this); 463 } 464 465 status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 466 { 467 ALOGV("RecordingProxy::startRecording"); 468 mCamera->setRecordingProxyListener(listener); 469 mCamera->reconnect(); 470 return mCamera->startRecording(); 471 } 472 473 void Camera::RecordingProxy::stopRecording() 474 { 475 ALOGV("RecordingProxy::stopRecording"); 476 mCamera->stopRecording(); 477 } 478 479 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 480 { 481 ALOGV("RecordingProxy::releaseRecordingFrame"); 482 mCamera->releaseRecordingFrame(mem); 483 } 484 485 void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) { 486 ALOGV("RecordingProxy::releaseRecordingFrameHandle"); 487 mCamera->releaseRecordingFrameHandle(handle); 488 } 489 490 void Camera::RecordingProxy::releaseRecordingFrameHandleBatch( 491 const std::vector<native_handle_t*>& handles) { 492 ALOGV("RecordingProxy::releaseRecordingFrameHandleBatch"); 493 mCamera->releaseRecordingFrameHandleBatch(handles); 494 } 495 496 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 497 { 498 mCamera = camera; 499 } 500 501 }; // namespace android 502