diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp index 8eb030a03d..7a0f63bc13 100644 --- a/camera/ndk/impl/ACameraManager.cpp +++ b/camera/ndk/impl/ACameraManager.cpp @@ -76,6 +76,10 @@ static bool isCameraServiceDisabled() { sp CameraManagerGlobal::getCameraService() { Mutex::Autolock _l(mLock); + return getCameraServiceLocked(); +} + +sp CameraManagerGlobal::getCameraServiceLocked() { if (mCameraService.get() == nullptr) { if (isCameraServiceDisabled()) { return mCameraService; @@ -216,8 +220,12 @@ void CameraManagerGlobal::registerAvailabilityCallback( if (pair.second) { for (auto& pair : mDeviceStatusMap) { const String8& cameraId = pair.first; - int32_t status = pair.second; - + int32_t status = pair.second.status; + // Don't send initial callbacks for camera ids which don't support + // camera2 + if (!pair.second.supportsHAL3) { + continue; + } sp msg = new AMessage(kWhatSendSingleCallback, mHandler); ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ? callback->onCameraAvailable : callback->onCameraUnavailable; @@ -236,20 +244,32 @@ void CameraManagerGlobal::unregisterAvailabilityCallback( mCallbacks.erase(cb); } +bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) { + bool camera2Support = false; + auto cs = getCameraServiceLocked(); + binder::Status serviceRet = + cs->supportsCameraApi(String16(cameraId), + hardware::ICameraService::API_VERSION_2, &camera2Support); + if (!serviceRet.isOk()) { + ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s", + __FUNCTION__, cameraId.c_str()); + return false; + } + return camera2Support; +} + void CameraManagerGlobal::getCameraIdList(std::vector* cameraIds) { // Ensure that we have initialized/refreshed the list of available devices - auto cs = getCameraService(); Mutex::Autolock _l(mLock); - + // Needed to make sure we're connected to cameraservice + getCameraServiceLocked(); for(auto& deviceStatus : mDeviceStatusMap) { - if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || - deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) { + if (deviceStatus.second.status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || + deviceStatus.second.status == + hardware::ICameraServiceListener::STATUS_ENUMERATING) { continue; } - bool camera2Support = false; - binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first), - hardware::ICameraService::API_VERSION_2, &camera2Support); - if (!serviceRet.isOk() || !camera2Support) { + if (!deviceStatus.second.supportsHAL3) { continue; } cameraIds->push_back(deviceStatus.first); @@ -377,7 +397,7 @@ void CameraManagerGlobal::onStatusChangedLocked( bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0); int32_t oldStatus = firstStatus ? status : // first status - mDeviceStatusMap[cameraId]; + mDeviceStatusMap[cameraId].status; if (!firstStatus && isStatusAvailable(status) == isStatusAvailable(oldStatus)) { @@ -385,16 +405,19 @@ void CameraManagerGlobal::onStatusChangedLocked( return; } + bool supportsHAL3 = supportsCamera2ApiLocked(cameraId); // Iterate through all registered callbacks - mDeviceStatusMap[cameraId] = status; - for (auto cb : mCallbacks) { - sp msg = new AMessage(kWhatSendSingleCallback, mHandler); - ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? - cb.mAvailable : cb.mUnavailable; - msg->setPointer(kCallbackFpKey, (void *) cbFp); - msg->setPointer(kContextKey, cb.mContext); - msg->setString(kCameraIdKey, AString(cameraId)); - msg->post(); + mDeviceStatusMap[cameraId] = StatusAndHAL3Support(status, supportsHAL3); + if (supportsHAL3) { + for (auto cb : mCallbacks) { + sp msg = new AMessage(kWhatSendSingleCallback, mHandler); + ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? + cb.mAvailable : cb.mUnavailable; + msg->setPointer(kCallbackFpKey, (void *) cbFp); + msg->setPointer(kContextKey, cb.mContext); + msg->setString(kCameraIdKey, AString(cameraId)); + msg->post(); + } } if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { mDeviceStatusMap.erase(cameraId); diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h index 8c1da36418..e945ba0cbd 100644 --- a/camera/ndk/impl/ACameraManager.h +++ b/camera/ndk/impl/ACameraManager.h @@ -66,9 +66,9 @@ class CameraManagerGlobal final : public RefBase { private: sp mCameraService; - const int kCameraServicePollDelay = 500000; // 0.5s - const char* kCameraServiceName = "media.camera"; - Mutex mLock; + const int kCameraServicePollDelay = 500000; // 0.5s + const char* kCameraServiceName = "media.camera"; + Mutex mLock; class DeathNotifier : public IBinder::DeathRecipient { public: @@ -156,12 +156,14 @@ class CameraManagerGlobal final : public RefBase { sp mHandler; sp mCbLooper; // Looper thread where callbacks actually happen on + sp getCameraServiceLocked(); void onCameraAccessPrioritiesChanged(); void onStatusChanged(int32_t status, const String8& cameraId); void onStatusChangedLocked(int32_t status, const String8& cameraId); // Utils for status static bool validStatus(int32_t status); static bool isStatusAvailable(int32_t status); + bool supportsCamera2ApiLocked(const String8 &cameraId); // The sort logic must match the logic in // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds @@ -184,8 +186,16 @@ class CameraManagerGlobal final : public RefBase { } }; + struct StatusAndHAL3Support { + int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT; + bool supportsHAL3 = false; + StatusAndHAL3Support(int32_t st, bool HAL3support): + status(st), supportsHAL3(HAL3support) { }; + StatusAndHAL3Support() = default; + }; + // Map camera_id -> status - std::map mDeviceStatusMap; + std::map mDeviceStatusMap; // For the singleton instance static Mutex sLock;