diff --git a/services/bundlemgr/include/base_bundle_installer.h b/services/bundlemgr/include/base_bundle_installer.h index 8e4e96afbc059f3cfce3c479b72476b76efd992c..a93862bc5f5bfa26cbba7be63c95d303cde7e9c8 100644 --- a/services/bundlemgr/include/base_bundle_installer.h +++ b/services/bundlemgr/include/base_bundle_installer.h @@ -143,6 +143,11 @@ protected: { state_ = state; } + + std::string GetCurrentBundleName() const + { + return bundleName_; + } /** * @brief The main function for bundle install by bundleName. * @param bundleName Indicates the bundleName of the application to install. diff --git a/services/bundlemgr/include/bundle_data_mgr.h b/services/bundlemgr/include/bundle_data_mgr.h index 18e7ceacda1158ae323f9358cdfda2778ac58d9c..eeb6fa788d187e417b6b478ef3595e2f1af1683f 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -873,6 +873,7 @@ public: ErrCode ResetAOTCompileStatus(const std::string &bundleName, const std::string &moduleName, int32_t triggerMode); std::vector GetAllBundleName() const; + std::vector GetAllDriverBundleName() const; bool IsBundleExist(const std::string &bundleName) const; bool QueryInnerBundleInfo(const std::string &bundleName, InnerBundleInfo &info) const; std::vector GetUserIds(const std::string &bundleName) const; diff --git a/services/bundlemgr/include/bundle_installer.h b/services/bundlemgr/include/bundle_installer.h index 189dc51e57e40cb8c058cac7b8d084310f00389d..da7b5c2af6c53429b5d33e85286acd833adb15ab 100644 --- a/services/bundlemgr/include/bundle_installer.h +++ b/services/bundlemgr/include/bundle_installer.h @@ -107,6 +107,14 @@ private: */ std::set GetExistsCommonUserIds(); + void InstallDriverForAllUsers(const std::string &bundleFilePath, const InstallParam &installParam); + + void InstallDriverForAllUsers(const std::vector &bundleFilePaths, const InstallParam &installParam); + + void RecoverDriverForAllUsers(const std::string &bundleName, const InstallParam &installParam); + + bool HasDriverExtensionAbility(const std::string &bundleName); + private: const int64_t installerId_ = 0; const sptr statusReceiver_; diff --git a/services/bundlemgr/include/bundle_user_mgr_host_impl.h b/services/bundlemgr/include/bundle_user_mgr_host_impl.h index a15150ba76cdffa36623a6a38532f76b8c37b619..515830a63385a7040e06650b1a97f85522d90ad9 100644 --- a/services/bundlemgr/include/bundle_user_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_user_mgr_host_impl.h @@ -59,6 +59,7 @@ private: int32_t userId, std::set &preInstallBundleInfos); void UninstallBackupUninstallList(int32_t userId); + void GetAllDriverBundleInfos(std::set &preInstallBundleInfos); std::mutex bundleUserMgrMutex_; diff --git a/services/bundlemgr/include/pre_install_bundle_info.h b/services/bundlemgr/include/pre_install_bundle_info.h index 5a80f440b1e369608d65d646856ac527de3efb98..2352bf89fd2a3241ee7317eb4c3103ed70d1ed11 100644 --- a/services/bundlemgr/include/pre_install_bundle_info.h +++ b/services/bundlemgr/include/pre_install_bundle_info.h @@ -264,6 +264,16 @@ public: bundleType_ = bundleType; } + bool GetIsNonPreDriverApp() const + { + return isNonPreDriverApp_; + } + + void SetIsNonPreDriverApp(bool isNonPreDriverApp) + { + isNonPreDriverApp_ = isNonPreDriverApp; + } + private: std::string bundleName_; std::string moduleName_; @@ -277,6 +287,8 @@ private: Constants::AppType appType_ = Constants::AppType::SYSTEM_APP; bool systemApp_ = false; BundleType bundleType_ = BundleType::APP; + // non pre-installed driver app also need to be pre-installed for new user + bool isNonPreDriverApp_ = false; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/bundle_data_mgr.cpp b/services/bundlemgr/src/bundle_data_mgr.cpp index 296a1d9ec09b227e223e1b3c33f4f2de977dba28..fdb52f51f5782c8cc8761aa2c16662737a465227 100644 --- a/services/bundlemgr/src/bundle_data_mgr.cpp +++ b/services/bundlemgr/src/bundle_data_mgr.cpp @@ -6572,6 +6572,35 @@ std::vector BundleDataMgr::GetAllBundleName() const return bundleNames; } +std::vector BundleDataMgr::GetAllDriverBundleName() const +{ + APP_LOGD("GetAllDriverBundleName begin"); + std::shared_lock lock(bundleInfoMutex_); + std::vector bundleNames; + for (const auto &item : bundleInfos_) { + if (item.second.GetApplicationBundleType() == BundleType::SHARED || + item.second.GetApplicationBundleType() == BundleType::APP_SERVICE_FWK) { + APP_LOGD("app %{public}s is cross-app shared bundle or appService, ignore", + item.second.GetBundleName().c_str()); + continue; + } + // this function is used to install driver bundle in new user, so ignore pre-install app + if (item.second.IsPreInstallApp()) { + APP_LOGD("app %{public}s is pre-install app, ignore", item.second.GetBundleName().c_str()); + continue; + } + const auto extensions = item.second.GetInnerExtensionInfos(); + for (const auto &item : extensions) { + if (item.second.type == ExtensionAbilityType::DRIVER) { + bundleNames.emplace_back(item.second.bundleName); + APP_LOGI("driver bundle found: %{public}s", item.second.bundleName.c_str()); + break; + } + } + } + return bundleNames; +} + bool BundleDataMgr::QueryInnerBundleInfo(const std::string &bundleName, InnerBundleInfo &info) const { APP_LOGD("QueryInnerBundleInfo begin, bundleName : %{public}s", bundleName.c_str()); diff --git a/services/bundlemgr/src/bundle_installer.cpp b/services/bundlemgr/src/bundle_installer.cpp index c16fe0ad7eed81009997cc8a52aabe5647ecb8dd..b7ac9a6adddc80256f4038a961afed5b1c1db8b9 100644 --- a/services/bundlemgr/src/bundle_installer.cpp +++ b/services/bundlemgr/src/bundle_installer.cpp @@ -51,6 +51,7 @@ void BundleInstaller::Install(const std::string &bundleFilePath, const InstallPa } else { resultCode = InstallBundle( bundleFilePath, installParam, Constants::AppType::THIRD_PARTY_APP); + InstallDriverForAllUsers(bundleFilePath, installParam); } std::string resultMsg = GetCheckResultMsg(); SetCheckResultMsg(""); @@ -72,6 +73,7 @@ void BundleInstaller::Recover(const std::string &bundleName, const InstallParam } } else { resultCode = BaseBundleInstaller::Recover(bundleName, installParam); + RecoverDriverForAllUsers(bundleName, installParam); } if (statusReceiver_ != nullptr) { @@ -96,6 +98,7 @@ void BundleInstaller::Install(const std::vector &bundleFilePaths, c NotifyAllBundleStatus(); } else { resultCode = InstallBundle(bundleFilePaths, installParam, Constants::AppType::THIRD_PARTY_APP); + InstallDriverForAllUsers(bundleFilePaths, installParam); } std::string resultMsg = GetCheckResultMsg(); SetCheckResultMsg(""); @@ -115,7 +118,7 @@ void BundleInstaller::InstallByBundleName(const std::string &bundleName, const I void BundleInstaller::Uninstall(const std::string &bundleName, const InstallParam &installParam) { ErrCode resultCode = ERR_OK; - if (installParam.userId == Constants::ALL_USERID) { + if (installParam.userId == Constants::ALL_USERID || HasDriverExtensionAbility(bundleName)) { std::vector errCode; auto userInstallParam = installParam; for (auto userId : GetExistsCommonUserIds()) { @@ -158,7 +161,7 @@ void BundleInstaller::Uninstall( const std::string &bundleName, const std::string &modulePackage, const InstallParam &installParam) { ErrCode resultCode = ERR_OK; - if (installParam.userId == Constants::ALL_USERID) { + if (installParam.userId == Constants::ALL_USERID || HasDriverExtensionAbility(bundleName)) { std::vector errCode; auto userInstallParam = installParam; for (auto userId : GetExistsCommonUserIds()) { @@ -215,6 +218,86 @@ std::set BundleInstaller::GetExistsCommonUserIds() return userIds; } +void BundleInstaller::InstallDriverForAllUsers(const std::string &bundleFilePath, const InstallParam &installParam) +{ + std::vector bundleFilePaths { bundleFilePath }; + InstallDriverForAllUsers(bundleFilePaths, installParam); +} + +void BundleInstaller::InstallDriverForAllUsers(const std::vector &bundleFilePaths, + const InstallParam &installParam) +{ + std::string bundleName = GetCurrentBundleName(); + if (!HasDriverExtensionAbility(bundleName)) { + APP_LOGD("bundle %{public}s has no driver extension ability", bundleName.c_str()); + return; + } + APP_LOGI("bundle %{public}s has driver extension ability, need to install for all users", bundleName.c_str()); + ResetInstallProperties(); + auto userInstallParam = installParam; + userInstallParam.allUser = true; + for (auto userId : GetExistsCommonUserIds()) { + if (userId == installParam.userId) { + continue; + } + userInstallParam.userId = userId; + userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING; + ErrCode resultCode = InstallBundle( + bundleFilePaths, userInstallParam, Constants::AppType::THIRD_PARTY_APP); + ResetInstallProperties(); + if (resultCode != ERR_OK) { + APP_LOGE("install driver for user %{public}d failed, resultCode: %{public}d", userId, resultCode); + } + } + NotifyAllBundleStatus(); +} + +void BundleInstaller::RecoverDriverForAllUsers(const std::string &bundleName, const InstallParam &installParam) +{ + if (!HasDriverExtensionAbility(bundleName)) { + APP_LOGD("bundle %{public}s has no driver extension ability", bundleName.c_str()); + return; + } + APP_LOGI("bundle %{public}s has driver extension ability, need to recover for all users", bundleName.c_str()); + ResetInstallProperties(); + auto userInstallParam = installParam; + for (auto userId : GetExistsCommonUserIds()) { + if (userId == installParam.userId) { + continue; + } + userInstallParam.userId = userId; + userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING; + ErrCode resultCode = BaseBundleInstaller::Recover(bundleName, userInstallParam); + ResetInstallProperties(); + if (resultCode != ERR_OK) { + APP_LOGE("recover driver for user %{public}d failed, resultCode: %{public}d", userId, resultCode); + } + } +} + +bool BundleInstaller::HasDriverExtensionAbility(const std::string &bundleName) +{ + auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); + if (dataMgr == nullptr) { + APP_LOGE("Get dataMgr shared_ptr nullptr"); + return false; + } + + InnerBundleInfo info; + bool isAppExist = dataMgr->FetchInnerBundleInfo(bundleName, info); + if (isAppExist) { + const auto extensions = info.GetInnerExtensionInfos(); + for (const auto &item : extensions) { + if (item.second.type == ExtensionAbilityType::DRIVER) { + APP_LOGI("find driver extension ability, bundleName: %{public}s, moduleName: %{public}s", + item.second.bundleName.c_str(), item.second.moduleName.c_str()); + return true; + } + } + } + return false; +} + void BundleInstaller::UninstallAndRecover(const std::string &bundleName, const InstallParam &installParam) { ErrCode resultCode = ERR_OK; diff --git a/services/bundlemgr/src/bundle_user_mgr_host_impl.cpp b/services/bundlemgr/src/bundle_user_mgr_host_impl.cpp index 6eff7c258903e8027bac7de34ef87ef16a8a0f24..be269a2a45604c371118f9b9449565b3a442cfe7 100644 --- a/services/bundlemgr/src/bundle_user_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_user_mgr_host_impl.cpp @@ -140,6 +140,7 @@ void BundleUserMgrHostImpl::OnCreateNewUser(int32_t userId, const std::vector bundlePromise = std::make_shared(); @@ -150,7 +151,7 @@ void BundleUserMgrHostImpl::OnCreateNewUser(int32_t userId, const std::vector userReceiverImpl( new (std::nothrow) UserReceiverImpl(info.GetBundleName(), needReinstall)); @@ -204,6 +205,23 @@ bool BundleUserMgrHostImpl::GetAllPreInstallBundleInfos( return !preInstallBundleInfos.empty(); } +void BundleUserMgrHostImpl::GetAllDriverBundleInfos(std::set &preInstallBundleInfos) +{ + auto dataMgr = GetDataMgrFromService(); + if (dataMgr == nullptr) { + APP_LOGE("DataMgr is nullptr"); + return; + } + // get all non pre-installed driver apps to install for new user + std::vector driverBundleNames = dataMgr->GetAllDriverBundleName(); + for (auto &driverBundleName : driverBundleNames) { + PreInstallBundleInfo preInstallBundleInfo; + preInstallBundleInfo.SetBundleName(driverBundleName); + preInstallBundleInfo.SetIsNonPreDriverApp(true); + preInstallBundleInfos.insert(preInstallBundleInfo); + } +} + void BundleUserMgrHostImpl::AfterCreateNewUser(int32_t userId) { if (userId == Constants::START_USERID) { diff --git a/services/bundlemgr/test/unittest/bms_bundle_manager_test/bms_bundle_manager_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_manager_test/bms_bundle_manager_test.cpp index 0c19d3b53eba8f09520e4c2b6de27bcb205b8109..5b55559e2880df898d4ff3b7485e8bb266e5d95e 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_manager_test/bms_bundle_manager_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_manager_test/bms_bundle_manager_test.cpp @@ -5946,4 +5946,35 @@ HWTEST_F(BmsBundleManagerTest, InitExtendResourceManager_0010, Function | SmallT auto result = DelayedSingleton::GetInstance()->GetExtendResourceManager(); EXPECT_NE(result, nullptr); } + +/** + * @tc.number: GetAllDriverBundleName_0100 + * @tc.name: test GetAllDriverBundleName without driver bundle + */ +HWTEST_F(BmsBundleManagerTest, GetAllDriverBundleName_0100, Function | SmallTest | Level1) +{ + auto dataMgr = GetBundleDataMgr(); + ASSERT_NE(dataMgr, nullptr); + dataMgr->bundleInfos_.clear(); + std::vector ret = dataMgr->GetAllDriverBundleName(); + EXPECT_EQ(ret.size(), 0); +} + +/** + * @tc.number: GetAllDriverBundleName_0200 + * @tc.name: test GetAllDriverBundleName within driver bundle + */ +HWTEST_F(BmsBundleManagerTest, GetAllDriverBundleName_0200, Function | SmallTest | Level1) +{ + auto dataMgr = GetBundleDataMgr(); + ASSERT_NE(dataMgr, nullptr); + InnerBundleInfo info; + ExtensionAbilityInfo abilityInfo; + abilityInfo.type = ExtensionAbilityType::DRIVER; + info.InsertExtensionInfo("key", abilityInfo); + dataMgr->bundleInfos_.try_emplace(BUNDLE_NAME, info); + std::vector ret = dataMgr->GetAllDriverBundleName(); + EXPECT_EQ(ret.size(), 1); + dataMgr->bundleInfos_.clear(); +} } // OHOS