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 <binder/IPCThreadState.h> 23 #include <binder/IServiceManager.h> 24 #include <binder/IMemory.h> 25 26 #include <camera/Camera.h> 27 #include <camera/ICameraRecordingProxyListener.h> 28 #include <camera/ICameraService.h> 29 30 #include <gui/ISurfaceTexture.h> 31 #include <gui/Surface.h> 32 33 namespace android { 34 35 // client singleton for camera service binder interface 36 Mutex Camera::mLock; 37 sp<ICameraService> Camera::mCameraService; 38 sp<Camera::DeathNotifier> Camera::mDeathNotifier; 39 40 // establish binder interface to camera service 41 const sp<ICameraService>& Camera::getCameraService() 42 { 43 Mutex::Autolock _l(mLock); 44 if (mCameraService.get() == 0) { 45 sp<IServiceManager> sm = defaultServiceManager(); 46 sp<IBinder> binder; 47 do { 48 binder = sm->getService(String16("media.camera")); 49 if (binder != 0) 50 break; 51 ALOGW("CameraService not published, waiting..."); 52 usleep(500000); // 0.5 s 53 } while(true); 54 if (mDeathNotifier == NULL) { 55 mDeathNotifier = new DeathNotifier(); 56 } 57 binder->linkToDeath(mDeathNotifier); 58 mCameraService = interface_cast<ICameraService>(binder); 59 } 60 ALOGE_IF(mCameraService==0, "no CameraService!?"); 61 return mCameraService; 62 } 63 64 // --------------------------------------------------------------------------- 65 66 Camera::Camera() 67 { 68 init(); 69 } 70 71 // construct a camera client from an existing camera remote 72 sp<Camera> Camera::create(const sp<ICamera>& camera) 73 { 74 ALOGV("create"); 75 if (camera == 0) { 76 ALOGE("camera remote is a NULL pointer"); 77 return 0; 78 } 79 80 sp<Camera> c = new Camera(); 81 if (camera->connect(c) == NO_ERROR) { 82 c->mStatus = NO_ERROR; 83 c->mCamera = camera; 84 camera->asBinder()->linkToDeath(c); 85 return c; 86 } 87 return 0; 88 } 89 90 void Camera::init() 91 { 92 mStatus = UNKNOWN_ERROR; 93 } 94 95 Camera::~Camera() 96 { 97 // We don't need to call disconnect() here because if the CameraService 98 // thinks we are the owner of the hardware, it will hold a (strong) 99 // reference to us, and we can't possibly be here. We also don't want to 100 // call disconnect() here if we are in the same process as mediaserver, 101 // because we may be invoked by CameraService::Client::connect() and will 102 // deadlock if we call any method of ICamera here. 103 } 104 105 int32_t Camera::getNumberOfCameras() 106 { 107 const sp<ICameraService>& cs = getCameraService(); 108 if (cs == 0) return 0; 109 return cs->getNumberOfCameras(); 110 } 111 112 status_t Camera::getCameraInfo(int cameraId, 113 struct CameraInfo* cameraInfo) { 114 const sp<ICameraService>& cs = getCameraService(); 115 if (cs == 0) return UNKNOWN_ERROR; 116 return cs->getCameraInfo(cameraId, cameraInfo); 117 } 118 119 sp<Camera> Camera::connect(int cameraId) 120 { 121 ALOGV("connect"); 122 sp<Camera> c = new Camera(); 123 const sp<ICameraService>& cs = getCameraService(); 124 if (cs != 0) { 125 c->mCamera = cs->connect(c, cameraId); 126 } 127 if (c->mCamera != 0) { 128 c->mCamera->asBinder()->linkToDeath(c); 129 c->mStatus = NO_ERROR; 130 } else { 131 c.clear(); 132 } 133 return c; 134 } 135 136 void Camera::disconnect() 137 { 138 ALOGV("disconnect"); 139 if (mCamera != 0) { 140 mCamera->disconnect(); 141 mCamera->asBinder()->unlinkToDeath(this); 142 mCamera = 0; 143 } 144 } 145 146 status_t Camera::reconnect() 147 { 148 ALOGV("reconnect"); 149 sp <ICamera> c = mCamera; 150 if (c == 0) return NO_INIT; 151 return c->connect(this); 152 } 153 154 sp<ICamera> Camera::remote() 155 { 156 return mCamera; 157 } 158 159 status_t Camera::lock() 160 { 161 sp <ICamera> c = mCamera; 162 if (c == 0) return NO_INIT; 163 return c->lock(); 164 } 165 166 status_t Camera::unlock() 167 { 168 sp <ICamera> c = mCamera; 169 if (c == 0) return NO_INIT; 170 return c->unlock(); 171 } 172 173 // pass the buffered Surface to the camera service 174 status_t Camera::setPreviewDisplay(const sp<Surface>& surface) 175 { 176 ALOGV("setPreviewDisplay(%p)", surface.get()); 177 sp <ICamera> c = mCamera; 178 if (c == 0) return NO_INIT; 179 if (surface != 0) { 180 return c->setPreviewDisplay(surface); 181 } else { 182 ALOGD("app passed NULL surface"); 183 return c->setPreviewDisplay(0); 184 } 185 } 186 187 // pass the buffered ISurfaceTexture to the camera service 188 status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture) 189 { 190 ALOGV("setPreviewTexture(%p)", surfaceTexture.get()); 191 sp <ICamera> c = mCamera; 192 if (c == 0) return NO_INIT; 193 if (surfaceTexture != 0) { 194 return c->setPreviewTexture(surfaceTexture); 195 } else { 196 ALOGD("app passed NULL surface"); 197 return c->setPreviewTexture(0); 198 } 199 } 200 201 // start preview mode 202 status_t Camera::startPreview() 203 { 204 ALOGV("startPreview"); 205 sp <ICamera> c = mCamera; 206 if (c == 0) return NO_INIT; 207 return c->startPreview(); 208 } 209 210 status_t Camera::storeMetaDataInBuffers(bool enabled) 211 { 212 ALOGV("storeMetaDataInBuffers: %s", 213 enabled? "true": "false"); 214 sp <ICamera> c = mCamera; 215 if (c == 0) return NO_INIT; 216 return c->storeMetaDataInBuffers(enabled); 217 } 218 219 // start recording mode, must call setPreviewDisplay first 220 status_t Camera::startRecording() 221 { 222 ALOGV("startRecording"); 223 sp <ICamera> c = mCamera; 224 if (c == 0) return NO_INIT; 225 return c->startRecording(); 226 } 227 228 // stop preview mode 229 void Camera::stopPreview() 230 { 231 ALOGV("stopPreview"); 232 sp <ICamera> c = mCamera; 233 if (c == 0) return; 234 c->stopPreview(); 235 } 236 237 // stop recording mode 238 void Camera::stopRecording() 239 { 240 ALOGV("stopRecording"); 241 { 242 Mutex::Autolock _l(mLock); 243 mRecordingProxyListener.clear(); 244 } 245 sp <ICamera> c = mCamera; 246 if (c == 0) return; 247 c->stopRecording(); 248 } 249 250 // release a recording frame 251 void Camera::releaseRecordingFrame(const sp<IMemory>& mem) 252 { 253 ALOGV("releaseRecordingFrame"); 254 sp <ICamera> c = mCamera; 255 if (c == 0) return; 256 c->releaseRecordingFrame(mem); 257 } 258 259 // get preview state 260 bool Camera::previewEnabled() 261 { 262 ALOGV("previewEnabled"); 263 sp <ICamera> c = mCamera; 264 if (c == 0) return false; 265 return c->previewEnabled(); 266 } 267 268 // get recording state 269 bool Camera::recordingEnabled() 270 { 271 ALOGV("recordingEnabled"); 272 sp <ICamera> c = mCamera; 273 if (c == 0) return false; 274 return c->recordingEnabled(); 275 } 276 277 status_t Camera::autoFocus() 278 { 279 ALOGV("autoFocus"); 280 sp <ICamera> c = mCamera; 281 if (c == 0) return NO_INIT; 282 return c->autoFocus(); 283 } 284 285 status_t Camera::cancelAutoFocus() 286 { 287 ALOGV("cancelAutoFocus"); 288 sp <ICamera> c = mCamera; 289 if (c == 0) return NO_INIT; 290 return c->cancelAutoFocus(); 291 } 292 293 // take a picture 294 status_t Camera::takePicture(int msgType) 295 { 296 ALOGV("takePicture: 0x%x", msgType); 297 sp <ICamera> c = mCamera; 298 if (c == 0) return NO_INIT; 299 return c->takePicture(msgType); 300 } 301 302 // set preview/capture parameters - key/value pairs 303 status_t Camera::setParameters(const String8& params) 304 { 305 ALOGV("setParameters"); 306 sp <ICamera> c = mCamera; 307 if (c == 0) return NO_INIT; 308 return c->setParameters(params); 309 } 310 311 // get preview/capture parameters - key/value pairs 312 String8 Camera::getParameters() const 313 { 314 ALOGV("getParameters"); 315 String8 params; 316 sp <ICamera> c = mCamera; 317 if (c != 0) params = mCamera->getParameters(); 318 return params; 319 } 320 321 // send command to camera driver 322 status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 323 { 324 ALOGV("sendCommand"); 325 sp <ICamera> c = mCamera; 326 if (c == 0) return NO_INIT; 327 return c->sendCommand(cmd, arg1, arg2); 328 } 329 330 void Camera::setListener(const sp<CameraListener>& listener) 331 { 332 Mutex::Autolock _l(mLock); 333 mListener = listener; 334 } 335 336 void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener) 337 { 338 Mutex::Autolock _l(mLock); 339 mRecordingProxyListener = listener; 340 } 341 342 void Camera::setPreviewCallbackFlags(int flag) 343 { 344 ALOGV("setPreviewCallbackFlags"); 345 sp <ICamera> c = mCamera; 346 if (c == 0) return; 347 mCamera->setPreviewCallbackFlag(flag); 348 } 349 350 // callback from camera service 351 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) 352 { 353 sp<CameraListener> listener; 354 { 355 Mutex::Autolock _l(mLock); 356 listener = mListener; 357 } 358 if (listener != NULL) { 359 listener->notify(msgType, ext1, ext2); 360 } 361 } 362 363 // callback from camera service when frame or image is ready 364 void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, 365 camera_frame_metadata_t *metadata) 366 { 367 sp<CameraListener> listener; 368 { 369 Mutex::Autolock _l(mLock); 370 listener = mListener; 371 } 372 if (listener != NULL) { 373 listener->postData(msgType, dataPtr, metadata); 374 } 375 } 376 377 // callback from camera service when timestamped frame is ready 378 void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 379 { 380 // If recording proxy listener is registered, forward the frame and return. 381 // The other listener (mListener) is ignored because the receiver needs to 382 // call releaseRecordingFrame. 383 sp<ICameraRecordingProxyListener> proxylistener; 384 { 385 Mutex::Autolock _l(mLock); 386 proxylistener = mRecordingProxyListener; 387 } 388 if (proxylistener != NULL) { 389 proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); 390 return; 391 } 392 393 sp<CameraListener> listener; 394 { 395 Mutex::Autolock _l(mLock); 396 listener = mListener; 397 } 398 if (listener != NULL) { 399 listener->postDataTimestamp(timestamp, msgType, dataPtr); 400 } else { 401 ALOGW("No listener was set. Drop a recording frame."); 402 releaseRecordingFrame(dataPtr); 403 } 404 } 405 406 void Camera::binderDied(const wp<IBinder>& who) { 407 ALOGW("ICamera died"); 408 notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); 409 } 410 411 void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { 412 ALOGV("binderDied"); 413 Mutex::Autolock _l(Camera::mLock); 414 Camera::mCameraService.clear(); 415 ALOGW("Camera server died!"); 416 } 417 418 sp<ICameraRecordingProxy> Camera::getRecordingProxy() { 419 ALOGV("getProxy"); 420 return new RecordingProxy(this); 421 } 422 423 status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener) 424 { 425 ALOGV("RecordingProxy::startRecording"); 426 mCamera->setRecordingProxyListener(listener); 427 mCamera->reconnect(); 428 return mCamera->startRecording(); 429 } 430 431 void Camera::RecordingProxy::stopRecording() 432 { 433 ALOGV("RecordingProxy::stopRecording"); 434 mCamera->stopRecording(); 435 } 436 437 void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem) 438 { 439 ALOGV("RecordingProxy::releaseRecordingFrame"); 440 mCamera->releaseRecordingFrame(mem); 441 } 442 443 Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera) 444 { 445 mCamera = camera; 446 } 447 448 }; // namespace android 449