Open Harmony——包管理子系统包安装模块源码解析

系统教程2年前发布 10100
17 0 0
文章目录
  • foundation/appexecfwk/standard├── kits│ └── appkit # Appkit实现的核心代码├── common│ └── log # 日志组件目录├── interfaces│ └── innerkits # 内部接口存放目录├── services│ └── bundlemgr # 包管理服务框架代码│ └── dbms # 分布式包管理服务框架代码├── test # 测试目录└── tools # bm命令存放目录
  • Open Harmony——包管理子系统包安装模块源码解析

    ​想了解更多关于开源的内容,请访问:​

    ​51CTO 开源基础软件社区​

    ​https://ost.51cto.com​

    包管理子系统负责应用安装包的管理,提供安装包的信息查询、安装、更新、卸载和包信息存储等能力。

    包管理子系统架构如下图所示:

    Open Harmony——包管理子系统包安装模块源码解析

    foundation/appexecfwk/standard
    ├── kits
    └── appkit # Appkit实现的核心代码
    ├── common
    └── log # 日志组件目录
    ├── interfaces
    └── innerkits # 内部接口存放目录
    ├── services
    └── bundlemgr # 包管理服务框架代码
    └── dbms # 分布式包管理服务框架代码
    ├── test # 测试目录
    └── tools # bm命令存放目录

    Open Harmony——包管理子系统包安装模块源码解析

    BaseBundleInstaller是安装流程中最重要的类,最终的安装、卸载功能都是在其中实现的。

    IBundleMgr中定义了获取IBundleInstaller实例的方法GetBundleInstaller。

    IBundleInstaller类是BundleInstallerProxy和BundleInstallerHost的基类,只是在类中声明了Install,Uninstall等函数,具体实现是在这两个子类中实现的。

    BundleInstallerProxy类实现了Install,Uninstall功能,利用IPC Proxy向service层发送安装或卸载请求。

    服务层Host接收到Proxy发送过来的请求处理消息,调用BundleInstallerHost类的Install功能,调用BundleInstallerManager类的创建安装任务CreateInstallTask函数,在此函数中调用BundleInstaller类的Install功能。

    BundleInstaller类的基类是BaseBundleInstaller,它的Install功能实际上调用的是BaseBundleInstaller类的InstallBundle函数。

    BMSEventHandler类是继承EventHandler类的,由它来处理系统应用包的安装。它调用SystemBundleInstaller类的InstallSystemBundle函数。

    SystemBundleInstaller类也是BaseBundleInstaller的子类,所以最终调用的还是BaseBundleInstaller的InstallBundle功能。

    类名

    功能简介

    IBundleMgr

    包管理类,声明了获取和查询APP信息、包信息等接口。

    IBundleInstaller

    包安装类,声明了安装、卸载等接口。

    BundleInstallerProxy

    interface层包安装代理类,继承了IBundleInstaller类,实现了安装、卸载等功能。

    BundleInstallerHost

    service层host侧包安装类,继承了IBundleInstaller类,处理来自proxy的安装、卸载信息,实现了host侧安装、卸载等功能,。

    BundleInstallerManager

    包安装服务类,创建安装、卸载等任务。

    BundleInstaller

    包安装类,实现安装、卸载第三方应用包功能。

    BMSEventHandler

    继承EventHandler,实现了处理系统应用包安装等功能。

    SystemBundleInstaller

    系统应用包安装类,实现安装、卸载系统应用包功能。

    BaseBundleInstaller

    包安装基类,实现安装、卸载包功能。

    Open Harmony——包管理子系统包安装模块源码解析

    由于流程较为复杂,受篇幅限制,此处摘取流程中重要的代码段进行说明。详细的代码流程需要对照OpenHarmony源码进行学习。

    foundation\appexecfwk\standard\kits\appkit\napi\bundlemgr\native_module.cpp。

    //注册模块
    extern "C" __attribute__((constructor)) void RegisterModule(void)
    {
    napi_module_register(&_module);
    }
    //包模块描述
    static napi_module _module = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "bundle",
    .nm_priv = ((void *)0),
    .reserved = {0}
    };
    //初始化
    static napi_value Init(napi_env env, napi_value exports)
    {
    ...
    napi_property_descriptor properties[] = {
    DECLARE_NAPI_FUNCTION("install", Install),//调用Install流程
    DECLARE_NAPI_FUNCTION("recover", Recover),
    DECLARE_NAPI_FUNCTION("uninstall", Uninstall),
    };
    NAPI_CALL(env,
    napi_define_class(env,
    "BundleInstaller",
    NAPI_AUTO_LENGTH,
    BundleInstallerConstructor,
    nullptr,
    sizeof(properties) / sizeof(*properties),
    properties,
    &m_classBundleInstaller));
    }

    foundation\appexecfwk\standard\kits\appkit\napi\bundlemgr\bundle_mgr.cpp。

    napi_value Install(napi_env env, napi_callback_info info)
    {
    ...
    napi_create_async_work(
    env,
    nullptr,
    resourceName,
    [](napi_env env, void *data) {
    AsyncInstallCallbackInfo *asyncCallbackInfo = (AsyncInstallCallbackInfo *)data;
    if (!asyncCallbackInfo->errCode) {
    InnerInstall(env,
    asyncCallbackInfo->hapFiles,
    asyncCallbackInfo->installParam,
    asyncCallbackInfo->installResult);//调用InnerInstall
    }
    },
    ...
    }
    static void InnerInstall(napi_env env, const std::vector<std::string> &bundleFilePath, InstallParam &installParam,
    InstallResult &installResult)
    {
    if (bundleFilePath.empty()) {
    installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID);
    return;
    }
    auto iBundleMgr = GetBundleMgr();
    if (!iBundleMgr) {
    APP_LOGE("can not get iBundleMgr");
    return;
    }
    auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
    if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
    APP_LOGE("can not get iBundleInstaller");
    return;
    }
    installParam.installFlag = InstallFlag::REPLACE_EXISTING;
    OHOS::sptr<InstallerCallback> callback = new InstallerCallback();
    if (!callback) {
    APP_LOGE("callback nullptr");
    return;
    }

    sptr<BundleDeathRecipient> recipient(new BundleDeathRecipient(callback));
    iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
    iBundleInstaller->Install(bundleFilePath, installParam, callback);//调用IBundleInstaller的Install
    installResult.resultMsg = callback->GetResultMsg();
    APP_LOGD("InnerInstall resultMsg %{public}s", installResult.resultMsg.c_str());
    installResult.resultCode = callback->GetResultCode();
    APP_LOGD("InnerInstall resultCode %{public}d", installResult.resultCode);
    }

    foundation\appexecfwk\standard\interfaces\innerkits\appexecfwk_core\src\bundlemgr\bundle_installer_proxy.cpp。

    bool BundleInstallerProxy::Install(
    const std::string &bundlePath, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
    {
    BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
    MessageParcel data;
    MessageParcel reply;
    MessageOption option(MessageOption::TF_SYNC);
    PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor());
    PARCEL_WRITE(data, String16, Str8ToStr16(bundlePath));
    PARCEL_WRITE(data, Parcelable, &installParam);
    if (!statusReceiver) {
    APP_LOGE("fail to install, for statusReceiver is nullptr");
    return false;
    }
    if (!data.WriteObject<IRemoteObject>(statusReceiver->AsObject())) {
    APP_LOGE("write parcel failed");
    return false;
    }
    return SendInstallRequest(static_cast<int32_t>(IBundleInstaller::Message::INSTALL), data, reply, option);//发送安装消息
    }
    bool BundleInstallerProxy::SendInstallRequest(const int32_t& code, MessageParcel& data, MessageParcel& reply,
    MessageOption& option)
    {
    sptr<IRemoteObject> remote = Remote();
    if (!remote) {
    APP_LOGE("fail to uninstall, for Remote() is nullptr");
    return false;
    }
    int32_t ret = remote->SendRequest(code, data, reply, option);//发送安装消息
    if (ret != NO_ERROR) {
    APP_LOGE("fail to sendRequest, for transact is failed and error code is: %{public}d", ret);
    return false;
    }
    return true;
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\bundle_installer_host.cpp。

    int BundleInstallerHost::OnRemoteRequest(
    uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
    {
    APP_LOGD("bundle installer host onReceived message, the message code is %{public}u", code);
    std::u16string descripter = GetDescriptor();
    std::u16string remoteDescripter = data.ReadInterfaceToken();
    if (descripter != remoteDescripter) {
    APP_LOGE("fail to write reply message in bundle mgr host due to the reply is nullptr");
    return OBJECT_NULL;
    }
    switch (code) {
    case static_cast<uint32_t>(IBundleInstaller::Message::INSTALL):
    HandleInstallMessage(data);//处理安装消息
    break;
    case static_cast<uint32_t>(IBundleInstaller::Message::INSTALL_MULTIPLE_HAPS):
    HandleInstallMultipleHapsMessage(data);
    break;
    case static_cast<uint32_t>(IBundleInstaller::Message::UNINSTALL):
    HandleUninstallMessage(data);
    break;
    case static_cast<uint32_t>(IBundleInstaller::Message::UNINSTALL_MODULE):
    HandleUninstallModuleMessage(data);
    break;
    case static_cast<uint32_t>(IBundleInstaller::Message::RECOVER):
    HandleRecoverMessage(data);
    break;
    default:
    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
    }
    return NO_ERROR;
    }

    void BundleInstallerHost::HandleInstallMessage(Parcel &data)
    {
    APP_LOGD("handle install message");
    std::string bundlePath = Str16ToStr8(data.ReadString16());
    std::unique_ptr<InstallParam> installParam(data.ReadParcelable<InstallParam>());
    if (!installParam) {
    APP_LOGE("ReadParcelable<InstallParam> failed");
    return;
    }
    sptr<IRemoteObject> object = data.ReadObject<IRemoteObject>();
    if (object == nullptr) {
    APP_LOGE("read failed");
    return;
    }
    sptr<IStatusReceiver> statusReceiver = iface_cast<IStatusReceiver>(object);

    Install(bundlePath, *installParam, statusReceiver);//调用安装函数
    APP_LOGD("handle install message finished");
    }
    bool BundleInstallerHost::Install(
    const std::string &bundleFilePath, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
    {
    if (!CheckBundleInstallerManager(statusReceiver)) {
    APP_LOGE("statusReceiver invalid");
    return false;
    }
    if (!BundlePermissionMgr::VerifyCallingPermission(Constants::PERMISSION_INSTALL_BUNDLE)) {
    APP_LOGE("install permission denied");
    statusReceiver->OnFinished(ERR_APPEXECFWK_INSTALL_PERMISSION_DENIED, "");
    return false;
    }
    manager_->CreateInstallTask(bundleFilePath, CheckInstallParam(installParam), statusReceiver);//创建安装任务
    return true;
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\bundle_installer_manager.cpp。

    void BundleInstallerManager::CreateInstallTask(
    const std::string &bundleFilePath, const InstallParam &installParam, const sptr<IStatusReceiver> &statusReceiver)
    {
    auto installer = CreateInstaller(statusReceiver);
    if (!installer) {
    APP_LOGE("create installer failed");
    return;
    }
    auto task = [installer, bundleFilePath, installParam] {
    int timerId = HiviewDFX::XCollie::GetInstance().SetTimer(INSTALL_TASK, TIME_OUT_SECONDS,
    nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
    installer->Install(bundleFilePath, installParam);//调用BundleInstaller的Install函数
    HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
    };
    installersPool_.AddTask(task);
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\bundle_installer.cpp。

    void BundleInstaller::Install(const std::string &bundleFilePath, const InstallParam &installParam)
    {
    ErrCode resultCode = ERR_OK;
    if (installParam.userId == Constants::ALL_USERID) {
    auto userInstallParam = installParam;
    for (auto userId : GetExistsCommonUserIs()) {
    userInstallParam.userId = userId;
    userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING;
    resultCode = InstallBundle(
    bundleFilePath, userInstallParam, Constants::AppType::THIRD_PARTY_APP);//安装第三方应用的包
    ResetInstallProperties();
    }
    } else {
    resultCode = InstallBundle(
    bundleFilePath, installParam, Constants::AppType::THIRD_PARTY_APP);//安装第三方应用的包
    }
    statusReceiver_->OnFinished(resultCode, "");
    SendRemoveEvent();
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\base_bundle_installer.cpp。

    ErrCode BaseBundleInstaller::InstallBundle(
    const std::string &bundlePath, const InstallParam &installParam, const Constants::AppType appType)
    {
    std::vector<std::string> bundlePaths { bundlePath };
    return InstallBundle(bundlePaths, installParam, appType);
    }
    ErrCode BaseBundleInstaller::InstallBundle(
    const std::vector<std::string> &bundlePaths, const InstallParam &installParam, const Constants::AppType appType)
    {
    BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
    APP_LOGD("begin to process bundle install");
    PerfProfile::GetInstance().SetBundleInstallStartTime(GetTickCount());
    int32_t uid = Constants::INVALID_UID;
    ErrCode result = ProcessBundleInstall(bundlePaths, installParam, appType, uid);//处理包安装的具体流程
    if (installParam.needSendEvent && dataMgr_ && !bundleName_.empty()) {
    dataMgr_->NotifyBundleStatus(bundleName_,
    Constants::EMPTY_STRING,
    mainAbility_,
    result,
    isAppExist_ ? NotifyType::UPDATE : NotifyType::INSTALL,
    uid);//包安装完成后反馈包安装状态
    }
    PerfProfile::GetInstance().SetBundleInstallEndTime(GetTickCount());
    APP_LOGD("finish to process bundle install");
    return result;
    }

    Open Harmony——包管理子系统包安装模块源码解析

    限于篇幅,每个调用函数只摘抄关键语句。

    foundation\appexecfwk\standard\services\bundlemgr\src\bundle_mgr_service_event_handler.cpp。

    void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer &event)
    {
    switch (event->GetInnerEventId()) {
    case BUNDLE_SCAN_START: {
    OnStartScanning(Constants::DEFAULT_USERID);//启动扫描
    SetAllInstallFlag();
    DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
    break;
    }
    case BUNDLE_SCAN_FINISHED:
    break;
    case BMS_START_FINISHED:
    break;
    case BUNDLE_REBOOT_SCAN_START: {
    RebootStartScanning();
    SetAllInstallFlag();
    DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
    break;
    }
    default:
    APP_LOGE("the eventId is not supported");
    break;
    }
    }
    void BMSEventHandler::OnStartScanning(int32_t userId)
    {
    auto future = std::async(std::launch::async, [this, userId] {
    ProcessSystemBundleInstall(Constants::AppType::SYSTEM_APP, userId);//处理系统应用包安装
    ProcessSystemBundleInstall(Constants::AppType::THIRD_SYSTEM_APP, userId);//处理第三方系统应用包安装
    });
    future.get();
    }
    void BMSEventHandler::ProcessSystemBundleInstall(Constants::AppType appType, int32_t userId) const
    {
    APP_LOGD("scan thread start");
    auto scanner = std::make_unique<BundleScanner>();
    if (!scanner) {
    APP_LOGE("make scanner failed");
    return;
    }
    std::string scanDir = (appType == Constants::AppType::SYSTEM_APP) ? Constants::SYSTEM_APP_SCAN_PATH
    : Constants::THIRD_SYSTEM_APP_SCAN_PATH;
    APP_LOGD("scanDir: %{public}s and userId: %{public}d", scanDir.c_str(), userId);
    std::list<std::string> bundleList = scanner->Scan(scanDir);
    auto iter = std::find(bundleList.begin(), bundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH);
    if (iter != bundleList.end()) {
    bundleList.erase(iter);
    bundleList.insert(bundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH);
    }
    for (const auto &item : bundleList) {
    SystemBundleInstaller installer(item);
    APP_LOGD("scan item %{public}s", item.c_str());
    if (!installer.InstallSystemBundle(appType, userId)) {//调用安装系统包流程
    APP_LOGW("Install System app:%{public}s error", item.c_str());
    }
    }
    PerfProfile::GetInstance().Dump();
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\system_bundle_installer.cpp。

    bool SystemBundleInstaller::InstallSystemBundle(Constants::AppType appType, int32_t userId)
    {
    InstallParam installParam;
    installParam.userId = userId;
    installParam.isPreInstallApp = true;
    installParam.noSkipsKill = false;
    installParam.needSendEvent = false;
    if (appType == Constants::AppType::SYSTEM_APP
    || appType == Constants::AppType::THIRD_SYSTEM_APP) {
    installParam.needSavePreInstallInfo = true;
    }
    ErrCode result = InstallBundle(filePath_, installParam, appType);
    if (result != ERR_OK) {
    APP_LOGE("install system bundle fail, error: %{public}d", result);
    return false;
    }
    return true;
    }

    foundation\appexecfwk\standard\services\bundlemgr\src\base_bundle_installer.cpp。

    ErrCode BaseBundleInstaller::InstallBundle(
    const std::string &bundlePath, const InstallParam &installParam, const Constants::AppType appType)
    {
    std::vector<std::string> bundlePaths { bundlePath };
    return InstallBundle(bundlePaths, installParam, appType);
    }
    ErrCode BaseBundleInstaller::InstallBundle(
    const std::vector<std::string> &bundlePaths, const InstallParam &installParam, const Constants::AppType appType)
    {
    BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
    APP_LOGD("begin to process bundle install");
    PerfProfile::GetInstance().SetBundleInstallStartTime(GetTickCount());
    int32_t uid = Constants::INVALID_UID;
    ErrCode result = ProcessBundleInstall(bundlePaths, installParam, appType, uid);//处理包安装的具体流程
    if (installParam.needSendEvent && dataMgr_ && !bundleName_.empty()) {
    dataMgr_->NotifyBundleStatus(bundleName_,
    Constants::EMPTY_STRING,
    mainAbility_,
    result,
    isAppExist_ ? NotifyType::UPDATE : NotifyType::INSTALL,
    uid);//包安装完成后反馈包安装状态
    }
    PerfProfile::GetInstance().SetBundleInstallEndTime(GetTickCount());
    APP_LOGD("finish to process bundle install");
    return result;
    }

    本文主要介绍了包管理子系统的关键实现机制、主要类关系及重要的处理流程,为开发人员维护和扩展功能提供参考。

    ​想了解更多关于开源的内容,请访问:​

    ​51CTO 开源基础软件社区​

    ​https://ost.51cto.com​

    © 版权声明

    相关文章