ACameraManager.cpp revision 02bf03287652923b5bb5316667b065423565d6b4
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ACameraManager" 19 20#include <memory> 21#include "ACameraManager.h" 22#include "ACameraMetadata.h" 23#include "ACameraDevice.h" 24#include <utils/Vector.h> 25#include <stdlib.h> 26#include <camera/VendorTagDescriptor.h> 27 28using namespace android; 29 30//constants shared between ACameraManager and CameraManagerGlobal 31namespace { 32 const int kMaxCameraIdLen = 32; 33} 34 35namespace android { 36// Static member definitions 37const char* CameraManagerGlobal::kCameraIdKey = "CameraId"; 38const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp"; 39const char* CameraManagerGlobal::kContextKey = "CallbackContext"; 40Mutex CameraManagerGlobal::sLock; 41CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr; 42 43CameraManagerGlobal& 44CameraManagerGlobal::getInstance() { 45 Mutex::Autolock _l(sLock); 46 CameraManagerGlobal* instance = sInstance; 47 if (instance == nullptr) { 48 instance = new CameraManagerGlobal(); 49 sInstance = instance; 50 } 51 return *instance; 52} 53 54CameraManagerGlobal::~CameraManagerGlobal() { 55 // clear sInstance so next getInstance call knows to create a new one 56 Mutex::Autolock _sl(sLock); 57 sInstance = nullptr; 58 Mutex::Autolock _l(mLock); 59 if (mCameraService != nullptr) { 60 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier); 61 mCameraService->removeListener(mCameraServiceListener); 62 } 63 mDeathNotifier.clear(); 64 if (mCbLooper != nullptr) { 65 mCbLooper->unregisterHandler(mHandler->id()); 66 mCbLooper->stop(); 67 } 68 mCbLooper.clear(); 69 mHandler.clear(); 70 mCameraServiceListener.clear(); 71 mCameraService.clear(); 72} 73 74sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() { 75 Mutex::Autolock _l(mLock); 76 if (mCameraService.get() == nullptr) { 77 sp<IServiceManager> sm = defaultServiceManager(); 78 sp<IBinder> binder; 79 do { 80 binder = sm->getService(String16(kCameraServiceName)); 81 if (binder != nullptr) { 82 break; 83 } 84 ALOGW("CameraService not published, waiting..."); 85 usleep(kCameraServicePollDelay); 86 } while(true); 87 if (mDeathNotifier == nullptr) { 88 mDeathNotifier = new DeathNotifier(this); 89 } 90 binder->linkToDeath(mDeathNotifier); 91 mCameraService = interface_cast<hardware::ICameraService>(binder); 92 93 // Setup looper thread to perfrom availiability callbacks 94 if (mCbLooper == nullptr) { 95 mCbLooper = new ALooper; 96 mCbLooper->setName("C2N-mgr-looper"); 97 status_t err = mCbLooper->start( 98 /*runOnCallingThread*/false, 99 /*canCallJava*/ true, 100 PRIORITY_DEFAULT); 101 if (err != OK) { 102 ALOGE("%s: Unable to start camera service listener looper: %s (%d)", 103 __FUNCTION__, strerror(-err), err); 104 mCbLooper.clear(); 105 return nullptr; 106 } 107 if (mHandler == nullptr) { 108 mHandler = new CallbackHandler(); 109 } 110 mCbLooper->registerHandler(mHandler); 111 } 112 113 // register ICameraServiceListener 114 if (mCameraServiceListener == nullptr) { 115 mCameraServiceListener = new CameraServiceListener(this); 116 } 117 mCameraService->addListener(mCameraServiceListener); 118 119 // setup vendor tags 120 sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); 121 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get()); 122 123 if (ret.isOk()) { 124 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc); 125 if (err != OK) { 126 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)", 127 __FUNCTION__, strerror(-err), err); 128 } 129 } else if (ret.serviceSpecificErrorCode() == 130 hardware::ICameraService::ERROR_DEPRECATED_HAL) { 131 ALOGW("%s: Camera HAL too old; does not support vendor tags", 132 __FUNCTION__); 133 VendorTagDescriptor::clearGlobalVendorTagDescriptor(); 134 } else { 135 ALOGE("%s: Failed to get vendor tag descriptors: %s", 136 __FUNCTION__, ret.toString8().string()); 137 } 138 } 139 ALOGE_IF(mCameraService == nullptr, "no CameraService!?"); 140 return mCameraService; 141} 142 143void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) 144{ 145 ALOGE("Camera service binderDied!"); 146 sp<CameraManagerGlobal> cm = mCameraManager.promote(); 147 if (cm != nullptr) { 148 AutoMutex lock(cm->mLock); 149 for (auto pair : cm->mDeviceStatusMap) { 150 int32_t cameraId = pair.first; 151 cm->onStatusChangedLocked( 152 CameraServiceListener::STATUS_NOT_PRESENT, cameraId); 153 } 154 cm->mCameraService.clear(); 155 // TODO: consider adding re-connect call here? 156 } 157} 158 159void CameraManagerGlobal::registerAvailabilityCallback( 160 const ACameraManager_AvailabilityCallbacks *callback) { 161 Mutex::Autolock _l(mLock); 162 Callback cb(callback); 163 auto pair = mCallbacks.insert(cb); 164 // Send initial callbacks if callback is newly registered 165 if (pair.second) { 166 for (auto pair : mDeviceStatusMap) { 167 int32_t cameraId = pair.first; 168 int32_t status = pair.second; 169 170 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); 171 ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ? 172 callback->onCameraAvailable : callback->onCameraUnavailable; 173 msg->setPointer(kCallbackFpKey, (void *) cb); 174 msg->setPointer(kContextKey, callback->context); 175 msg->setInt32(kCameraIdKey, cameraId); 176 msg->post(); 177 } 178 } 179} 180 181void CameraManagerGlobal::unregisterAvailabilityCallback( 182 const ACameraManager_AvailabilityCallbacks *callback) { 183 Mutex::Autolock _l(mLock); 184 Callback cb(callback); 185 mCallbacks.erase(cb); 186} 187 188bool CameraManagerGlobal::validStatus(int32_t status) { 189 switch (status) { 190 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT: 191 case hardware::ICameraServiceListener::STATUS_PRESENT: 192 case hardware::ICameraServiceListener::STATUS_ENUMERATING: 193 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE: 194 return true; 195 default: 196 return false; 197 } 198} 199 200bool CameraManagerGlobal::isStatusAvailable(int32_t status) { 201 switch (status) { 202 case hardware::ICameraServiceListener::STATUS_PRESENT: 203 return true; 204 default: 205 return false; 206 } 207} 208 209void CameraManagerGlobal::CallbackHandler::sendSingleCallback( 210 int32_t cameraId, void* context, 211 ACameraManager_AvailabilityCallback cb) const { 212 char cameraIdStr[kMaxCameraIdLen]; 213 snprintf(cameraIdStr, sizeof(cameraIdStr), "%d", cameraId); 214 (*cb)(context, cameraIdStr); 215} 216 217void CameraManagerGlobal::CallbackHandler::onMessageReceived( 218 const sp<AMessage> &msg) { 219 switch (msg->what()) { 220 case kWhatSendSingleCallback: 221 { 222 ACameraManager_AvailabilityCallback cb; 223 void* context; 224 int32_t cameraId; 225 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb); 226 if (!found) { 227 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__); 228 return; 229 } 230 found = msg->findPointer(kContextKey, &context); 231 if (!found) { 232 ALOGE("%s: Cannot find callback context!", __FUNCTION__); 233 return; 234 } 235 found = msg->findInt32(kCameraIdKey, &cameraId); 236 if (!found) { 237 ALOGE("%s: Cannot find camera ID!", __FUNCTION__); 238 return; 239 } 240 sendSingleCallback(cameraId, context, cb); 241 break; 242 } 243 default: 244 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what()); 245 break; 246 } 247} 248 249binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( 250 int32_t status, int32_t cameraId) { 251 sp<CameraManagerGlobal> cm = mCameraManager.promote(); 252 if (cm != nullptr) { 253 cm->onStatusChanged(status, cameraId); 254 } else { 255 ALOGE("Cannot deliver status change. Global camera manager died"); 256 } 257 return binder::Status::ok(); 258} 259 260void CameraManagerGlobal::onStatusChanged( 261 int32_t status, int32_t cameraId) { 262 Mutex::Autolock _l(mLock); 263 onStatusChangedLocked(status, cameraId); 264} 265 266void CameraManagerGlobal::onStatusChangedLocked( 267 int32_t status, int32_t cameraId) { 268 if (!validStatus(status)) { 269 ALOGE("%s: Invalid status %d", __FUNCTION__, status); 270 return; 271 } 272 273 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0); 274 int32_t oldStatus = firstStatus ? 275 status : // first status 276 mDeviceStatusMap[cameraId]; 277 278 if (!firstStatus && 279 isStatusAvailable(status) == isStatusAvailable(oldStatus)) { 280 // No status update. No need to send callback 281 return; 282 } 283 284 // Iterate through all registered callbacks 285 mDeviceStatusMap[cameraId] = status; 286 for (auto cb : mCallbacks) { 287 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); 288 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? 289 cb.mAvailable : cb.mUnavailable; 290 msg->setPointer(kCallbackFpKey, (void *) cbFp); 291 msg->setPointer(kContextKey, cb.mContext); 292 msg->setInt32(kCameraIdKey, cameraId); 293 msg->post(); 294 } 295} 296 297} // namespace android 298 299/** 300 * ACameraManger Implementation 301 */ 302camera_status_t 303ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) { 304 if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) { 305 int numCameras = 0; 306 Vector<char *> cameraIds; 307 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 308 if (cs == nullptr) { 309 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 310 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 311 } 312 // Get number of cameras 313 int numAllCameras = 0; 314 binder::Status serviceRet = cs->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, 315 &numAllCameras); 316 if (!serviceRet.isOk()) { 317 ALOGE("%s: Error getting camera count: %s", __FUNCTION__, 318 serviceRet.toString8().string()); 319 numAllCameras = 0; 320 } 321 // Filter API2 compatible cameras and push to cameraIds 322 for (int i = 0; i < numAllCameras; i++) { 323 // TODO: Only suppot HALs that supports API2 directly now 324 bool camera2Support = false; 325 serviceRet = cs->supportsCameraApi(i, hardware::ICameraService::API_VERSION_2, 326 &camera2Support); 327 char buf[kMaxCameraIdLen]; 328 if (camera2Support) { 329 numCameras++; 330 mCameraIds.insert(i); 331 snprintf(buf, sizeof(buf), "%d", i); 332 size_t cameraIdSize = strlen(buf) + 1; 333 char *cameraId = new char[cameraIdSize]; 334 if (!cameraId) { 335 ALOGE("Allocate memory for ACameraIdList failed!"); 336 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 337 } 338 strlcpy(cameraId, buf, cameraIdSize); 339 cameraIds.push(cameraId); 340 } 341 } 342 mCachedCameraIdList.numCameras = numCameras; 343 mCachedCameraIdList.cameraIds = new const char*[numCameras]; 344 if (!mCachedCameraIdList.cameraIds) { 345 ALOGE("Allocate memory for ACameraIdList failed!"); 346 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 347 } 348 for (int i = 0; i < numCameras; i++) { 349 mCachedCameraIdList.cameraIds[i] = cameraIds[i]; 350 } 351 } 352 *cameraIdList = &mCachedCameraIdList; 353 return ACAMERA_OK; 354} 355 356camera_status_t 357ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) { 358 Mutex::Autolock _l(mLock); 359 ACameraIdList* cachedList; 360 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList); 361 if (ret != ACAMERA_OK) { 362 ALOGE("Get camera ID list failed! err: %d", ret); 363 return ret; 364 } 365 366 int numCameras = cachedList->numCameras; 367 ACameraIdList *out = new ACameraIdList; 368 if (!out) { 369 ALOGE("Allocate memory for ACameraIdList failed!"); 370 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 371 } 372 out->numCameras = numCameras; 373 out->cameraIds = new const char*[numCameras]; 374 if (!out->cameraIds) { 375 ALOGE("Allocate memory for ACameraIdList failed!"); 376 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 377 } 378 for (int i = 0; i < numCameras; i++) { 379 const char* src = cachedList->cameraIds[i]; 380 size_t dstSize = strlen(src) + 1; 381 char* dst = new char[dstSize]; 382 if (!dst) { 383 ALOGE("Allocate memory for ACameraIdList failed!"); 384 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 385 } 386 strlcpy(dst, src, dstSize); 387 out->cameraIds[i] = dst; 388 } 389 *cameraIdList = out; 390 return ACAMERA_OK; 391} 392 393void 394ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) { 395 if (cameraIdList != nullptr) { 396 if (cameraIdList->cameraIds != nullptr) { 397 for (int i = 0; i < cameraIdList->numCameras; i ++) { 398 delete[] cameraIdList->cameraIds[i]; 399 } 400 delete[] cameraIdList->cameraIds; 401 } 402 delete cameraIdList; 403 } 404} 405 406camera_status_t ACameraManager::getCameraCharacteristics( 407 const char *cameraIdStr, ACameraMetadata **characteristics) { 408 Mutex::Autolock _l(mLock); 409 ACameraIdList* cachedList; 410 // Make sure mCameraIds is initialized 411 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList); 412 if (ret != ACAMERA_OK) { 413 ALOGE("%s: Get camera ID list failed! err: %d", __FUNCTION__, ret); 414 return ret; 415 } 416 int cameraId = atoi(cameraIdStr); 417 if (mCameraIds.count(cameraId) == 0) { 418 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr); 419 return ACAMERA_ERROR_INVALID_PARAMETER; 420 } 421 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 422 if (cs == nullptr) { 423 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 424 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 425 } 426 CameraMetadata rawMetadata; 427 binder::Status serviceRet = cs->getCameraCharacteristics(cameraId, &rawMetadata); 428 if (!serviceRet.isOk()) { 429 ALOGE("Get camera characteristics from camera service failed: %s", 430 serviceRet.toString8().string()); 431 return ACAMERA_ERROR_UNKNOWN; // should not reach here 432 } 433 434 *characteristics = new ACameraMetadata( 435 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS); 436 return ACAMERA_OK; 437} 438 439camera_status_t 440ACameraManager::openCamera( 441 const char* cameraId, 442 ACameraDevice_StateCallbacks* callback, 443 /*out*/ACameraDevice** outDevice) { 444 ACameraMetadata* rawChars; 445 camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars); 446 Mutex::Autolock _l(mLock); 447 if (ret != ACAMERA_OK) { 448 ALOGE("%s: cannot get camera characteristics for camera %s. err %d", 449 __FUNCTION__, cameraId, ret); 450 return ACAMERA_ERROR_INVALID_PARAMETER; 451 } 452 std::unique_ptr<ACameraMetadata> chars(rawChars); 453 rawChars = nullptr; 454 455 ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars)); 456 457 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 458 if (cs == nullptr) { 459 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 460 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 461 } 462 463 int id = atoi(cameraId); 464 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback(); 465 sp<hardware::camera2::ICameraDeviceUser> deviceRemote; 466 // No way to get package name from native. 467 // Send a zero length package name and let camera service figure it out from UID 468 binder::Status serviceRet = cs->connectDevice( 469 callbacks, id, String16(""), 470 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote); 471 472 if (!serviceRet.isOk()) { 473 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string()); 474 delete device; 475 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 476 } 477 if (deviceRemote == nullptr) { 478 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__); 479 delete device; 480 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 481 } 482 device->setRemoteDevice(deviceRemote); 483 *outDevice = device; 484 return ACAMERA_OK; 485} 486 487ACameraManager::~ACameraManager() { 488 Mutex::Autolock _l(mLock); 489 if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) { 490 for (int i = 0; i < mCachedCameraIdList.numCameras; i++) { 491 delete[] mCachedCameraIdList.cameraIds[i]; 492 } 493 delete[] mCachedCameraIdList.cameraIds; 494 } 495} 496