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