ACameraManager.cpp revision d56db1d2bee182d1851097a9c712712fc094d117
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 ret = mCbLooper->start( 98 /*runOnCallingThread*/false, 99 /*canCallJava*/ true, 100 PRIORITY_DEFAULT); 101 if (mHandler == nullptr) { 102 mHandler = new CallbackHandler(); 103 } 104 mCbLooper->registerHandler(mHandler); 105 } 106 107 // register ICameraServiceListener 108 if (mCameraServiceListener == nullptr) { 109 mCameraServiceListener = new CameraServiceListener(this); 110 } 111 mCameraService->addListener(mCameraServiceListener); 112 113 // setup vendor tags 114 sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); 115 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get()); 116 117 if (ret.isOk()) { 118 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc); 119 if (err != OK) { 120 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)", 121 __FUNCTION__, strerror(-err), err); 122 } 123 } else if (ret.serviceSpecificErrorCode() == 124 hardware::ICameraService::ERROR_DEPRECATED_HAL) { 125 ALOGW("%s: Camera HAL too old; does not support vendor tags", 126 __FUNCTION__); 127 VendorTagDescriptor::clearGlobalVendorTagDescriptor(); 128 } else { 129 ALOGE("%s: Failed to get vendor tag descriptors: %s", 130 __FUNCTION__, ret.toString8().string()); 131 } 132 } 133 ALOGE_IF(mCameraService == nullptr, "no CameraService!?"); 134 return mCameraService; 135} 136 137void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) 138{ 139 ALOGE("Camera service binderDied!"); 140 sp<CameraManagerGlobal> cm = mCameraManager.promote(); 141 if (cm != nullptr) { 142 AutoMutex lock(cm->mLock); 143 for (auto pair : cm->mDeviceStatusMap) { 144 int32_t cameraId = pair.first; 145 cm->onStatusChangedLocked( 146 CameraServiceListener::STATUS_NOT_PRESENT, cameraId); 147 } 148 cm->mCameraService.clear(); 149 // TODO: consider adding re-connect call here? 150 } 151} 152 153void CameraManagerGlobal::registerAvailabilityCallback( 154 const ACameraManager_AvailabilityCallbacks *callback) { 155 Mutex::Autolock _l(mLock); 156 Callback cb(callback); 157 auto pair = mCallbacks.insert(cb); 158 // Send initial callbacks if callback is newly registered 159 if (pair.second) { 160 for (auto pair : mDeviceStatusMap) { 161 int32_t cameraId = pair.first; 162 int32_t status = pair.second; 163 164 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); 165 ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ? 166 callback->onCameraAvailable : callback->onCameraUnavailable; 167 msg->setPointer(kCallbackFpKey, (void *) cb); 168 msg->setPointer(kContextKey, callback->context); 169 msg->setInt32(kCameraIdKey, cameraId); 170 msg->post(); 171 } 172 } 173} 174 175void CameraManagerGlobal::unregisterAvailabilityCallback( 176 const ACameraManager_AvailabilityCallbacks *callback) { 177 Mutex::Autolock _l(mLock); 178 Callback cb(callback); 179 mCallbacks.erase(cb); 180} 181 182bool CameraManagerGlobal::validStatus(int32_t status) { 183 switch (status) { 184 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT: 185 case hardware::ICameraServiceListener::STATUS_PRESENT: 186 case hardware::ICameraServiceListener::STATUS_ENUMERATING: 187 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE: 188 return true; 189 default: 190 return false; 191 } 192} 193 194bool CameraManagerGlobal::isStatusAvailable(int32_t status) { 195 switch (status) { 196 case hardware::ICameraServiceListener::STATUS_PRESENT: 197 return true; 198 default: 199 return false; 200 } 201} 202 203void CameraManagerGlobal::CallbackHandler::sendSingleCallback( 204 int32_t cameraId, void* context, 205 ACameraManager_AvailabilityCallback cb) const { 206 char cameraIdStr[kMaxCameraIdLen]; 207 snprintf(cameraIdStr, sizeof(cameraIdStr), "%d", cameraId); 208 (*cb)(context, cameraIdStr); 209} 210 211void CameraManagerGlobal::CallbackHandler::onMessageReceived( 212 const sp<AMessage> &msg) { 213 switch (msg->what()) { 214 case kWhatSendSingleCallback: 215 { 216 ACameraManager_AvailabilityCallback cb; 217 void* context; 218 int32_t cameraId; 219 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb); 220 if (!found) { 221 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__); 222 return; 223 } 224 found = msg->findPointer(kContextKey, &context); 225 if (!found) { 226 ALOGE("%s: Cannot find callback context!", __FUNCTION__); 227 return; 228 } 229 found = msg->findInt32(kCameraIdKey, &cameraId); 230 if (!found) { 231 ALOGE("%s: Cannot find camera ID!", __FUNCTION__); 232 return; 233 } 234 sendSingleCallback(cameraId, context, cb); 235 break; 236 } 237 default: 238 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what()); 239 break; 240 } 241} 242 243binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( 244 int32_t status, int32_t cameraId) { 245 sp<CameraManagerGlobal> cm = mCameraManager.promote(); 246 if (cm != nullptr) { 247 cm->onStatusChanged(status, cameraId); 248 } else { 249 ALOGE("Cannot deliver status change. Global camera manager died"); 250 } 251 return binder::Status::ok(); 252} 253 254void CameraManagerGlobal::onStatusChanged( 255 int32_t status, int32_t cameraId) { 256 Mutex::Autolock _l(mLock); 257 onStatusChangedLocked(status, cameraId); 258} 259 260void CameraManagerGlobal::onStatusChangedLocked( 261 int32_t status, int32_t cameraId) { 262 if (!validStatus(status)) { 263 ALOGE("%s: Invalid status %d", __FUNCTION__, status); 264 return; 265 } 266 267 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0); 268 int32_t oldStatus = firstStatus ? 269 status : // first status 270 mDeviceStatusMap[cameraId]; 271 272 if (!firstStatus && 273 isStatusAvailable(status) == isStatusAvailable(oldStatus)) { 274 // No status update. No need to send callback 275 return; 276 } 277 278 // Iterate through all registered callbacks 279 mDeviceStatusMap[cameraId] = status; 280 for (auto cb : mCallbacks) { 281 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); 282 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? 283 cb.mAvailable : cb.mUnavailable; 284 msg->setPointer(kCallbackFpKey, (void *) cbFp); 285 msg->setPointer(kContextKey, cb.mContext); 286 msg->setInt32(kCameraIdKey, cameraId); 287 msg->post(); 288 } 289} 290 291} // namespace android 292 293/** 294 * ACameraManger Implementation 295 */ 296camera_status_t 297ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) { 298 if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) { 299 int numCameras = 0; 300 Vector<char *> cameraIds; 301 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 302 if (cs == nullptr) { 303 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 304 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 305 } 306 // Get number of cameras 307 int numAllCameras = 0; 308 binder::Status serviceRet = cs->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, 309 &numAllCameras); 310 if (!serviceRet.isOk()) { 311 ALOGE("%s: Error getting camera count: %s", __FUNCTION__, 312 serviceRet.toString8().string()); 313 numAllCameras = 0; 314 } 315 // Filter API2 compatible cameras and push to cameraIds 316 for (int i = 0; i < numAllCameras; i++) { 317 // TODO: Only suppot HALs that supports API2 directly now 318 bool camera2Support = false; 319 serviceRet = cs->supportsCameraApi(i, hardware::ICameraService::API_VERSION_2, 320 &camera2Support); 321 char buf[kMaxCameraIdLen]; 322 if (camera2Support) { 323 numCameras++; 324 mCameraIds.insert(i); 325 snprintf(buf, sizeof(buf), "%d", i); 326 size_t cameraIdSize = strlen(buf) + 1; 327 char *cameraId = new char[cameraIdSize]; 328 if (!cameraId) { 329 ALOGE("Allocate memory for ACameraIdList failed!"); 330 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 331 } 332 strlcpy(cameraId, buf, cameraIdSize); 333 cameraIds.push(cameraId); 334 } 335 } 336 mCachedCameraIdList.numCameras = numCameras; 337 mCachedCameraIdList.cameraIds = new const char*[numCameras]; 338 if (!mCachedCameraIdList.cameraIds) { 339 ALOGE("Allocate memory for ACameraIdList failed!"); 340 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 341 } 342 for (int i = 0; i < numCameras; i++) { 343 mCachedCameraIdList.cameraIds[i] = cameraIds[i]; 344 } 345 } 346 *cameraIdList = &mCachedCameraIdList; 347 return ACAMERA_OK; 348} 349 350camera_status_t 351ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) { 352 Mutex::Autolock _l(mLock); 353 ACameraIdList* cachedList; 354 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList); 355 if (ret != ACAMERA_OK) { 356 ALOGE("Get camera ID list failed! err: %d", ret); 357 return ret; 358 } 359 360 int numCameras = cachedList->numCameras; 361 ACameraIdList *out = new ACameraIdList; 362 if (!out) { 363 ALOGE("Allocate memory for ACameraIdList failed!"); 364 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 365 } 366 out->numCameras = numCameras; 367 out->cameraIds = new const char*[numCameras]; 368 if (!out->cameraIds) { 369 ALOGE("Allocate memory for ACameraIdList failed!"); 370 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 371 } 372 for (int i = 0; i < numCameras; i++) { 373 const char* src = cachedList->cameraIds[i]; 374 size_t dstSize = strlen(src) + 1; 375 char* dst = new char[dstSize]; 376 if (!dst) { 377 ALOGE("Allocate memory for ACameraIdList failed!"); 378 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY; 379 } 380 strlcpy(dst, src, dstSize); 381 out->cameraIds[i] = dst; 382 } 383 *cameraIdList = out; 384 return ACAMERA_OK; 385} 386 387void 388ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) { 389 if (cameraIdList != nullptr) { 390 if (cameraIdList->cameraIds != nullptr) { 391 for (int i = 0; i < cameraIdList->numCameras; i ++) { 392 delete[] cameraIdList->cameraIds[i]; 393 } 394 delete[] cameraIdList->cameraIds; 395 } 396 delete cameraIdList; 397 } 398} 399 400camera_status_t ACameraManager::getCameraCharacteristics( 401 const char *cameraIdStr, ACameraMetadata **characteristics) { 402 Mutex::Autolock _l(mLock); 403 ACameraIdList* cachedList; 404 // Make sure mCameraIds is initialized 405 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList); 406 if (ret != ACAMERA_OK) { 407 ALOGE("%s: Get camera ID list failed! err: %d", __FUNCTION__, ret); 408 return ret; 409 } 410 int cameraId = atoi(cameraIdStr); 411 if (mCameraIds.count(cameraId) == 0) { 412 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr); 413 return ACAMERA_ERROR_INVALID_PARAMETER; 414 } 415 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 416 if (cs == nullptr) { 417 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 418 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 419 } 420 CameraMetadata rawMetadata; 421 binder::Status serviceRet = cs->getCameraCharacteristics(cameraId, &rawMetadata); 422 if (!serviceRet.isOk()) { 423 ALOGE("Get camera characteristics from camera service failed: %s", 424 serviceRet.toString8().string()); 425 return ACAMERA_ERROR_UNKNOWN; // should not reach here 426 } 427 428 *characteristics = new ACameraMetadata( 429 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS); 430 return ACAMERA_OK; 431} 432 433camera_status_t 434ACameraManager::openCamera( 435 const char* cameraId, 436 ACameraDevice_StateCallbacks* callback, 437 /*out*/ACameraDevice** outDevice) { 438 ACameraMetadata* rawChars; 439 camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars); 440 Mutex::Autolock _l(mLock); 441 if (ret != ACAMERA_OK) { 442 ALOGE("%s: cannot get camera characteristics for camera %s. err %d", 443 __FUNCTION__, cameraId, ret); 444 return ACAMERA_ERROR_INVALID_PARAMETER; 445 } 446 std::unique_ptr<ACameraMetadata> chars(rawChars); 447 rawChars = nullptr; 448 449 ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars)); 450 451 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService(); 452 if (cs == nullptr) { 453 ALOGE("%s: Cannot reach camera service!", __FUNCTION__); 454 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 455 } 456 457 int id = atoi(cameraId); 458 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback(); 459 sp<hardware::camera2::ICameraDeviceUser> deviceRemote; 460 // No way to get package name from native. 461 // Send a zero length package name and let camera service figure it out from UID 462 binder::Status serviceRet = cs->connectDevice( 463 callbacks, id, String16(""), 464 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote); 465 466 if (!serviceRet.isOk()) { 467 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string()); 468 delete device; 469 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 470 } 471 if (deviceRemote == nullptr) { 472 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__); 473 delete device; 474 return ACAMERA_ERROR_CAMERA_DISCONNECTED; 475 } 476 device->setRemoteDevice(deviceRemote); 477 *outDevice = device; 478 return ACAMERA_OK; 479} 480 481ACameraManager::~ACameraManager() { 482 Mutex::Autolock _l(mLock); 483 if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) { 484 for (int i = 0; i < mCachedCameraIdList.numCameras; i++) { 485 delete[] mCachedCameraIdList.cameraIds[i]; 486 } 487 delete[] mCachedCameraIdList.cameraIds; 488 } 489} 490