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/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 7a0f63b..4870265 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -32,6 +32,7 @@
namespace acam {
// Static member definitions
const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
+const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Mutex CameraManagerGlobal::sLock;
@@ -220,7 +221,7 @@
if (pair.second) {
for (auto& pair : mDeviceStatusMap) {
const String8& cameraId = pair.first;
- int32_t status = pair.second.status;
+ int32_t status = pair.second.getStatus();
// Don't send initial callbacks for camera ids which don't support
// camera2
if (!pair.second.supportsHAL3) {
@@ -264,9 +265,9 @@
// Needed to make sure we're connected to cameraservice
getCameraServiceLocked();
for(auto& deviceStatus : mDeviceStatusMap) {
- if (deviceStatus.second.status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
- deviceStatus.second.status ==
- hardware::ICameraServiceListener::STATUS_ENUMERATING) {
+ int32_t status = deviceStatus.second.getStatus();
+ if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
+ status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
continue;
}
if (!deviceStatus.second.supportsHAL3) {
@@ -341,6 +342,39 @@
(*cb)(context);
break;
}
+ case kWhatSendSinglePhysicalCameraCallback:
+ {
+ ACameraManager_PhysicalCameraAvailabilityCallback cb;
+ void* context;
+ AString cameraId;
+ AString physicalCameraId;
+ bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+ if (!found) {
+ ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+ return;
+ }
+ if (cb == nullptr) {
+ // Physical camera callback is null
+ return;
+ }
+ found = msg->findPointer(kContextKey, &context);
+ if (!found) {
+ ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+ return;
+ }
+ found = msg->findString(kCameraIdKey, &cameraId);
+ if (!found) {
+ ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
+ return;
+ }
+ found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
+ if (!found) {
+ ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
+ return;
+ }
+ (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
+ break;
+ }
default:
ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
break;
@@ -368,6 +402,17 @@
return binder::Status::ok();
}
+binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
+ int32_t status, const String16& cameraId, const String16& physicalCameraId) {
+ sp<CameraManagerGlobal> cm = mCameraManager.promote();
+ if (cm != nullptr) {
+ cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
+ } else {
+ ALOGE("Cannot deliver physical camera status change. Global camera manager died");
+ }
+ return binder::Status::ok();
+}
+
void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
Mutex::Autolock _l(mLock);
for (auto cb : mCallbacks) {
@@ -397,7 +442,7 @@
bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
int32_t oldStatus = firstStatus ?
status : // first status
- mDeviceStatusMap[cameraId].status;
+ mDeviceStatusMap[cameraId].getStatus();
if (!firstStatus &&
isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
@@ -406,8 +451,14 @@
}
bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
+ if (firstStatus) {
+ mDeviceStatusMap.emplace(std::piecewise_construct,
+ std::forward_as_tuple(cameraId),
+ std::forward_as_tuple(status, supportsHAL3));
+ } else {
+ mDeviceStatusMap[cameraId].updateStatus(status);
+ }
// Iterate through all registered callbacks
- mDeviceStatusMap[cameraId] = StatusAndHAL3Support(status, supportsHAL3);
if (supportsHAL3) {
for (auto cb : mCallbacks) {
sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
@@ -424,6 +475,81 @@
}
}
+void CameraManagerGlobal::onStatusChanged(
+ int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+ Mutex::Autolock _l(mLock);
+ onStatusChangedLocked(status, cameraId, physicalCameraId);
+}
+
+void CameraManagerGlobal::onStatusChangedLocked(
+ int32_t status, const String8& cameraId, const String8& physicalCameraId) {
+ if (!validStatus(status)) {
+ ALOGE("%s: Invalid status %d", __FUNCTION__, status);
+ return;
+ }
+
+ auto logicalStatus = mDeviceStatusMap.find(cameraId);
+ if (logicalStatus == mDeviceStatusMap.end()) {
+ ALOGE("%s: Physical camera id %s status change on a non-present id %s",
+ __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
+ return;
+ }
+ int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
+ if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
+ logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
+ ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
+ __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
+ return;
+ }
+
+ bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
+
+ bool updated = false;
+ if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
+ updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
+ } else {
+ updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
+ }
+
+ // Iterate through all registered callbacks
+ if (supportsHAL3 && updated) {
+ for (auto cb : mCallbacks) {
+ sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
+ ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
+ cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
+ msg->setPointer(kCallbackFpKey, (void *) cbFp);
+ msg->setPointer(kContextKey, cb.mContext);
+ msg->setString(kCameraIdKey, AString(cameraId));
+ msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+ msg->post();
+ }
+ }
+}
+
+int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
+ std::lock_guard<std::mutex> lock(mLock);
+ return status;
+}
+
+void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
+ std::lock_guard<std::mutex> lock(mLock);
+ status = newStatus;
+}
+
+bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
+ const String8& physicalCameraId) {
+ std::lock_guard<std::mutex> lock(mLock);
+ auto result = unavailablePhysicalIds.insert(physicalCameraId);
+ return result.second;
+}
+
+bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
+ const String8& physicalCameraId) {
+ std::lock_guard<std::mutex> lock(mLock);
+ auto count = unavailablePhysicalIds.erase(physicalCameraId);
+ return count > 0;
+}
+
} // namespace acam
} // namespace android
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index e945ba0..98cd934 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -85,6 +85,8 @@
public:
explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId);
+ virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
+ const String16& cameraId, const String16& physicalCameraId);
// Torch API not implemented yet
virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
@@ -104,18 +106,24 @@
mAvailable(callback->onCameraAvailable),
mUnavailable(callback->onCameraUnavailable),
mAccessPriorityChanged(nullptr),
+ mPhysicalCamAvailable(nullptr),
+ mPhysicalCamUnavailable(nullptr),
mContext(callback->context) {}
explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
mAvailable(callback->availabilityCallbacks.onCameraAvailable),
mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
+ mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
+ mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
mContext(callback->availabilityCallbacks.context) {}
bool operator == (const Callback& other) const {
return (mAvailable == other.mAvailable &&
mUnavailable == other.mUnavailable &&
mAccessPriorityChanged == other.mAccessPriorityChanged &&
+ mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
+ mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
mContext == other.mContext);
}
bool operator != (const Callback& other) const {
@@ -124,6 +132,12 @@
bool operator < (const Callback& other) const {
if (*this == other) return false;
if (mContext != other.mContext) return mContext < other.mContext;
+ if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
+ return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
+ }
+ if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
+ return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
+ }
if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
return mAccessPriorityChanged < other.mAccessPriorityChanged;
}
@@ -136,6 +150,8 @@
ACameraManager_AvailabilityCallback mAvailable;
ACameraManager_AvailabilityCallback mUnavailable;
ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
+ ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
+ ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
void* mContext;
};
std::set<Callback> mCallbacks;
@@ -144,8 +160,10 @@
enum {
kWhatSendSingleCallback,
kWhatSendSingleAccessCallback,
+ kWhatSendSinglePhysicalCameraCallback,
};
static const char* kCameraIdKey;
+ static const char* kPhysicalCameraIdKey;
static const char* kCallbackFpKey;
static const char* kContextKey;
class CallbackHandler : public AHandler {
@@ -160,6 +178,9 @@
void onCameraAccessPrioritiesChanged();
void onStatusChanged(int32_t status, const String8& cameraId);
void onStatusChangedLocked(int32_t status, const String8& cameraId);
+ void onStatusChanged(int32_t status, const String8& cameraId, const String8& physicalCameraId);
+ void onStatusChangedLocked(int32_t status, const String8& cameraId,
+ const String8& physicalCameraId);
// Utils for status
static bool validStatus(int32_t status);
static bool isStatusAvailable(int32_t status);
@@ -187,11 +208,20 @@
};
struct StatusAndHAL3Support {
+ private:
int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
- bool supportsHAL3 = false;
+ mutable std::mutex mLock;
+ std::set<String8> unavailablePhysicalIds;
+ public:
+ const bool supportsHAL3 = false;
StatusAndHAL3Support(int32_t st, bool HAL3support):
status(st), supportsHAL3(HAL3support) { };
StatusAndHAL3Support() = default;
+
+ bool addUnavailablePhysicalId(const String8& physicalCameraId);
+ bool removeUnavailablePhysicalId(const String8& physicalCameraId);
+ int32_t getStatus();
+ void updateStatus(int32_t newStatus);
};
// Map camera_id -> status