Loading camera/ndk/Android.bp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,8 @@ cc_library_shared { "impl/ACameraCaptureSession.cpp", "impl/ACameraCaptureSession.cpp", ], ], shared_libs: [ shared_libs: [ "android.companion.virtual.virtualdevice_aidl-cpp", "android.companion.virtualdevice.flags-aconfig-cc", "libbinder", "libbinder", "liblog", "liblog", "libgui", "libgui", Loading camera/ndk/NdkCameraManager.cpp +8 −8 Original line number Original line Diff line number Diff line Loading @@ -68,7 +68,7 @@ void ACameraManager_deleteCameraIdList(ACameraIdList* cameraIdList) { EXPORT EXPORT camera_status_t ACameraManager_registerAvailabilityCallback( camera_status_t ACameraManager_registerAvailabilityCallback( ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -81,13 +81,13 @@ camera_status_t ACameraManager_registerAvailabilityCallback( callback->onCameraAvailable, callback->onCameraUnavailable); callback->onCameraAvailable, callback->onCameraUnavailable); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->registerAvailabilityCallback(callback); manager->registerAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_unregisterAvailabilityCallback( camera_status_t ACameraManager_unregisterAvailabilityCallback( ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -100,13 +100,13 @@ camera_status_t ACameraManager_unregisterAvailabilityCallback( callback->onCameraAvailable, callback->onCameraUnavailable); callback->onCameraAvailable, callback->onCameraUnavailable); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->unregisterAvailabilityCallback(callback); manager->unregisterAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_registerExtendedAvailabilityCallback( camera_status_t ACameraManager_registerExtendedAvailabilityCallback( ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -131,13 +131,13 @@ camera_status_t ACameraManager_registerExtendedAvailabilityCallback( return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } } } CameraManagerGlobal::getInstance()->registerExtendedAvailabilityCallback(callback); manager->registerExtendedAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -154,7 +154,7 @@ camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( callback->onCameraAccessPrioritiesChanged); callback->onCameraAccessPrioritiesChanged); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->unregisterExtendedAvailabilityCallback(callback); manager->unregisterExtendedAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } Loading camera/ndk/impl/ACameraManager.cpp +198 −90 Original line number Original line Diff line number Diff line Loading @@ -17,23 +17,108 @@ //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #define LOG_TAG "ACameraManager" #define LOG_TAG "ACameraManager" #include <memory> #include "ACameraManager.h" #include "ACameraManager.h" #include "ACameraMetadata.h" #include <android_companion_virtualdevice_flags.h> #include "ACameraDevice.h" #include <utils/Vector.h> #include <cutils/properties.h> #include <stdlib.h> #include <camera/CameraUtils.h> #include <camera/CameraUtils.h> #include <camera/StringUtils.h> #include <camera/StringUtils.h> #include <camera/VendorTagDescriptor.h> #include <camera/VendorTagDescriptor.h> #include <cutils/properties.h> #include <stdlib.h> #include <utils/Vector.h> #include <memory> #include "ACameraDevice.h" #include "ACameraMetadata.h" using namespace android::acam; using namespace android::acam; namespace vd_flags = android::companion::virtualdevice::flags; namespace android { namespace android { namespace acam { namespace acam { namespace { using ::android::binder::Status; using ::android::companion::virtualnative::IVirtualDeviceManagerNative; // Return binder connection to VirtualDeviceManager. // // Subsequent calls return the same cached instance. sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() { auto connectToVirtualDeviceManagerNative = []() { sp<IBinder> binder = defaultServiceManager()->checkService(String16("virtualdevice_native")); if (binder == nullptr) { ALOGW("%s: Cannot get virtualdevice_native service", __func__); return interface_cast<IVirtualDeviceManagerNative>(nullptr); } return interface_cast<IVirtualDeviceManagerNative>(binder); }; static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative(); return vdm; } // Returns device id calling process is running on. // If the process cannot be attributed to single virtual device id, returns default device id. int getCurrentDeviceId() { if (!vd_flags::camera_device_awareness()) { return kDefaultDeviceId; } auto vdm = getVirtualDeviceManager(); if (vdm == nullptr) { return kDefaultDeviceId; } const uid_t myUid = getuid(); std::vector<int> deviceIds; Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds); if (!status.isOk() || deviceIds.empty()) { ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s", __func__, myUid, status.toString8().c_str()); return kDefaultDeviceId; } // If the UID is associated with multiple virtual devices, use the default device's // camera as we cannot disambiguate here. This effectively means that the app has // activities on different devices at the same time. if (deviceIds.size() != 1) { return kDefaultDeviceId; } return deviceIds[0]; } // Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId. DevicePolicy getDevicePolicyForDeviceId(const int deviceId) { if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) { return DevicePolicy::DEVICE_POLICY_DEFAULT; } auto vdm = getVirtualDeviceManager(); if (vdm == nullptr) { return DevicePolicy::DEVICE_POLICY_DEFAULT; } int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT; Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA, &policy); if (!status.isOk()) { ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s", __func__, deviceId, status.toString8().c_str()); return DevicePolicy::DEVICE_POLICY_DEFAULT; } return static_cast<DevicePolicy>(policy); } // Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext. bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) { if (!vd_flags::camera_device_awareness() || deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) { return cameraDeviceId == kDefaultDeviceId; } return deviceContext.deviceId == cameraDeviceId; } // TODO(b/291736219): Add device-awareness to ACameraManager. } // namespace // Static member definitions // Static member definitions const char* CameraManagerGlobal::kCameraIdKey = "CameraId"; const char* CameraManagerGlobal::kCameraIdKey = "CameraId"; Loading @@ -44,6 +129,11 @@ const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms Mutex CameraManagerGlobal::sLock; Mutex CameraManagerGlobal::sLock; wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr; wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr; DeviceContext::DeviceContext() { deviceId = getCurrentDeviceId(); policy = getDevicePolicyForDeviceId(deviceId); } sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() { sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() { Mutex::Autolock _l(sLock); Mutex::Autolock _l(sLock); sp<CameraManagerGlobal> instance = sInstance.promote(); sp<CameraManagerGlobal> instance = sInstance.promote(); Loading Loading @@ -128,17 +218,11 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() { std::vector<hardware::CameraStatus> cameraStatuses{}; std::vector<hardware::CameraStatus> cameraStatuses{}; mCameraService->addListener(mCameraServiceListener, &cameraStatuses); mCameraService->addListener(mCameraServiceListener, &cameraStatuses); for (auto& c : cameraStatuses) { for (auto& c : cameraStatuses) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support onStatusChangedLocked(c.status, c.deviceId, c.cameraId); // device awareness yet. if (c.deviceId != kDefaultDeviceId) { continue; } onStatusChangedLocked(c.status, c.cameraId); for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) { for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) { onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT, onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT, c.cameraId, unavailablePhysicalId); c.deviceId, c.cameraId, unavailablePhysicalId); } } } } Loading Loading @@ -198,14 +282,15 @@ void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { AutoMutex lock(cm->mLock); AutoMutex lock(cm->mLock); std::vector<std::string> cameraIdList; std::vector<DeviceStatusMapKey> keysToRemove; keysToRemove.reserve(cm->mDeviceStatusMap.size()); for (auto& pair : cm->mDeviceStatusMap) { for (auto& pair : cm->mDeviceStatusMap) { cameraIdList.push_back(pair.first); keysToRemove.push_back(pair.first); } } for (const std::string& cameraId : cameraIdList) { for (const DeviceStatusMapKey& key : keysToRemove) { cm->onStatusChangedLocked( cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId, CameraServiceListener::STATUS_NOT_PRESENT, cameraId); key.cameraId); } } cm->mCameraService.clear(); cm->mCameraService.clear(); // TODO: consider adding re-connect call here? // TODO: consider adding re-connect call here? Loading @@ -213,32 +298,35 @@ void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) } } void CameraManagerGlobal::registerExtendedAvailabilityCallback( void CameraManagerGlobal::registerExtendedAvailabilityCallback( const DeviceContext& deviceContext, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { const ACameraManager_ExtendedAvailabilityCallbacks* callback) { return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback); return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext, callback); } } void CameraManagerGlobal::unregisterExtendedAvailabilityCallback( void CameraManagerGlobal::unregisterExtendedAvailabilityCallback( const DeviceContext& deviceContext, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { const ACameraManager_ExtendedAvailabilityCallbacks* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); drainPendingCallbacksLocked(); drainPendingCallbacksLocked(); Callback cb(callback); Callback cb(deviceContext, callback); mCallbacks.erase(cb); mCallbacks.erase(cb); } } void CameraManagerGlobal::registerAvailabilityCallback( void CameraManagerGlobal::registerAvailabilityCallback( const ACameraManager_AvailabilityCallbacks *callback) { const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) { return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback); return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback); } } void CameraManagerGlobal::unregisterAvailabilityCallback( void CameraManagerGlobal::unregisterAvailabilityCallback( const ACameraManager_AvailabilityCallbacks *callback) { const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); drainPendingCallbacksLocked(); drainPendingCallbacksLocked(); Callback cb(callback); Callback cb(deviceContext, callback); mCallbacks.erase(cb); mCallbacks.erase(cb); } } Loading @@ -262,19 +350,23 @@ void CameraManagerGlobal::drainPendingCallbacksLocked() { } } template <class T> template <class T> void CameraManagerGlobal::registerAvailCallback(const T *callback) { void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext, const T* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); getCameraServiceLocked(); getCameraServiceLocked(); Callback cb(callback); Callback cb(deviceContext, callback); auto pair = mCallbacks.insert(cb); const auto& [_, newlyRegistered] = mCallbacks.insert(cb); // Send initial callbacks if callback is newly registered // Send initial callbacks if callback is newly registered if (pair.second) { if (newlyRegistered) { for (auto& pair : mDeviceStatusMap) { for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) { const std::string& cameraId = pair.first; if (!isCameraAccessible(deviceContext, key.deviceId)) { int32_t status = pair.second.getStatus(); continue; } const std::string& cameraId = key.cameraId; int32_t status = statusAndHAL3Support.getStatus(); // Don't send initial callbacks for camera ids which don't support // Don't send initial callbacks for camera ids which don't support // camera2 // camera2 if (!pair.second.supportsHAL3) { if (!statusAndHAL3Support.supportsHAL3) { continue; continue; } } Loading @@ -290,7 +382,7 @@ void CameraManagerGlobal::registerAvailCallback(const T *callback) { // Physical camera unavailable callback // Physical camera unavailable callback std::set<std::string> unavailablePhysicalCameras = std::set<std::string> unavailablePhysicalCameras = pair.second.getUnavailablePhysicalIds(); statusAndHAL3Support.getUnavailablePhysicalIds(); for (const auto& physicalCameraId : unavailablePhysicalCameras) { for (const auto& physicalCameraId : unavailablePhysicalCameras) { sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); ACameraManager_PhysicalCameraAvailabilityCallback cbFunc = ACameraManager_PhysicalCameraAvailabilityCallback cbFunc = Loading Loading @@ -320,21 +412,26 @@ bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) return camera2Support; return camera2Support; } } void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) { void CameraManagerGlobal::getCameraIdList(const DeviceContext& context, std::vector<std::string>* cameraIds) { // Ensure that we have initialized/refreshed the list of available devices // Ensure that we have initialized/refreshed the list of available devices Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); // Needed to make sure we're connected to cameraservice // Needed to make sure we're connected to cameraservice getCameraServiceLocked(); getCameraServiceLocked(); for(auto& deviceStatus : mDeviceStatusMap) { for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) { int32_t status = deviceStatus.second.getStatus(); if (!isCameraAccessible(context, key.deviceId)) { continue; } int32_t status = statusAndHAL3Support.getStatus(); if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || status == hardware::ICameraServiceListener::STATUS_ENUMERATING) { status == hardware::ICameraServiceListener::STATUS_ENUMERATING) { continue; continue; } } if (!deviceStatus.second.supportsHAL3) { if (!statusAndHAL3Support.supportsHAL3) { continue; continue; } } cameraIds->push_back(deviceStatus.first); cameraIds->push_back(key.cameraId); } } } } Loading Loading @@ -471,36 +568,24 @@ binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPriorit binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( int32_t status, const std::string& cameraId, int deviceId) { int32_t status, const std::string& cameraId, int deviceId) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support // device awareness yet. if (deviceId != kDefaultDeviceId) { return binder::Status::ok(); } sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { cm->onStatusChanged(status, cameraId); cm->onStatusChanged(status, deviceId, cameraId); } else { ALOGE("Cannot deliver status change. Global camera manager died"); } } ALOGE_IF(cm == nullptr, "Cannot deliver physical camera status change. Global camera manager died"); return binder::Status::ok(); return binder::Status::ok(); } } binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged( binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged( int32_t status, const std::string& cameraId, const std::string& physicalCameraId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId, int deviceId) { int deviceId) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support // device awareness yet. if (deviceId != kDefaultDeviceId) { return binder::Status::ok(); } sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { cm->onStatusChanged(status, cameraId, physicalCameraId); cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId); } else { ALOGE("Cannot deliver physical camera status change. Global camera manager died"); } } ALOGE_IF(cm == nullptr, "Cannot deliver physical camera status change. Global camera manager died"); return binder::Status::ok(); return binder::Status::ok(); } } Loading @@ -518,23 +603,24 @@ void CameraManagerGlobal::onCameraAccessPrioritiesChanged() { } } } } void CameraManagerGlobal::onStatusChanged( void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId, int32_t status, const std::string& cameraId) { const std::string& cameraId) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); onStatusChangedLocked(status, cameraId); onStatusChangedLocked(status, deviceId, cameraId); } } void CameraManagerGlobal::onStatusChangedLocked( void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId, int32_t status, const std::string& cameraId) { const std::string& cameraId) { if (!validStatus(status)) { if (!validStatus(status)) { ALOGE("%s: Invalid status %d", __FUNCTION__, status); ALOGE("%s: Invalid status %d", __FUNCTION__, status); return; return; } } bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0); DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId}; int32_t oldStatus = firstStatus ? status : // first status bool firstStatus = (mDeviceStatusMap.count(key) == 0); mDeviceStatusMap[cameraId].getStatus(); int32_t oldStatus = firstStatus ? status : // first status mDeviceStatusMap[key].getStatus(); if (!firstStatus && if (!firstStatus && isStatusAvailable(status) == isStatusAvailable(oldStatus)) { isStatusAvailable(status) == isStatusAvailable(oldStatus)) { Loading @@ -544,15 +630,17 @@ void CameraManagerGlobal::onStatusChangedLocked( bool supportsHAL3 = supportsCamera2ApiLocked(cameraId); bool supportsHAL3 = supportsCamera2ApiLocked(cameraId); if (firstStatus) { if (firstStatus) { mDeviceStatusMap.emplace(std::piecewise_construct, mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(cameraId), std::forward_as_tuple(status, supportsHAL3)); std::forward_as_tuple(status, supportsHAL3)); } else { } else { mDeviceStatusMap[cameraId].updateStatus(status); mDeviceStatusMap[key].updateStatus(status); } } // Iterate through all registered callbacks // Iterate through all registered callbacks if (supportsHAL3) { if (supportsHAL3) { for (auto cb : mCallbacks) { for (auto cb : mCallbacks) { if (!isCameraAccessible(cb.mDeviceContext, deviceId)) { continue; } sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? cb.mAvailable : cb.mUnavailable; cb.mAvailable : cb.mUnavailable; Loading @@ -564,30 +652,31 @@ void CameraManagerGlobal::onStatusChangedLocked( } } } } if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { mDeviceStatusMap.erase(cameraId); mDeviceStatusMap.erase(key); } } } } void CameraManagerGlobal::onStatusChanged( void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId) { const std::string& cameraId, const std::string& physicalCameraId) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); onStatusChangedLocked(status, cameraId, physicalCameraId); onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId); } } void CameraManagerGlobal::onStatusChangedLocked( void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId) { const std::string& cameraId, const std::string& physicalCameraId) { if (!validStatus(status)) { if (!validStatus(status)) { ALOGE("%s: Invalid status %d", __FUNCTION__, status); ALOGE("%s: Invalid status %d", __FUNCTION__, status); return; return; } } auto logicalStatus = mDeviceStatusMap.find(cameraId); DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId}; auto logicalStatus = mDeviceStatusMap.find(key); if (logicalStatus == mDeviceStatusMap.end()) { if (logicalStatus == mDeviceStatusMap.end()) { ALOGE("%s: Physical camera id %s status change on a non-present id %s", ALOGE("%s: Physical camera id %s status change on a non-present id %s", __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str()); __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str()); return; return; } } int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus(); int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus(); if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT && if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT && logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) { logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) { ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d", ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d", Loading @@ -599,14 +688,17 @@ void CameraManagerGlobal::onStatusChangedLocked( bool updated = false; bool updated = false; if (status == hardware::ICameraServiceListener::STATUS_PRESENT) { if (status == hardware::ICameraServiceListener::STATUS_PRESENT) { updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId); updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId); } else { } else { updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId); updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId); } } // Iterate through all registered callbacks // Iterate through all registered callbacks if (supportsHAL3 && updated) { if (supportsHAL3 && updated) { for (auto cb : mCallbacks) { for (auto cb : mCallbacks) { if (!isCameraAccessible(cb.mDeviceContext, deviceId)) { continue; } sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ? ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ? cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable; cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable; Loading Loading @@ -660,7 +752,7 @@ ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); std::vector<std::string> idList; std::vector<std::string> idList; CameraManagerGlobal::getInstance()->getCameraIdList(&idList); mGlobalManager->getCameraIdList(mDeviceContext, &idList); int numCameras = idList.size(); int numCameras = idList.size(); ACameraIdList *out = new ACameraIdList; ACameraIdList *out = new ACameraIdList; Loading Loading @@ -710,7 +802,7 @@ camera_status_t ACameraManager::getCameraCharacteristics( const char* cameraIdStr, sp<ACameraMetadata>* characteristics) { const char* cameraIdStr, sp<ACameraMetadata>* characteristics) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService(); sp<hardware::ICameraService> cs = mGlobalManager->getCameraService(); if (cs == nullptr) { if (cs == nullptr) { ALOGE("%s: Cannot reach camera service!", __FUNCTION__); ALOGE("%s: Cannot reach camera service!", __FUNCTION__); return ACAMERA_ERROR_CAMERA_DISCONNECTED; return ACAMERA_ERROR_CAMERA_DISCONNECTED; Loading @@ -720,7 +812,7 @@ camera_status_t ACameraManager::getCameraCharacteristics( int targetSdkVersion = android_get_application_target_sdk_version(); int targetSdkVersion = android_get_application_target_sdk_version(); binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr, binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, kDefaultDeviceId, /*devicePolicy*/0, mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy), &rawMetadata); &rawMetadata); if (!serviceRet.isOk()) { if (!serviceRet.isOk()) { switch(serviceRet.serviceSpecificErrorCode()) { switch(serviceRet.serviceSpecificErrorCode()) { Loading Loading @@ -758,7 +850,7 @@ ACameraManager::openCamera( ACameraDevice* device = new ACameraDevice(cameraId, callback, chars); ACameraDevice* device = new ACameraDevice(cameraId, callback, chars); sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService(); sp<hardware::ICameraService> cs = mGlobalManager->getCameraService(); if (cs == nullptr) { if (cs == nullptr) { ALOGE("%s: Cannot reach camera service!", __FUNCTION__); ALOGE("%s: Cannot reach camera service!", __FUNCTION__); delete device; delete device; Loading @@ -774,7 +866,7 @@ ACameraManager::openCamera( callbacks, cameraId, "", {}, callbacks, cameraId, "", {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, kDefaultDeviceId, /*devicePolicy*/0, mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy), /*out*/&deviceRemote); /*out*/&deviceRemote); if (!serviceRet.isOk()) { if (!serviceRet.isOk()) { Loading Loading @@ -822,6 +914,22 @@ ACameraManager::openCamera( return ACAMERA_OK; return ACAMERA_OK; } } ACameraManager::~ACameraManager() { void ACameraManager::registerAvailabilityCallback( const ACameraManager_AvailabilityCallbacks* callback) { mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::unregisterAvailabilityCallback( const ACameraManager_AvailabilityCallbacks* callback) { mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::registerExtendedAvailabilityCallback( const ACameraManager_ExtendedAvailabilityCallbacks* callback) { mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::unregisterExtendedAvailabilityCallback( const ACameraManager_ExtendedAvailabilityCallbacks* callback) { mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback); } } Loading
camera/ndk/Android.bp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,8 @@ cc_library_shared { "impl/ACameraCaptureSession.cpp", "impl/ACameraCaptureSession.cpp", ], ], shared_libs: [ shared_libs: [ "android.companion.virtual.virtualdevice_aidl-cpp", "android.companion.virtualdevice.flags-aconfig-cc", "libbinder", "libbinder", "liblog", "liblog", "libgui", "libgui", Loading
camera/ndk/NdkCameraManager.cpp +8 −8 Original line number Original line Diff line number Diff line Loading @@ -68,7 +68,7 @@ void ACameraManager_deleteCameraIdList(ACameraIdList* cameraIdList) { EXPORT EXPORT camera_status_t ACameraManager_registerAvailabilityCallback( camera_status_t ACameraManager_registerAvailabilityCallback( ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -81,13 +81,13 @@ camera_status_t ACameraManager_registerAvailabilityCallback( callback->onCameraAvailable, callback->onCameraUnavailable); callback->onCameraAvailable, callback->onCameraUnavailable); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->registerAvailabilityCallback(callback); manager->registerAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_unregisterAvailabilityCallback( camera_status_t ACameraManager_unregisterAvailabilityCallback( ACameraManager*, const ACameraManager_AvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_AvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -100,13 +100,13 @@ camera_status_t ACameraManager_unregisterAvailabilityCallback( callback->onCameraAvailable, callback->onCameraUnavailable); callback->onCameraAvailable, callback->onCameraUnavailable); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->unregisterAvailabilityCallback(callback); manager->unregisterAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_registerExtendedAvailabilityCallback( camera_status_t ACameraManager_registerExtendedAvailabilityCallback( ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -131,13 +131,13 @@ camera_status_t ACameraManager_registerExtendedAvailabilityCallback( return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } } } CameraManagerGlobal::getInstance()->registerExtendedAvailabilityCallback(callback); manager->registerExtendedAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } EXPORT EXPORT camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) { ACameraManager* manager, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { ATRACE_CALL(); ATRACE_CALL(); if (callback == nullptr) { if (callback == nullptr) { ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); ALOGE("%s: invalid argument! callback is null!", __FUNCTION__); Loading @@ -154,7 +154,7 @@ camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback( callback->onCameraAccessPrioritiesChanged); callback->onCameraAccessPrioritiesChanged); return ACAMERA_ERROR_INVALID_PARAMETER; return ACAMERA_ERROR_INVALID_PARAMETER; } } CameraManagerGlobal::getInstance()->unregisterExtendedAvailabilityCallback(callback); manager->unregisterExtendedAvailabilityCallback(callback); return ACAMERA_OK; return ACAMERA_OK; } } Loading
camera/ndk/impl/ACameraManager.cpp +198 −90 Original line number Original line Diff line number Diff line Loading @@ -17,23 +17,108 @@ //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #define LOG_TAG "ACameraManager" #define LOG_TAG "ACameraManager" #include <memory> #include "ACameraManager.h" #include "ACameraManager.h" #include "ACameraMetadata.h" #include <android_companion_virtualdevice_flags.h> #include "ACameraDevice.h" #include <utils/Vector.h> #include <cutils/properties.h> #include <stdlib.h> #include <camera/CameraUtils.h> #include <camera/CameraUtils.h> #include <camera/StringUtils.h> #include <camera/StringUtils.h> #include <camera/VendorTagDescriptor.h> #include <camera/VendorTagDescriptor.h> #include <cutils/properties.h> #include <stdlib.h> #include <utils/Vector.h> #include <memory> #include "ACameraDevice.h" #include "ACameraMetadata.h" using namespace android::acam; using namespace android::acam; namespace vd_flags = android::companion::virtualdevice::flags; namespace android { namespace android { namespace acam { namespace acam { namespace { using ::android::binder::Status; using ::android::companion::virtualnative::IVirtualDeviceManagerNative; // Return binder connection to VirtualDeviceManager. // // Subsequent calls return the same cached instance. sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() { auto connectToVirtualDeviceManagerNative = []() { sp<IBinder> binder = defaultServiceManager()->checkService(String16("virtualdevice_native")); if (binder == nullptr) { ALOGW("%s: Cannot get virtualdevice_native service", __func__); return interface_cast<IVirtualDeviceManagerNative>(nullptr); } return interface_cast<IVirtualDeviceManagerNative>(binder); }; static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative(); return vdm; } // Returns device id calling process is running on. // If the process cannot be attributed to single virtual device id, returns default device id. int getCurrentDeviceId() { if (!vd_flags::camera_device_awareness()) { return kDefaultDeviceId; } auto vdm = getVirtualDeviceManager(); if (vdm == nullptr) { return kDefaultDeviceId; } const uid_t myUid = getuid(); std::vector<int> deviceIds; Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds); if (!status.isOk() || deviceIds.empty()) { ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s", __func__, myUid, status.toString8().c_str()); return kDefaultDeviceId; } // If the UID is associated with multiple virtual devices, use the default device's // camera as we cannot disambiguate here. This effectively means that the app has // activities on different devices at the same time. if (deviceIds.size() != 1) { return kDefaultDeviceId; } return deviceIds[0]; } // Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId. DevicePolicy getDevicePolicyForDeviceId(const int deviceId) { if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) { return DevicePolicy::DEVICE_POLICY_DEFAULT; } auto vdm = getVirtualDeviceManager(); if (vdm == nullptr) { return DevicePolicy::DEVICE_POLICY_DEFAULT; } int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT; Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA, &policy); if (!status.isOk()) { ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s", __func__, deviceId, status.toString8().c_str()); return DevicePolicy::DEVICE_POLICY_DEFAULT; } return static_cast<DevicePolicy>(policy); } // Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext. bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) { if (!vd_flags::camera_device_awareness() || deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) { return cameraDeviceId == kDefaultDeviceId; } return deviceContext.deviceId == cameraDeviceId; } // TODO(b/291736219): Add device-awareness to ACameraManager. } // namespace // Static member definitions // Static member definitions const char* CameraManagerGlobal::kCameraIdKey = "CameraId"; const char* CameraManagerGlobal::kCameraIdKey = "CameraId"; Loading @@ -44,6 +129,11 @@ const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms Mutex CameraManagerGlobal::sLock; Mutex CameraManagerGlobal::sLock; wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr; wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr; DeviceContext::DeviceContext() { deviceId = getCurrentDeviceId(); policy = getDevicePolicyForDeviceId(deviceId); } sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() { sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() { Mutex::Autolock _l(sLock); Mutex::Autolock _l(sLock); sp<CameraManagerGlobal> instance = sInstance.promote(); sp<CameraManagerGlobal> instance = sInstance.promote(); Loading Loading @@ -128,17 +218,11 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() { std::vector<hardware::CameraStatus> cameraStatuses{}; std::vector<hardware::CameraStatus> cameraStatuses{}; mCameraService->addListener(mCameraServiceListener, &cameraStatuses); mCameraService->addListener(mCameraServiceListener, &cameraStatuses); for (auto& c : cameraStatuses) { for (auto& c : cameraStatuses) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support onStatusChangedLocked(c.status, c.deviceId, c.cameraId); // device awareness yet. if (c.deviceId != kDefaultDeviceId) { continue; } onStatusChangedLocked(c.status, c.cameraId); for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) { for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) { onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT, onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT, c.cameraId, unavailablePhysicalId); c.deviceId, c.cameraId, unavailablePhysicalId); } } } } Loading Loading @@ -198,14 +282,15 @@ void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { AutoMutex lock(cm->mLock); AutoMutex lock(cm->mLock); std::vector<std::string> cameraIdList; std::vector<DeviceStatusMapKey> keysToRemove; keysToRemove.reserve(cm->mDeviceStatusMap.size()); for (auto& pair : cm->mDeviceStatusMap) { for (auto& pair : cm->mDeviceStatusMap) { cameraIdList.push_back(pair.first); keysToRemove.push_back(pair.first); } } for (const std::string& cameraId : cameraIdList) { for (const DeviceStatusMapKey& key : keysToRemove) { cm->onStatusChangedLocked( cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId, CameraServiceListener::STATUS_NOT_PRESENT, cameraId); key.cameraId); } } cm->mCameraService.clear(); cm->mCameraService.clear(); // TODO: consider adding re-connect call here? // TODO: consider adding re-connect call here? Loading @@ -213,32 +298,35 @@ void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&) } } void CameraManagerGlobal::registerExtendedAvailabilityCallback( void CameraManagerGlobal::registerExtendedAvailabilityCallback( const DeviceContext& deviceContext, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { const ACameraManager_ExtendedAvailabilityCallbacks* callback) { return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback); return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext, callback); } } void CameraManagerGlobal::unregisterExtendedAvailabilityCallback( void CameraManagerGlobal::unregisterExtendedAvailabilityCallback( const DeviceContext& deviceContext, const ACameraManager_ExtendedAvailabilityCallbacks* callback) { const ACameraManager_ExtendedAvailabilityCallbacks* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); drainPendingCallbacksLocked(); drainPendingCallbacksLocked(); Callback cb(callback); Callback cb(deviceContext, callback); mCallbacks.erase(cb); mCallbacks.erase(cb); } } void CameraManagerGlobal::registerAvailabilityCallback( void CameraManagerGlobal::registerAvailabilityCallback( const ACameraManager_AvailabilityCallbacks *callback) { const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) { return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback); return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback); } } void CameraManagerGlobal::unregisterAvailabilityCallback( void CameraManagerGlobal::unregisterAvailabilityCallback( const ACameraManager_AvailabilityCallbacks *callback) { const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); drainPendingCallbacksLocked(); drainPendingCallbacksLocked(); Callback cb(callback); Callback cb(deviceContext, callback); mCallbacks.erase(cb); mCallbacks.erase(cb); } } Loading @@ -262,19 +350,23 @@ void CameraManagerGlobal::drainPendingCallbacksLocked() { } } template <class T> template <class T> void CameraManagerGlobal::registerAvailCallback(const T *callback) { void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext, const T* callback) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); getCameraServiceLocked(); getCameraServiceLocked(); Callback cb(callback); Callback cb(deviceContext, callback); auto pair = mCallbacks.insert(cb); const auto& [_, newlyRegistered] = mCallbacks.insert(cb); // Send initial callbacks if callback is newly registered // Send initial callbacks if callback is newly registered if (pair.second) { if (newlyRegistered) { for (auto& pair : mDeviceStatusMap) { for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) { const std::string& cameraId = pair.first; if (!isCameraAccessible(deviceContext, key.deviceId)) { int32_t status = pair.second.getStatus(); continue; } const std::string& cameraId = key.cameraId; int32_t status = statusAndHAL3Support.getStatus(); // Don't send initial callbacks for camera ids which don't support // Don't send initial callbacks for camera ids which don't support // camera2 // camera2 if (!pair.second.supportsHAL3) { if (!statusAndHAL3Support.supportsHAL3) { continue; continue; } } Loading @@ -290,7 +382,7 @@ void CameraManagerGlobal::registerAvailCallback(const T *callback) { // Physical camera unavailable callback // Physical camera unavailable callback std::set<std::string> unavailablePhysicalCameras = std::set<std::string> unavailablePhysicalCameras = pair.second.getUnavailablePhysicalIds(); statusAndHAL3Support.getUnavailablePhysicalIds(); for (const auto& physicalCameraId : unavailablePhysicalCameras) { for (const auto& physicalCameraId : unavailablePhysicalCameras) { sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); ACameraManager_PhysicalCameraAvailabilityCallback cbFunc = ACameraManager_PhysicalCameraAvailabilityCallback cbFunc = Loading Loading @@ -320,21 +412,26 @@ bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) return camera2Support; return camera2Support; } } void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) { void CameraManagerGlobal::getCameraIdList(const DeviceContext& context, std::vector<std::string>* cameraIds) { // Ensure that we have initialized/refreshed the list of available devices // Ensure that we have initialized/refreshed the list of available devices Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); // Needed to make sure we're connected to cameraservice // Needed to make sure we're connected to cameraservice getCameraServiceLocked(); getCameraServiceLocked(); for(auto& deviceStatus : mDeviceStatusMap) { for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) { int32_t status = deviceStatus.second.getStatus(); if (!isCameraAccessible(context, key.deviceId)) { continue; } int32_t status = statusAndHAL3Support.getStatus(); if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT || status == hardware::ICameraServiceListener::STATUS_ENUMERATING) { status == hardware::ICameraServiceListener::STATUS_ENUMERATING) { continue; continue; } } if (!deviceStatus.second.supportsHAL3) { if (!statusAndHAL3Support.supportsHAL3) { continue; continue; } } cameraIds->push_back(deviceStatus.first); cameraIds->push_back(key.cameraId); } } } } Loading Loading @@ -471,36 +568,24 @@ binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPriorit binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged( int32_t status, const std::string& cameraId, int deviceId) { int32_t status, const std::string& cameraId, int deviceId) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support // device awareness yet. if (deviceId != kDefaultDeviceId) { return binder::Status::ok(); } sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { cm->onStatusChanged(status, cameraId); cm->onStatusChanged(status, deviceId, cameraId); } else { ALOGE("Cannot deliver status change. Global camera manager died"); } } ALOGE_IF(cm == nullptr, "Cannot deliver physical camera status change. Global camera manager died"); return binder::Status::ok(); return binder::Status::ok(); } } binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged( binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged( int32_t status, const std::string& cameraId, const std::string& physicalCameraId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId, int deviceId) { int deviceId) { // Skip callback for cameras not belonging to the default device, as NDK doesn't support // device awareness yet. if (deviceId != kDefaultDeviceId) { return binder::Status::ok(); } sp<CameraManagerGlobal> cm = mCameraManager.promote(); sp<CameraManagerGlobal> cm = mCameraManager.promote(); if (cm != nullptr) { if (cm != nullptr) { cm->onStatusChanged(status, cameraId, physicalCameraId); cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId); } else { ALOGE("Cannot deliver physical camera status change. Global camera manager died"); } } ALOGE_IF(cm == nullptr, "Cannot deliver physical camera status change. Global camera manager died"); return binder::Status::ok(); return binder::Status::ok(); } } Loading @@ -518,23 +603,24 @@ void CameraManagerGlobal::onCameraAccessPrioritiesChanged() { } } } } void CameraManagerGlobal::onStatusChanged( void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId, int32_t status, const std::string& cameraId) { const std::string& cameraId) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); onStatusChangedLocked(status, cameraId); onStatusChangedLocked(status, deviceId, cameraId); } } void CameraManagerGlobal::onStatusChangedLocked( void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId, int32_t status, const std::string& cameraId) { const std::string& cameraId) { if (!validStatus(status)) { if (!validStatus(status)) { ALOGE("%s: Invalid status %d", __FUNCTION__, status); ALOGE("%s: Invalid status %d", __FUNCTION__, status); return; return; } } bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0); DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId}; int32_t oldStatus = firstStatus ? status : // first status bool firstStatus = (mDeviceStatusMap.count(key) == 0); mDeviceStatusMap[cameraId].getStatus(); int32_t oldStatus = firstStatus ? status : // first status mDeviceStatusMap[key].getStatus(); if (!firstStatus && if (!firstStatus && isStatusAvailable(status) == isStatusAvailable(oldStatus)) { isStatusAvailable(status) == isStatusAvailable(oldStatus)) { Loading @@ -544,15 +630,17 @@ void CameraManagerGlobal::onStatusChangedLocked( bool supportsHAL3 = supportsCamera2ApiLocked(cameraId); bool supportsHAL3 = supportsCamera2ApiLocked(cameraId); if (firstStatus) { if (firstStatus) { mDeviceStatusMap.emplace(std::piecewise_construct, mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(cameraId), std::forward_as_tuple(status, supportsHAL3)); std::forward_as_tuple(status, supportsHAL3)); } else { } else { mDeviceStatusMap[cameraId].updateStatus(status); mDeviceStatusMap[key].updateStatus(status); } } // Iterate through all registered callbacks // Iterate through all registered callbacks if (supportsHAL3) { if (supportsHAL3) { for (auto cb : mCallbacks) { for (auto cb : mCallbacks) { if (!isCameraAccessible(cb.mDeviceContext, deviceId)) { continue; } sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler); ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ? cb.mAvailable : cb.mUnavailable; cb.mAvailable : cb.mUnavailable; Loading @@ -564,30 +652,31 @@ void CameraManagerGlobal::onStatusChangedLocked( } } } } if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { mDeviceStatusMap.erase(cameraId); mDeviceStatusMap.erase(key); } } } } void CameraManagerGlobal::onStatusChanged( void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId) { const std::string& cameraId, const std::string& physicalCameraId) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); onStatusChangedLocked(status, cameraId, physicalCameraId); onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId); } } void CameraManagerGlobal::onStatusChangedLocked( void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId, int32_t status, const std::string& cameraId, const std::string& physicalCameraId) { const std::string& cameraId, const std::string& physicalCameraId) { if (!validStatus(status)) { if (!validStatus(status)) { ALOGE("%s: Invalid status %d", __FUNCTION__, status); ALOGE("%s: Invalid status %d", __FUNCTION__, status); return; return; } } auto logicalStatus = mDeviceStatusMap.find(cameraId); DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId}; auto logicalStatus = mDeviceStatusMap.find(key); if (logicalStatus == mDeviceStatusMap.end()) { if (logicalStatus == mDeviceStatusMap.end()) { ALOGE("%s: Physical camera id %s status change on a non-present id %s", ALOGE("%s: Physical camera id %s status change on a non-present id %s", __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str()); __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str()); return; return; } } int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus(); int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus(); if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT && if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT && logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) { logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) { ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d", ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d", Loading @@ -599,14 +688,17 @@ void CameraManagerGlobal::onStatusChangedLocked( bool updated = false; bool updated = false; if (status == hardware::ICameraServiceListener::STATUS_PRESENT) { if (status == hardware::ICameraServiceListener::STATUS_PRESENT) { updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId); updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId); } else { } else { updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId); updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId); } } // Iterate through all registered callbacks // Iterate through all registered callbacks if (supportsHAL3 && updated) { if (supportsHAL3 && updated) { for (auto cb : mCallbacks) { for (auto cb : mCallbacks) { if (!isCameraAccessible(cb.mDeviceContext, deviceId)) { continue; } sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler); ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ? ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ? cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable; cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable; Loading Loading @@ -660,7 +752,7 @@ ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); std::vector<std::string> idList; std::vector<std::string> idList; CameraManagerGlobal::getInstance()->getCameraIdList(&idList); mGlobalManager->getCameraIdList(mDeviceContext, &idList); int numCameras = idList.size(); int numCameras = idList.size(); ACameraIdList *out = new ACameraIdList; ACameraIdList *out = new ACameraIdList; Loading Loading @@ -710,7 +802,7 @@ camera_status_t ACameraManager::getCameraCharacteristics( const char* cameraIdStr, sp<ACameraMetadata>* characteristics) { const char* cameraIdStr, sp<ACameraMetadata>* characteristics) { Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService(); sp<hardware::ICameraService> cs = mGlobalManager->getCameraService(); if (cs == nullptr) { if (cs == nullptr) { ALOGE("%s: Cannot reach camera service!", __FUNCTION__); ALOGE("%s: Cannot reach camera service!", __FUNCTION__); return ACAMERA_ERROR_CAMERA_DISCONNECTED; return ACAMERA_ERROR_CAMERA_DISCONNECTED; Loading @@ -720,7 +812,7 @@ camera_status_t ACameraManager::getCameraCharacteristics( int targetSdkVersion = android_get_application_target_sdk_version(); int targetSdkVersion = android_get_application_target_sdk_version(); binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr, binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, kDefaultDeviceId, /*devicePolicy*/0, mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy), &rawMetadata); &rawMetadata); if (!serviceRet.isOk()) { if (!serviceRet.isOk()) { switch(serviceRet.serviceSpecificErrorCode()) { switch(serviceRet.serviceSpecificErrorCode()) { Loading Loading @@ -758,7 +850,7 @@ ACameraManager::openCamera( ACameraDevice* device = new ACameraDevice(cameraId, callback, chars); ACameraDevice* device = new ACameraDevice(cameraId, callback, chars); sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService(); sp<hardware::ICameraService> cs = mGlobalManager->getCameraService(); if (cs == nullptr) { if (cs == nullptr) { ALOGE("%s: Cannot reach camera service!", __FUNCTION__); ALOGE("%s: Cannot reach camera service!", __FUNCTION__); delete device; delete device; Loading @@ -774,7 +866,7 @@ ACameraManager::openCamera( callbacks, cameraId, "", {}, callbacks, cameraId, "", {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, kDefaultDeviceId, /*devicePolicy*/0, mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy), /*out*/&deviceRemote); /*out*/&deviceRemote); if (!serviceRet.isOk()) { if (!serviceRet.isOk()) { Loading Loading @@ -822,6 +914,22 @@ ACameraManager::openCamera( return ACAMERA_OK; return ACAMERA_OK; } } ACameraManager::~ACameraManager() { void ACameraManager::registerAvailabilityCallback( const ACameraManager_AvailabilityCallbacks* callback) { mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::unregisterAvailabilityCallback( const ACameraManager_AvailabilityCallbacks* callback) { mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::registerExtendedAvailabilityCallback( const ACameraManager_ExtendedAvailabilityCallbacks* callback) { mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback); } void ACameraManager::unregisterExtendedAvailabilityCallback( const ACameraManager_ExtendedAvailabilityCallbacks* callback) { mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback); } }