本讲是Android Camera Native Framework专题的第9讲,我们介绍cameraserver进程启动之HIDL CameraProvider初始化。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
HIDL Camera Provider初始化
HIDL Camera Provider初始化流程如下:
initializeHidlProvider详解
代码基于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;
}
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), interface->isRemote());
// 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;
}
}
}
// 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);
}
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);
notifyDeviceStateChange(currentDeviceState);
res = setUpVendorTags();
if (res != OK) {
ALOGE("%s: Unable to set up vendor tags from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return res;
}
// 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);
}
// Get list of concurrent streaming camera device combinations
if (mMinorVersion >= 6) {
res = getConcurrentCameraIdsInternalLocked(interface2_6);
if (res != OK) {
return res;
}
}
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();
initializeProviderInfoCommon(devices);
return OK;
}
解释:
- 通过castFrom来判断ICameraProvider的mMinorVersion
- 调用setCallback方法,接收ICameraProviderCallback的回调
- 调用linkToDeath方法,在serviceDied处理HAL进程挂掉后的异常,remove掉Provider
- 调用notifyDeviceStateChange通知Camera HAL进程,当前摄像头的状态(NORMAL/BACK_COVERED/FRONT_COVERED/FOLDED,可以一次性通知多个状态),该功能在Provider 2.5及之后的版本才有
- setUpVendorTags,调用ICameraProvider的getVendorTags方法拿到VendorTagSection,然后创建VendorTagDescriptor,通过VendorTagDescriptor就能知道有哪些Vendor Tag了
- 调用ICameraProvider的getCameraIdList方法获取到当前Provider支持的Camera Device,解析出Camera ID存放在mProviderPublicCameraIds(解析规则解读)
-
针对Provider >= 2.6
- 调用Provider的getConcurrentStreamingCameraIds获取哪些Camera可以同时做ConfigureStream,存放在mConcurrentCameraIdCombinations
- 调用Provider的isSetTorchModeSupported判断是否支持手电筒,存放在mSetTorchModeSupported
- 调用initializeProviderInfoCommon,完成Device的初始化