Camera: Support new provider callback version in camera service
The new provider callback version enables availability callback for
physical camera.
Test: Camera CTS
Bug: 119325027
Change-Id: I22e0b669c3d9891a431e1befc7f1c9f40b826a08
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 496a21b..87cb0b5 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -117,6 +117,7 @@
"android.hardware.camera.common@1.0",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
+ "android.hardware.camera.provider@2.6",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2fe7179..8666b7b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -420,7 +420,52 @@
}
updateStatus(newStatus, id);
}
+}
+void CameraService::onDeviceStatusChanged(const String8& id,
+ const String8& physicalId,
+ CameraDeviceStatus newHalStatus) {
+ ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
+ __FUNCTION__, id.string(), physicalId.string(), newHalStatus);
+
+ StatusInternal newStatus = mapToInternal(newHalStatus);
+
+ std::shared_ptr<CameraState> state = getCameraState(id);
+
+ if (state == nullptr) {
+ ALOGE("%s: Physical camera id %s status change on a non-present ID %s",
+ __FUNCTION__, id.string(), physicalId.string());
+ return;
+ }
+
+ StatusInternal logicalCameraStatus = state->getStatus();
+ if (logicalCameraStatus != StatusInternal::PRESENT &&
+ logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
+ ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
+ __FUNCTION__, physicalId.string(), newHalStatus, logicalCameraStatus);
+ return;
+ }
+
+ bool updated = false;
+ if (newStatus == StatusInternal::PRESENT) {
+ updated = state->removeUnavailablePhysicalId(physicalId);
+ } else {
+ updated = state->addUnavailablePhysicalId(physicalId);
+ }
+
+ if (updated) {
+ logDeviceRemoved(id, String8::format("Device %s-%s availability changed from %d to %d",
+ id.string(), physicalId.string(),
+ newStatus != StatusInternal::PRESENT,
+ newStatus == StatusInternal::PRESENT));
+
+ String16 id16(id), physicalId16(physicalId);
+ Mutex::Autolock lock(mStatusListenerLock);
+ for (auto& listener : mListenerList) {
+ listener->getListener()->onPhysicalCameraStatusChanged(mapToInterface(newStatus),
+ id16, physicalId16);
+ }
+ }
}
void CameraService::disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect) {
@@ -2045,7 +2090,8 @@
{
Mutex::Autolock lock(mCameraStatesLock);
for (auto& i : mCameraStates) {
- cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
+ cameraStatuses->emplace_back(i.first,
+ mapToInterface(i.second->getStatus()), i.second->getUnavailablePhysicalIds());
}
}
// Remove the camera statuses that should be hidden from the client, we do
@@ -3188,6 +3234,12 @@
return mStatus;
}
+std::vector<String8> CameraService::CameraState::getUnavailablePhysicalIds() const {
+ Mutex::Autolock lock(mStatusLock);
+ std::vector<String8> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
+ return res;
+}
+
CameraParameters CameraService::CameraState::getShimParams() const {
return mShimParams;
}
@@ -3212,6 +3264,18 @@
return mSystemCameraKind;
}
+bool CameraService::CameraState::addUnavailablePhysicalId(const String8& physicalId) {
+ Mutex::Autolock lock(mStatusLock);
+ auto result = mUnavailablePhysicalIds.insert(physicalId);
+ return result.second;
+}
+
+bool CameraService::CameraState::removeUnavailablePhysicalId(const String8& physicalId) {
+ Mutex::Autolock lock(mStatusLock);
+ auto count = mUnavailablePhysicalIds.erase(physicalId);
+ return count > 0;
+}
+
// ----------------------------------------------------------------------------
// ClientEventListener
// ----------------------------------------------------------------------------
@@ -3569,7 +3633,7 @@
return;
}
// Update the status for this camera state, then send the onStatusChangedCallbacks to each
- // of the listeners with both the mStatusStatus and mStatusListenerLock held
+ // of the listeners with both the mStatusLock and mStatusListenerLock held
state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &supportsHAL3]
(const String8& cameraId, StatusInternal status) {
@@ -3591,6 +3655,8 @@
Mutex::Autolock lock(mStatusListenerLock);
+ notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId);
+
for (auto& listener : mListenerList) {
bool isVendorListener = listener->isVendorListener();
if (shouldSkipStatusUpdates(deviceKind, isVendorListener,
@@ -3684,6 +3750,28 @@
return OK;
}
+void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId) {
+ Mutex::Autolock lock(mCameraStatesLock);
+ for (const auto& state : mCameraStates) {
+ std::vector<std::string> physicalCameraIds;
+ if (!mCameraProviderManager->isLogicalCamera(state.first.c_str(), &physicalCameraIds)) {
+ // This is not a logical multi-camera.
+ continue;
+ }
+ if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), cameraId.c_str())
+ == physicalCameraIds.end()) {
+ // cameraId is not a physical camera of this logical multi-camera.
+ continue;
+ }
+
+ String16 id16(state.first), physicalId16(cameraId);
+ for (auto& listener : mListenerList) {
+ listener->getListener()->onPhysicalCameraStatusChanged(status,
+ id16, physicalId16);
+ }
+ }
+}
+
void CameraService::blockClientsForUid(uid_t uid) {
const auto clients = mActiveClientManager.getAll();
for (auto& current : clients) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 726cb0f..34b970d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -103,6 +103,9 @@
virtual void onDeviceStatusChanged(const String8 &cameraId,
hardware::camera::common::V1_0::CameraDeviceStatus newHalStatus) override;
+ virtual void onDeviceStatusChanged(const String8 &cameraId,
+ const String8 &physicalCameraId,
+ hardware::camera::common::V1_0::CameraDeviceStatus newHalStatus) override;
virtual void onTorchStatusChanged(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
virtual void onNewProviderRegistered() override;
@@ -556,11 +559,24 @@
*/
SystemCameraKind getSystemCameraKind() const;
+ /**
+ * Add/Remove the unavailable physical camera ID.
+ */
+ bool addUnavailablePhysicalId(const String8& physicalId);
+ bool removeUnavailablePhysicalId(const String8& physicalId);
+
+ /**
+ * Return the unavailable physical ids for this device.
+ *
+ * This method acquires mStatusLock.
+ */
+ std::vector<String8> getUnavailablePhysicalIds() const;
private:
const String8 mId;
StatusInternal mStatus; // protected by mStatusLock
const int mCost;
std::set<String8> mConflicting;
+ std::set<String8> mUnavailablePhysicalIds;
mutable Mutex mStatusLock;
CameraParameters mShimParams;
const SystemCameraKind mSystemCameraKind;
@@ -962,6 +978,9 @@
status_t setTorchStatusLocked(const String8 &cameraId,
hardware::camera::common::V1_0::TorchModeStatus status);
+ // notify physical camera status when the physical camera is public.
+ void notifyPhysicalCameraStatusLocked(int32_t status, const String8& cameraId);
+
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 0f74a48..57f812f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1255,20 +1255,6 @@
mMinorVersion = 4;
}
- // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
- // before setCallback returns
- hardware::Return<Status> status = interface->setCallback(this);
- if (!status.isOk()) {
- ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
- __FUNCTION__, mProviderName.c_str(), status.description().c_str());
- return DEAD_OBJECT;
- }
- if (status != Status::OK) {
- ALOGE("%s: Unable to register callbacks with camera provider '%s'",
- __FUNCTION__, mProviderName.c_str());
- return mapToStatusT(status);
- }
-
hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
@@ -1297,6 +1283,7 @@
return res;
}
+ Status status;
// Get initial list of camera devices, if any
std::vector<std::string> devices;
hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
@@ -1353,6 +1340,22 @@
}
}
+ // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
+ // before setCallback returns. setCallback must be called after addDevice so that
+ // the physical camera status callback can look up available regular
+ // cameras.
+ hardware::Return<Status> st = interface->setCallback(this);
+ if (!st.isOk()) {
+ ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), st.description().c_str());
+ return DEAD_OBJECT;
+ }
+ if (st != Status::OK) {
+ ALOGE("%s: Unable to register callbacks with camera provider '%s'",
+ __FUNCTION__, mProviderName.c_str());
+ return mapToStatusT(st);
+ }
+
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
@@ -1604,6 +1607,61 @@
return hardware::Void();
}
+hardware::Return<void> CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChange(
+ const hardware::hidl_string& cameraDeviceName,
+ const hardware::hidl_string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ sp<StatusListener> listener;
+ std::string id;
+ bool initialized = false;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ bool known = false;
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ id = deviceInfo->mId;
+
+ if (!deviceInfo->mIsLogicalCamera) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, id.c_str(), physicalCameraDeviceName.c_str());
+ return hardware::Void();
+ }
+ if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
+ physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, id.c_str(), physicalCameraDeviceName.c_str());
+ return hardware::Void();
+ }
+ ALOGI("Camera device %s physical device %s status is now %s, was %s",
+ cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
+ deviceStatusToString(newStatus), deviceStatusToString(
+ deviceInfo->mPhysicalStatus[physicalCameraDeviceName]));
+ known = true;
+ break;
+ }
+ }
+ // Previously unseen device; status must not be NOT_PRESENT
+ if (!known) {
+ ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str(),
+ physicalCameraDeviceName.c_str());
+ return hardware::Void();
+ }
+ listener = mManager->getStatusListener();
+ initialized = mInitialized;
+ }
+ // Call without lock held to allow reentrancy into provider manager
+ // Don't send the callback if providerInfo hasn't been initialized.
+ // CameraService will initialize device status after provider is
+ // initialized
+ if (listener != nullptr && initialized) {
+ String8 physicalId(physicalCameraDeviceName.c_str());
+ listener->onDeviceStatusChanged(String8(id.c_str()),
+ physicalId, newStatus);
+ }
+ return hardware::Void();
+}
+
hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
TorchModeStatus newStatus) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 58df0e8..3eba162 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -29,6 +29,7 @@
#include <utils/Errors.h>
#include <android/hardware/camera/common/1.0/types.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include <camera/VendorTagDescriptor.h>
@@ -136,6 +137,9 @@
virtual void onDeviceStatusChanged(const String8 &cameraId,
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
+ virtual void onDeviceStatusChanged(const String8 &cameraId,
+ const String8 &physicalCameraId,
+ hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
virtual void onTorchStatusChanged(const String8 &cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) = 0;
virtual void onNewProviderRegistered() = 0;
@@ -342,7 +346,7 @@
std::mutex mProviderInterfaceMapLock;
struct ProviderInfo :
- virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
+ virtual public hardware::camera::provider::V2_6::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient
{
const std::string mProviderName;
@@ -380,12 +384,16 @@
status_t dump(int fd, const Vector<String16>& args) const;
// ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex
- virtual hardware::Return<void> cameraDeviceStatusChange(
+ hardware::Return<void> cameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
- virtual hardware::Return<void> torchModeStatusChange(
+ hardware::Return<void> torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
+ hardware::Return<void> physicalCameraDeviceStatusChange(
+ const hardware::hidl_string& cameraDeviceName,
+ const hardware::hidl_string& physicalCameraDeviceName,
+ hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
// hidl_death_recipient interface - this locks the parent mInterfaceMutex
virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
@@ -417,6 +425,8 @@
const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
+ std::map<std::string, hardware::camera::common::V1_0::CameraDeviceStatus>
+ mPhysicalStatus;
sp<ProviderInfo> mParentProvider;
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 0f6be79..175eb8e 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -46,12 +46,18 @@
~H2BCameraServiceListener() { }
virtual ::android::binder::Status onStatusChanged(int32_t status,
- const ::android::String16& cameraId) override;
+ const ::android::String16& cameraId) override;
+ virtual ::android::binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
+ const ::android::String16& /*cameraId*/,
+ const ::android::String16& /*physicalCameraId*/) override {
+ // no implementation yet.
+ return binder::Status::ok();
+ }
virtual ::android::binder::Status onTorchStatusChanged(
- int32_t status, const ::android::String16& cameraId) override;
+ int32_t status, const ::android::String16& cameraId) override;
virtual binder::Status onCameraAccessPrioritiesChanged() {
- // TODO: no implementation yet.
+ // TODO: no implementation yet. b/148146086
return binder::Status::ok();
}
};
diff --git a/services/camera/libcameraservice/tests/Android.mk b/services/camera/libcameraservice/tests/Android.mk
index ec5e876..ea4eb3b 100644
--- a/services/camera/libcameraservice/tests/Android.mk
+++ b/services/camera/libcameraservice/tests/Android.mk
@@ -31,6 +31,7 @@
android.hardware.camera.common@1.0 \
android.hardware.camera.provider@2.4 \
android.hardware.camera.provider@2.5 \
+ android.hardware.camera.provider@2.6 \
android.hardware.camera.device@1.0 \
android.hardware.camera.device@3.2 \
android.hardware.camera.device@3.4
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index 084dc62..a8f6889 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -236,6 +236,8 @@
void onDeviceStatusChanged(const String8 &,
hardware::camera::common::V1_0::CameraDeviceStatus) override {}
+ void onDeviceStatusChanged(const String8 &, const String8 &,
+ hardware::camera::common::V1_0::CameraDeviceStatus) override {}
void onTorchStatusChanged(const String8 &,
hardware::camera::common::V1_0::TorchModeStatus) override {}
void onNewProviderRegistered() override {}