修改系统设备类型导致应用无法安装卡开机动画问题分析报告
修改系统设备类型导致应用无法安装卡开机动画问题分析报告
·
1 关键字
设备类型;应用无法安装;开机动画;
2 问题描述
问题环境:
- 系统版本:OpenHarmony-3.2-Release
问题现象:
- 在base/startup/init/services/etc/param/ohos.para中修改const.product.devicetype系统设备类型为custom或其他自定义名称。
const.product.devicetype=custom
- 重新烧录设备后,卡开机动画
3 问题原因
3.1 正常机制
系统正常启动和应用安装正常。
3.2 异常机制
系统启动失败,卡开机动画,应用未正确安装。
使用bm dump -a查看所有安装应用,查询报错。
查看应用安装目录,无任何应用。
4 解决方案
方案一:修改CheckDeviceType默认过滤规则,增加自定义设备类型与默认设备的过滤条件,使现有应用配置的设备类型可以通过设备检查。
在foundation/bundlemanager/bundle_framework/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h文件中增加自定义设备名称。
constexpr const char* DEVICE_TYPE_OF_CUSTOM = "custom";
在foundation/bundlemanager/bundle_framework/services/bundlemgr/src/bundle_install_checker.cpp文件CheckDeviceType函数中增加过滤条件。
if ((deviceType == Constants::DEVICE_TYPE_OF_CUSTOM) &&
((find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_DEFAULT) != devVec.end()) ||
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_PHONE) != devVec.end()))) {
continue;
}
修改后完整函数代码:
ErrCode BundleInstallChecker::CheckDeviceType(std::unordered_map<std::string, InnerBundleInfo> &infos) const
{
std::string deviceType = GetDeviceType();
APP_LOGD("deviceType is %{public}s", deviceType.c_str());
for (const auto &info : infos) {
std::vector<std::string> devVec = info.second.GetDeviceType(info.second.GetCurrentModulePackage());
if (devVec.empty()) {
APP_LOGW("deviceTypes is empty");
continue;
}
if ((deviceType == Constants::DEVICE_TYPE_OF_CUSTOM) &&
((find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_DEFAULT) != devVec.end()) ||
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_PHONE) != devVec.end()))) {
continue;
}
if ((deviceType == Constants::DEVICE_TYPE_OF_PHONE) &&
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_DEFAULT) != devVec.end())) {
APP_LOGW("current deviceType is phone and bundle is matched with default");
continue;
}
if ((deviceType == Constants::DEVICE_TYPE_OF_DEFAULT) &&
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_PHONE) != devVec.end())) {
APP_LOGW("current deviceType is default and bundle is matched with phone");
continue;
}
if (find(devVec.begin(), devVec.end(), deviceType) == devVec.end()) {
APP_LOGE("%{public}s is not supported", deviceType.c_str());
return ERR_APPEXECFWK_INSTALL_DEVICE_TYPE_NOT_SUPPORTED;
}
}
return ERR_OK;
}
方案二:修改应用设备类型,增加自定义设备类型,此方案需修改全部应用的设备类型。
在应用的module.json5配置文件中deviceTypes配置项增加自定义设备类型custom。
{
"module": {
···
"deviceTypes": [
"default",
"custom",
],
···
}
}
5 定位过程
- 单独安装应用测试,报device type is not supported错误。
- 分析安装时日志,发现在检查设备类型时,报应用不支持custom设备类型错误。
08-05 22:17:20.154 541 898 D C01120/BundleMgrService: [bundle_install_checker.cpp(CheckDeviceType):1026] deviceType is custom
08-05 22:17:20.154 541 898 E C01120/BundleMgrService: [bundle_install_checker.cpp(CheckDeviceType):1047] custom is not supported
08-05 22:17:20.154 541 898 E C01120/BundleMgrService: [base_bundle_installer.cpp(ParseHapFiles):2206] CheckDeviceType failed due to errorCode : 8519725
- 查找报错位置对应源码。devVec变量为应用在module.json5中配置的支持的设备类型容器,社区Launcher默认配置的为default和tablet。在CheckDeviceType的判断中,由于没有触发默认过滤条件,又在应用支持的设备列表中没有配置custom设备,导致返回错误。
// foundation/bundlemanager/bundle_framework/services/bundlemgr/src/bundle_install_checker.cpp
ErrCode BundleInstallChecker::CheckDeviceType(std::unordered_map<std::string, InnerBundleInfo> &infos) const
{
std::string deviceType = GetDeviceType();
APP_LOGD("deviceType is %{public}s", deviceType.c_str());
for (const auto &info : infos) {
std::vector<std::string> devVec = info.second.GetDeviceType(info.second.GetCurrentModulePackage());
// devVec不为空,无法进入
if (devVec.empty()) {
APP_LOGW("deviceTypes is empty");
continue;
}
// deviceType为custom,无法进入
if ((deviceType == Constants::DEVICE_TYPE_OF_PHONE) &&
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_DEFAULT) != devVec.end())) {
APP_LOGW("current deviceType is phone and bundle is matched with default");
continue;
}
// deviceType为custom,无法进入
if ((deviceType == Constants::DEVICE_TYPE_OF_DEFAULT) &&
(find(devVec.begin(), devVec.end(), Constants::DEVICE_TYPE_OF_PHONE) != devVec.end())) {
APP_LOGW("current deviceType is default and bundle is matched with phone");
continue;
}
// devVec中无custom,进入返回报错信息
if (find(devVec.begin(), devVec.end(), deviceType) == devVec.end()) {
APP_LOGE("%{public}s is not supported", deviceType.c_str());
return ERR_APPEXECFWK_INSTALL_DEVICE_TYPE_NOT_SUPPORTED;
}
}
return ERR_OK;
}
6 知识分享
ohos.para配置文件中配置的信息,部分可以通过接口@ohos.deviceInfo获取,对应关系可参考以下两个文件:
- /base/startup/init/interfaces/kits/jskits/src/native_deviceinfo_js.cpp
- /base/startup/init/interfaces/syspara/parameter.c
例如:const.product.software.version对应@ohos.deviceInfo接口中displayVersion参数。
更多推荐
已为社区贡献19条内容
所有评论(0)