本讲是Android Camera Native Framework专题的第13讲,我们介绍cameraserver进程启动之PhysicalCameraDeviceStatusChange。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
initializeProviderInfoCommon
initializeProviderInfoCommon主要完成2件事情:
- 调用addDevice将CameraDevice保持在mDevices中
- 处理Cached Status回调
前面的课程已经介绍了addDevice的逻辑,本讲介绍处理Cached Status回调。
什么时候会有Cache Status
- 在CameraServer初始化Provider过程中,HAL通知发生了physicalCameraDeviceStatusChange 或 cameraDeviceStatusChange
Process Cache Status Callbacks
上面流程的逻辑来自Android 13:
// Process cached status callbacks
std::unique_ptr> cachedStatus =
std::make_unique>();
{
std::lock_guard lock(mInitLock);
for (auto& statusInfo : mCachedStatus) {
std::string id, physicalId;
status_t res = OK;
if (statusInfo.isPhysicalCameraStatus) {
res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
} else {
res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
}
if (res == OK) {
cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
id.c_str(), physicalId.c_str(), statusInfo.status);
}
}
mCachedStatus.clear();
mInitialized = true;
}
// The cached status change callbacks cannot be fired directly from this
// function, due to same-thread deadlock trying to acquire mInterfaceMutex
// twice.
if (listener != nullptr) {
mInitialStatusCallbackFuture = std::async(std::launch::async,
&CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
listener, std::move(cachedStatus));
}
physicalCameraDeviceStatusChangeLocked
上面流程的逻辑来自Android 13:
status_t CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeLocked(
std::string* id, std::string* physicalId,
const std::string& cameraDeviceName,
const std::string& physicalCameraDeviceName,
CameraDeviceStatus newStatus) {
bool known = false;
std::string cameraId;
for (auto& deviceInfo : mDevices) {
if (deviceInfo->mName == cameraDeviceName) {
cameraId = deviceInfo->mId;
if (!deviceInfo->mIsLogicalCamera) {
ALOGE("%s: Invalid combination of camera id %s, physical id %s",
__FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
return BAD_VALUE;
}
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__, cameraId.c_str(), physicalCameraDeviceName.c_str());
return BAD_VALUE;
}
ALOGI("Camera device %s physical device %s status is now %s",
cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
FrameworkDeviceStatusToString(newStatus));
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 BAD_VALUE;
}
*id = cameraId;
*physicalId = physicalCameraDeviceName.c_str();
return OK;
}
Physical onDeviceStatusChanged
关于SystemCameraKind的说明如下:
SystemCameraKind | Description |
---|---|
PUBLIC | 所有拥有Camera权限的进程可使用 |
SYSTEM_ONLY_CAMERA | 三方App不可用,且必须有SYSTEM_CAMERA权限 |
HIDDEN_SECURE_CAMERA | 只给Vendor Client(HAL进程)使用 |
上面流程的逻辑来自Android 13:
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 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) {
String8 idCombo = id + " : " + physicalId;
if (newStatus == StatusInternal::PRESENT) {
logDeviceAdded(idCombo,
String8::format("Device status changed to %d", newStatus));
} else {
logDeviceRemoved(idCombo,
String8::format("Device status changed to %d", newStatus));
}
// Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(id, &deviceKind) != OK) {
ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.string());
return;
}
String16 id16(id), physicalId16(physicalId);
Mutex::Autolock lock(mStatusListenerLock);
for (auto& listener : mListenerList) {
if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
listener->getListenerPid(), listener->getListenerUid())) {
ALOGV("Skipping discovery callback for system-only camera device %s",
id.c_str());
continue;
}
listener->getListener()->onPhysicalCameraStatusChanged(mapToInterface(newStatus),
id16, physicalId16);
}
}
}