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 // get preview state 244 bool 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 253 bool 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 261 status_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 269 status_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 278 status_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 287 status_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 296 String8 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 306 status_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 314 void Camera::setListener(const sp<CameraListener>& listener) 315 { 316 Mutex::Autolock _l(mLock); 317 mListener = listener; 318 } 319 320 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 321 { 322 Mutex::Autolock _l(mLock); 323 mRecordingProxyListener = listener; 324 } 325 326 void 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 334 status_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 343 void 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 349 void 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 363 void 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 392 void 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 421 sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 422 ALOGV("getProxy"); 423 return new RecordingProxy(this); 424 } 425 426 status_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 434 void Camera::RecordingProxy::stopRecording() 435 { 436 ALOGV("RecordingProxy::stopRecording"); 437 mCamera->stopRecording(); 438 } 439 440 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 441 { 442 ALOGV("RecordingProxy::releaseRecordingFrame"); 443 mCamera->releaseRecordingFrame(mem); 444 } 445 446 void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) { 447 ALOGV("RecordingProxy::releaseRecordingFrameHandle"); 448 mCamera->releaseRecordingFrameHandle(handle); 449 } 450 451 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 452 { 453 mCamera = camera; 454 } 455 456 }; // namespace android 457