Merge "Camera: Support new provider callback version in camera service"

gugelfrei
Shuzhen Wang 5 years ago committed by Android (Google) Code Review
commit a2055c57ea

@ -60,6 +60,13 @@ status_t CameraStatus::writeToParcel(android::Parcel* parcel) const {
if (res != OK) return res;
res = parcel->writeInt32(status);
if (res != OK) return res;
std::vector<String16> unavailablePhysicalIds16;
for (auto& id8 : unavailablePhysicalIds) {
unavailablePhysicalIds16.push_back(String16(id8));
}
res = parcel->writeString16Vector(unavailablePhysicalIds16);
return res;
}
@ -70,6 +77,14 @@ status_t CameraStatus::readFromParcel(const android::Parcel* parcel) {
cameraId = String8(tempCameraId);
res = parcel->readInt32(&status);
if (res != OK) return res;
std::vector<String16> unavailablePhysicalIds16;
res = parcel->readString16Vector(&unavailablePhysicalIds16);
if (res != OK) return res;
for (auto& id16 : unavailablePhysicalIds16) {
unavailablePhysicalIds.push_back(String8(id16));
}
return res;
}

@ -53,6 +53,12 @@ interface ICameraServiceListener
oneway void onStatusChanged(int status, String cameraId);
/**
* Notify registered client about status changes for a physical camera backing
* a logical camera.
*/
oneway void onPhysicalCameraStatusChanged(int status, String cameraId, String physicalCameraId);
/**
* The torch mode status of a camera.
*

@ -32,6 +32,7 @@ cc_binary {
"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",

@ -80,10 +80,16 @@ struct CameraStatus : public android::Parcelable {
*/
int32_t status;
/**
* Unavailable physical camera names for a multi-camera device
*/
std::vector<String8> unavailablePhysicalIds;
virtual status_t writeToParcel(android::Parcel* parcel) const;
virtual status_t readFromParcel(const android::Parcel* parcel);
CameraStatus(String8 id, int32_t s) : cameraId(id), status(s) {}
CameraStatus(String8 id, int32_t s, const std::vector<String8>& unavailSubIds) :
cameraId(id), status(s), unavailablePhysicalIds(unavailSubIds) {}
CameraStatus() : status(ICameraServiceListener::STATUS_PRESENT) {}
};

