https://deepinout.com/android-camera-native-framework/cameraserver-process-startup-enumerateproviders-hidl-cameradevice-adddevice.html
1 initializeProviderInfoCommon
initializeProviderInfoCommon主要完成2件事情:
- 调用addDevice将CameraDevice保持在mDevices中
- 处理Cached Status回调
void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
const std::vector<std::string> &devices) {
sp<StatusListener> listener = mManager->getStatusListener();
//1. 添加设备
for (auto& device : devices) {
std::string id;
status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
if (res != OK) {
ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
__FUNCTION__, device.c_str(), strerror(-res), res);
continue;
}
}
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
//2. 处理cachedStatus
// Process cached status callbacks
std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
std::make_unique<std::vector<CameraStatusInfoT>>();
{
std::lock_guard<std::mutex> 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));
}
}
2 addDevice完成的4件事情
status_t CameraProviderManager::ProviderInfo::addDevice(
const std::string& name, CameraDeviceStatus initialStatus,
/*out*/ std::string* parsedId) {
ALOGI("Enumerating new camera device: %s", name.c_str());
uint16_t major, minor;
std::string type, id;
//1.1 获取transport
IPCTransport transport = getIPCTransport();
//1.2 获取主设备号、次设备号、类型等
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
return res;
}
if (type != mType) {
ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
type.c_str(), mType.c_str());
return BAD_VALUE;
}
// 1.3 检查设备的合法性,会便利每个provider的每个device,以免重复。
if (mManager->isValidDeviceLocked(id, major, transport)) {
ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
name.c_str(), id.c_str(), major);
return BAD_VALUE;
}
std::unique_ptr<DeviceInfo> deviceInfo;
switch (transport) {
case IPCTransport::HIDL:
switch (major) {
case 3:
break;
default:
ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:",
__FUNCTION__, name.c_str(), major);
return BAD_VALUE;
}
break;
case IPCTransport::AIDL:
if (major != 1) {
ALOGE("%s: Device %s: Unsupported AIDL device HAL major version %d:", __FUNCTION__,
name.c_str(), major);
return BAD_VALUE;
}
break;
default:
ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
return BAD_VALUE;
}
//2 初始化DeviceInfo
deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
if (deviceInfo == nullptr) return BAD_VALUE;
//3 根据手机设备状态去更新ANDROID_SENSOR_ORIENTATION,如屏幕折叠
deviceInfo->notifyDeviceStateChange(getDeviceState());
deviceInfo->mStatus = initialStatus;
//4 判断是否支持API1
bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
mDevices.push_back(std::move(deviceInfo));
mUniqueCameraIds.insert(id);
if (isAPI1Compatible) {
// addDevice can be called more than once for the same camera id if HAL
// supports openLegacy.
if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
id) == mUniqueAPI1CompatibleCameraIds.end()) {
mUniqueAPI1CompatibleCameraIds.push_back(id);
}
}
if (parsedId != nullptr) {
*parsedId = id;
}
return OK;
}
2.1 HidlProviderInfo::initializeDeviceInfo完成3件事情
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
HidlProviderInfo::initializeDeviceInfo(
const std::string &name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion) {
Status status;
//1 获取实例
auto cameraInterface = startDeviceInterface(name);
if (cameraInterface == nullptr) return nullptr;
//2 获取resourceCost
common::V1_0::CameraResourceCost resourceCost;
cameraInterface->getResourceCost([&status, &resourceCost](
Status s, common::V1_0::CameraResourceCost cost) {
status = s;
resourceCost = cost;
});
if (status != Status::OK) {
ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
return nullptr;
}
// 检查名字
for (auto& conflictName : resourceCost.conflictingDevices) {
uint16_t major, minor;
std::string type, id;
status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
if (res != OK) {
ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
return nullptr;
}
conflictName = id;
}
//3. 创建HidlDeviceInfo3
return std::unique_ptr<DeviceInfo3>(
new HidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
this, mProviderPublicCameraIds, cameraInterface));
}
startDeviceInterface
先判断是否为空、如果不为空直接返接口,否则 startDeviceInterface
sp<hardware::camera::device::V3_2::ICameraDevice>
HidlProviderInfo::HidlDeviceInfo3::startDeviceInterface() {
Mutex::Autolock l(mDeviceAvailableLock);
sp<hardware::camera::device::V3_2::ICameraDevice> device;
ATRACE_CALL();
if (mSavedInterface == nullptr) {
sp<HidlProviderInfo> parentProvider =
static_cast<HidlProviderInfo *>(mParentProvider.promote().get());
if (parentProvider != nullptr) {
// Wait for lazy HALs to confirm device availability
if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
ALOGV("%s: Wait for external device to become available %s",
__FUNCTION__,
mId.c_str());
auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
kDeviceAvailableTimeout);
if (res != OK) {
ALOGE("%s: Failed waiting for device to become available",
__FUNCTION__);
return nullptr;
}
}
device = parentProvider->startDeviceInterface(mName);
}
} else {
device = (hardware::camera::device::V3_2::ICameraDevice *) mSavedInterface.get();
}
return device;
}
startDeviceInterface 调用provider的getCameraDeviceInterface_V3_x 获取interface的实例
sp<device::V3_2::ICameraDevice>
HidlProviderInfo::startDeviceInterface(const std::string &name) {
Status status;
sp<device::V3_2::ICameraDevice> cameraInterface;
hardware::Return<void> ret;
const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return nullptr;
}
ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
__FUNCTION__, name.c_str(), ret.description().c_str());
return nullptr;
}
if (status != Status::OK) {
ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
return nullptr;
}
return cameraInterface;
}
2.1.1 创建HidlDeviceInfo3完成5件事情
第四步和第五步 主要是为了,vendor HAL是老版本system framwork 是新版本的情况。
HidlProviderInfo::HidlDeviceInfo3::HidlDeviceInfo3(
const std::string& name,
const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion,
const CameraResourceCost& resourceCost,
sp<CameraProviderManager::ProviderInfo> parentProvider,
const std::vector<std::string>& publicCameraIds,
sp<hardware::camera::device::V3_2::ICameraDevice> interface) :
DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
// Get camera characteristics and initialize flash unit availability
Status status;
hardware::Return<void> ret;
// 获取metadata,保存到 mCameraCharacteristics
ret = interface->getCameraCharacteristics([&status, this](Status s,
device::V3_2::CameraMetadata metadata) {
status = s;
if (s == Status::OK) {
camera_metadata_t *buffer =
reinterpret_cast<camera_metadata_t*>(metadata.data());
size_t expectedSize = metadata.size();
int res = validate_camera_metadata_structure(buffer, &expectedSize);
if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
set_camera_metadata_vendor_id(buffer, mProviderTagid);
mCameraCharacteristics = buffer;
} else {
ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
status = Status::INTERNAL_ERROR;
}
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error getting camera characteristics for device %s"
" to check for a flash unit: %s", __FUNCTION__, id.c_str(),
ret.description().c_str());
return;
}
if (status != Status::OK) {
ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
__FUNCTION__, id.c_str(), statusToString(status), status);
return;
}
//2 获取 DeviceStateOrientationMap
if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
for (size_t i = 0; i < stateMap.count; i += 2) {
mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
}
} else {
ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
stateMap.count);
}
}
//3 获取 mSystemCameraKind
mSystemCameraKind = getSystemCameraKind();
//4 修复
status_t res = fixupMonochromeTags();
if (OK != res) {
ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
__FUNCTION__, strerror(-res), res);
return;
}
auto stat = addDynamicDepthTags();
if (OK != stat) {
ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
stat);
}
res = deriveHeicTags();
if (OK != res) {
ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
__FUNCTION__, strerror(-res), res);
}
if (SessionConfigurationUtils::isUltraHighResolutionSensor(mCameraCharacteristics)) {
status_t status = addDynamicDepthTags(/*maxResolution*/true);
if (OK != status) {
ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
__FUNCTION__, strerror(-status), status);
}
status = deriveHeicTags(/*maxResolution*/true);
if (OK != status) {
ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
"maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
}
}
res = addRotateCropTags();
if (OK != res) {
ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
strerror(-res), res);
}
res = addPreCorrectionActiveArraySize();
if (OK != res) {
ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
strerror(-res), res);
}
res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
&mCameraCharacteristics, &mSupportNativeZoomRatio);
if (OK != res) {
ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
__FUNCTION__, strerror(-res), res);
}
camera_metadata_entry flashAvailable =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
if (flashAvailable.count == 1 &&
flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
mHasFlashUnit = true;
// Fix up flash strength tags for devices without these keys.
res = fixupTorchStrengthTags();
if (OK != res) {
ALOGE("%s: Unable to add default ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL and"
"ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL tags: %s (%d)", __FUNCTION__,
strerror(-res), res);
}
} else {
mHasFlashUnit = false;
}
camera_metadata_entry entry =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
if (entry.count == 1) {
mTorchDefaultStrengthLevel = entry.data.i32[0];
} else {
mTorchDefaultStrengthLevel = 0;
}
entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
if (entry.count == 1) {
mTorchMaximumStrengthLevel = entry.data.i32[0];
} else {
mTorchMaximumStrengthLevel = 0;
}
mTorchStrengthLevel = 0;
queryPhysicalCameraIds();
// Get physical camera characteristics if applicable
auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
if (!castResult.isOk()) {
ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__);
return;
}
sp<device::V3_5::ICameraDevice> interface_3_5 = castResult;
if (interface_3_5 == nullptr) {
ALOGE("%s: Converted ICameraDevice instance to nullptr", __FUNCTION__);
return;
}
if (mIsLogicalCamera) {
for (auto& id : mPhysicalIds) {
if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
mPublicCameraIds.end()) {
continue;
}
hardware::hidl_string hidlId(id);
ret = interface_3_5->getPhysicalCameraCharacteristics(hidlId,
[&status, &id, this](Status s, device::V3_2::CameraMetadata metadata) {
status = s;
if (s == Status::OK) {
camera_metadata_t *buffer =
reinterpret_cast<camera_metadata_t*>(metadata.data());
size_t expectedSize = metadata.size();
int res = validate_camera_metadata_structure(buffer, &expectedSize);
if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
set_camera_metadata_vendor_id(buffer, mProviderTagid);
mPhysicalCameraCharacteristics[id] = buffer;
} else {
ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
status = Status::INTERNAL_ERROR;
}
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
__FUNCTION__, id.c_str(), id.c_str(), ret.description().c_str());
return;
}
if (status != Status::OK) {
ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
__FUNCTION__, id.c_str(), mId.c_str(),
statusToString(status), status);
return;
}
res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
&mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
if (OK != res) {
ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
__FUNCTION__, strerror(-res), res);
}
}
}
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
}
}