https://deepinout.com/android-camera-native-framework/cameraserver-process-startup-enumerateproviders-hidl-cameraprovider-initialize.html
1 HIDL Camera Provider初始化
HIDL Camera Provider初始化流程如下:
1.1 regestForNotification
监听provider的通知
- provider 注册成功上报一个通知
- HAL 进程crash 重新注册provider
1.2 listServices
查看 有多少个 provider
1.3 new ProviderInfo
创建新的结构体变量,记录provider的信息
1.4 initializeHidlProvider
初始化provider
2 initializeHidlProvider详解
2.1 确定HAL的最低版本
通过castFrom来判断ICameraProvider的mMinorVersion
原因: 有些API是新的版本才支持的,如果没有支持,调用起来就会crash
2.2 接收ICameraProviderCallback的回调
调用setCallback方法
作用: HAL这边回调一些消息给cameraServer
2.3 注册 HAL进程 死亡处理
调用linkToDeath方法,在serviceDied处理HAL进程挂掉后的异常,remove掉Provider
2.4 通知 HAL进程 当前摄像头的状态
可以一次性通知多个状态
- NORMAL
- BACK COVERED 后置被遮住
- FRONT COVERED
- FOLDED 折叠,前后置交换
调用notifyDeviceStateChange通知Camera HAL进程,该功能在 Provider 2.5及之后的版本才有。
2.5 获取 VendorTags
setUpVendorTags调用ICameraProvider的getVendorTags方法拿到VendorTagSection,然后创建 VendorTagDescriptor,通过VendorTagDescriptor就能知道有哪些Vendor Tag了
不同的provider的VendorTags定义可能不同,每个VendorTags变量对应一个 device
2.6 获取 Proyider支持的Camera Device
调用ICameraProvider的getCameraldList方法获取到当前Proyider支持的Camera Device,解析出 Camera ID存放在mProviderPublicCameralds(解析规则解读)
2.7 查看 camera是否支持 同时ConfigureStream
针对Provider >= 2.6
·调用Provider的getConcurrentStreamingCameralds获取哪些Camera可以同时做ConfigureStream,存放在 mConcurrentCameraldCombinations
2.8 查看是否支持手电筒
调用Provider的isSetTorchModeSupported判断是否支持手电筒,存放在mSetTorchModeSupported
2.9 完成Device的初始化
调用initializeProviderInfoCommon
代码基于Android 13:
status_t HidlProviderInfo::initializeHidlProvider(
sp& interface,
int64_t currentDeviceState) {
status_t res = parseProviderName(mProviderName, &mType, &mId);
if (res != OK) {
ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
return BAD_VALUE;
}
// remote表示 hal代码跑在独立的进程
// 否则 hal代码的跑在cameraServer进程
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), interface->isRemote());
// 2.1 确定HAL的最低版本
// Determine minor version
mMinorVersion = 4;
auto cast2_6 = provider::V2_6::ICameraProvider::castFrom(interface);
sp interface2_6 = nullptr;
if (cast2_6.isOk()) {
interface2_6 = cast2_6;
if (interface2_6 != nullptr) {
mMinorVersion = 6;
}
}
// We need to check again since cast2_6.isOk() succeeds even if the provider
// version isn't actually 2.6.
if (interface2_6 == nullptr){
auto cast2_5 =
provider::V2_5::ICameraProvider::castFrom(interface);
sp interface2_5 = nullptr;
if (cast2_5.isOk()) {
interface2_5 = cast2_5;
if (interface != nullptr) {
mMinorVersion = 5;
}
}
} else {
auto cast2_7 = provider::V2_7::ICameraProvider::castFrom(interface);
if (cast2_7.isOk()) {
sp interface2_7 = cast2_7;
if (interface2_7 != nullptr) {
mMinorVersion = 7;
}
}
}
// 2.2 接收ICameraProviderCallback的回调
// cameraDeviceStatusChange callbacks may be called (and causing new devices added)
// before setCallback returns
hardware::Return 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);
}
// 2.3 注册 HAL进程 死亡处理
hardware::Return linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
return DEAD_OBJECT;
} else if (!linked) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
}
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
} else {
mActiveInterface = interface;
}
ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
__FUNCTION__, mProviderName.c_str(), mDeviceState);
// 2.4 通知 HAL进程 当前摄像头的状态
notifyDeviceStateChange(currentDeviceState);
// 2.5 获取 VendorTags
res = setUpVendorTags();
if (res != OK) {
ALOGE("%s: Unable to set up vendor tags from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return res;
}
// 2.6 获取 Proyider支持的Camera Device
// Get initial list of camera devices, if any
std::vector devices;
hardware::Return ret = interface->getCameraIdList([&status, this, &devices](
Status idStatus,
const hardware::hidl_vec& cameraDeviceNames) {
status = idStatus;
if (status == Status::OK) {
for (auto& name : cameraDeviceNames) {
uint16_t major, minor;
std::string type, id;
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
status = Status::INTERNAL_ERROR;
} else {
devices.push_back(name);
mProviderPublicCameraIds.push_back(id);
}
}
} });
if (!ret.isOk()) {
ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
return DEAD_OBJECT;
}
if (status != Status::OK) {
ALOGE("%s: Unable to query for camera devices from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return mapToStatusT(status);
}
// 2.7 查看 camera是否支持 同时ConfigureStream
// Get list of concurrent streaming camera device combinations
if (mMinorVersion >= 6) {
res = getConcurrentCameraIdsInternalLocked(interface2_6);
if (res != OK) {
return res;
}
}
//2.8 查看是否支持手电筒
ret = interface->isSetTorchModeSupported(
[this](auto status, bool supported) {
if (status == Status::OK) {
mSetTorchModeSupported = supported;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error checking torch mode support '%s': %s",
__FUNCTION__, mProviderName.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
mIsRemote = interface->isRemote();
// 2.9 完成Device的初始化
initializeProviderInfoCommon(devices);
return OK;
}