本讲是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的初始化