1 关键字

设备类型;应用无法安装;开机动画;

2 问题描述

问题环境:

  • 系统版本:OpenHarmony-3.2-Release

问题现象:

  1. base/startup/init/services/etc/param/ohos.para中修改const.product.devicetype系统设备类型为custom或其他自定义名称。
const.product.devicetype=custom
  1. 重新烧录设备后,卡开机动画

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 定位过程

  1. 单独安装应用测试,报device type is not supported错误。

  2. 分析安装时日志,发现在检查设备类型时,报应用不支持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
  1. 查找报错位置对应源码。devVec变量为应用在module.json5中配置的支持的设备类型容器,社区Launcher默认配置的为defaulttablet。在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参数。

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