@ -32,6 +32,7 @@ namespace android {
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 @@ void CameraManagerGlobal::registerAvailabilityCallback(
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 @@ void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
// 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 @@ void CameraManagerGlobal::CallbackHandler::onMessageReceived(
(*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 @@ binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
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 @@ void CameraManagerGlobal::onStatusChangedLocked(
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 @@ void CameraManagerGlobal::onStatusChangedLocked(
}
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::onStatusChangedLocked(
}
}
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

@ -85,6 +85,8 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
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 @@ class CameraManagerGlobal final : public RefBase {
};
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

@ -122,6 +122,21 @@ void ACameraManager_deleteCameraIdList(ACameraIdList* cameraIdList) __INTRODUCED
typedef void (*ACameraManager_AvailabilityCallback)(void* context,
const char* cameraId);
/**
* Definition of physical camera availability callbacks.
*
* @param context The optional application context provided by user in
* {@link ACameraManager_AvailabilityCallbacks}.
* @param cameraId The ID of the logical multi-camera device whose physical camera status is
* changing. The memory of this argument is owned by camera framework and will
* become invalid immediately after this callback returns.
* @param physicalCameraId The ID of the physical camera device whose status is changing. The
* memory of this argument is owned by camera framework and will become invalid
* immediately after this callback returns.
*/
typedef void (*ACameraManager_PhysicalCameraAvailabilityCallback)(void* context,
const char* cameraId, const char* physicalCameraId);
/**
* A listener for camera devices becoming available or unavailable to open.
*
@ -320,8 +335,15 @@ typedef struct ACameraManager_ExtendedAvailabilityListener {
/// Called when there is camera access permission change
ACameraManager_AccessPrioritiesChangedCallback onCameraAccessPrioritiesChanged;
/// Called when a physical camera becomes available
ACameraManager_PhysicalCameraAvailabilityCallback onPhysicalCameraAvailable __INTRODUCED_IN(30);
/// Called when a physical camera becomes unavailable
ACameraManager_PhysicalCameraAvailabilityCallback onPhysicalCameraUnavailable
__INTRODUCED_IN(30);
/// Reserved for future use, please ensure that all entries are set to NULL
void *reserved[6];
void *reserved[4];
} ACameraManager_ExtendedAvailabilityCallbacks;
/**

@ -7941,14 +7941,20 @@ typedef enum acamera_metadata_enum_acamera_request_available_capabilities {
* <p>The camera device is a logical camera backed by two or more physical cameras.</p>
* <p>In API level 28, the physical cameras must also be exposed to the application via
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>.</p>
* <p>Starting from API level 29, some or all physical cameras may not be independently
* exposed to the application, in which case the physical camera IDs will not be
* available in <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. But the
* <p>Starting from API level 29:</p>
* <ul>
* <li>Some or all physical cameras may not be independently exposed to the application,
* in which case the physical camera IDs will not be available in
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. But the
* application can still query the physical cameras' characteristics by calling
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics">CameraManager#getCameraCharacteristics</a>. Additionally,
* if a physical camera is hidden from camera ID list, the mandatory stream combinations
* for that physical camera must be supported through the logical camera using physical
* streams.</p>
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics">CameraManager#getCameraCharacteristics</a>.</li>
* <li>If a physical camera is hidden from camera ID list, the mandatory stream
* combinations for that physical camera must be supported through the logical camera
* using physical streams. One exception is that in API level 30, a physical camera
* may become unavailable via
* {@link ACameraManager_PhysicalCameraAvailabilityCallback }
* callback.</li>
* </ul>
* <p>Combinations of logical and physical streams, or physical streams from different
* physical cameras are not guaranteed. However, if the camera device supports
* {@link ACameraDevice_isSessionConfigurationSupported },

@ -83,6 +83,12 @@ public:
return binder::Status::ok();
};
virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
const String16& /*cameraId*/, const String16& /*physicalCameraId*/) {
// No op
return binder::Status::ok();
};
virtual binder::Status onTorchStatusChanged(int32_t status, const String16& cameraId) {
Mutex::Autolock l(mLock);
mCameraTorchStatuses[cameraId] = status;

@ -117,6 +117,7 @@ cc_library_shared {
"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",

@ -420,7 +420,52 @@ void CameraService::onDeviceStatusChanged(const String8& id,
}
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 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen
{
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 @@ CameraService::StatusInternal CameraService::CameraState::getStatus() const {
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 @@ SystemCameraKind CameraService::CameraState::getSystemCameraKind() const {
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 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
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 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
Mutex::Autolock lock(mStatusListenerLock);
notifyPhysicalCameraStatusLocked(mapToInterface(status), cameraId);
for (auto& listener : mListenerList) {
bool isVendorListener = listener->isVendorListener();
if (shouldSkipStatusUpdates(deviceKind, isVendorListener,
@ -3684,6 +3750,28 @@ status_t CameraService::setTorchStatusLocked(const String8& cameraId,
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) {

@ -103,6 +103,9 @@ public:
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 @@ private:
*/
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 @@ private:
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);

@ -1255,20 +1255,6 @@ status_t CameraProviderManager::ProviderInfo::initialize(
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 @@ status_t CameraProviderManager::ProviderInfo::initialize(
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 @@ status_t CameraProviderManager::ProviderInfo::initialize(
}
}
// 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 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusCh
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) {

@ -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 @@ public:
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 @@ private:
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 @@ private:
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 @@ private:
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;

@ -46,12 +46,18 @@ struct H2BCameraServiceListener :
~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();
}
};

@ -31,6 +31,7 @@ LOCAL_SHARED_LIBRARIES := \
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

@ -236,6 +236,8 @@ struct TestStatusListener : public CameraProviderManager::StatusListener {
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 {}

Loading…
Cancel
Save