prebundle

Signed-off-by: dujingcheng <dujingcheng@huawei.com>
Change-Id: I987b2bd96746aa6b3727239fce3c383a6385fd57
This commit is contained in:
dujingcheng 2022-04-12 09:51:49 +08:00
parent 1800a18f33
commit 5cf6533846
11 changed files with 922 additions and 142 deletions

View File

@ -20,6 +20,7 @@ services_path = "${appexecfwk_path}/services"
kits_path = "${appexecfwk_path}/kits"
innerkits_path = "${appexecfwk_path}/interfaces/innerkits"
tools_path = "${appexecfwk_path}/tools"
use_pre_bundle_profile = false
declare_args() {
bundle_framework_graphics = true
bundle_framework_free_install = true

View File

@ -199,7 +199,9 @@ enum {
ERR_APPEXECFWK_FORM_SEND_FMS_MSG,
ERR_APPEXECFWK_FORM_FORM_DUPLICATE_ADDED,
ERR_APPEXECFWK_FORM_IN_RECOVER,
ERR_APPEXECFWK_FORM_GET_SYSMGR_FAILED
ERR_APPEXECFWK_FORM_GET_SYSMGR_FAILED,
// error code in prebundle sacn
ERR_APPEXECFWK_PARSE_FILE_FAILED
};
// Error code for Hidump
constexpr ErrCode APPEXECFWK_HIDUMP = ErrCodeOffset(SUBSYS_APPEXECFWK, APPEXECFWK_MODULE_HIDUMP);

View File

@ -223,6 +223,12 @@ constexpr std::string_view ABILTY_NAME = "abilityName";
const std::string HMDFS_CONFIG_PATH {"/config/hmdfs/"};
const std::string BUNDLE_ID_FILE = { "bid" };
const std::string PATH_SEPERATE {"/"};
// pre bundle profile
const std::string DEFAULT_PRE_BUNDLE_PROFILE = "/system/etc/bundle";
const std::string PREINSTALL_CONFIG = "/preinstall_config.json";
const std::string PREINSTALL_UNINSTALL_CONFIG = "/pre_uninstall_config.json";
const std::string PREINSTALL_ABILITY_CONFIG = "/preinstall_ability_config.json";
} // namespace Constants
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -89,6 +89,7 @@ ohos_source_set("bundle_parser") {
"src/bundle_parser.cpp",
"src/bundle_profile.cpp",
"src/module_profile.cpp",
"src/pre_bundle_profile.cpp",
]
public_configs = bundlemgr_parser_common_config
@ -234,6 +235,10 @@ ohos_shared_library("libbms") {
defines += [ "HICOLLIE_ENABLE" ]
}
if (use_pre_bundle_profile) {
defines += [ "USE_PRE_BUNDLE_PROFILE" ]
}
subsystem_name = "appexecfwk"
part_name = "bundle_framework"
}

View File

@ -19,6 +19,7 @@
#include "bundle_constants.h"
#include "bundle_data_mgr.h"
#include "event_handler.h"
#include "pre_scan_info.h"
namespace OHOS {
namespace AppExecFwk {
@ -44,7 +45,38 @@ public:
private:
/**
* @brief Install system and system vendor bundles.
* @brief start boot scan.
* @param userId Indicates the userId.
* @return
*/
void OnBootStartScanning(int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief Process boot bundle install from scan.
* @param userId Indicates the userId.
* @return
*/
void ProcessBootBundleInstallFromScan(int32_t userId);
/**
* @brief Process boot bundle install from pre bundle profile.
* @param userId Indicates the userId.
* @return
*/
void ProcessBootBundleInstallFromPreBundleProFile(int32_t userId);
/**
* @brief Process bundle install by scanInfos.
* @param scanInfos Indicates the scanInfos contains installed info.
* @param uninstallBundleNames Indicates the uninstall bundleNames.
* @param preBundleConfigInfos Indicates the preBundleConfigInfos.
* @param userId Indicates the userId.
* @return
*/
void InnerProcessBootPreBundleProFileInstall(
const std::set<PreScanInfo> &scanInfos,
const std::set<std::string> &uninstallBundleNames,
const std::set<PreBundleConfigInfo> &preBundleConfigInfos,
int32_t userId);
/**
* @brief Install bundles by scanDir.
* @param scanDir Indicates the scanDir.
* @param appType Indicates the bundle type.
* @param userId Indicates userId.
@ -52,29 +84,114 @@ private:
*/
void ProcessSystemBundleInstall(const std::string &scanDir,
Constants::AppType appType, int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief Install bundles by preScanInfo.
* @param preScanInfo Indicates the preScanInfo.
* @param preBundleConfig Indicates the preBundleConfig.
* @param userId Indicates userId.
* @return
*/
void ProcessSystemBundleInstall(
const PreScanInfo &preScanInfo,
const PreBundleConfigInfo &preBundleConfig,
int32_t userId);
/**
* @brief start reboot scan.
* @param userId Indicates the userId.
* @return
*/
void OnRebootStartScanning(int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief Process reboot bundle.
* @param userId Indicates the userId.
* @return
*/
void ProcessRebootBundle(int32_t userId);
/**
* @brief Obtains the PreInstallBundleInfo objects.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
bool LoadAllPreInstallBundleInfos();
/**
* @brief Process reboot bundle install.
* @return
*/
void ProcessRebootBundleInstall();
/**
* @brief Process reboot bundle install from pre bundle profile.
* @return
*/
void ProcessRebootBundleInstallFromPreBundleProFile();
/**
* @brief Process reboot bundle install by scanInfos.
* @param scanInfos Indicates the scanInfos contains installed info.
* @param uninstallBundleNames Indicates the uninstall bundleNames.
* @param preBundleConfigInfos Indicates the preBundleConfigInfos.
* @return
*/
void ProcessReBootPreBundleProFileInstall(
const std::set<PreScanInfo> &scanInfos,
const std::set<std::string> &uninstallBundleNames,
const std::set<PreBundleConfigInfo> &preBundleConfigInfos);
/**
* @brief Process reboot bundle install from scan.
* @return
*/
void ProcessRebootBundleInstallFromScan();
/**
* @brief Process reboot install bundles by bundleList.
* @param bundleList Indicates store bundle list.
* @param appType Indicates the bundle type.
* @return
*/
void InnerProcessRebootBundleInstall(
const std::list<std::string> &bundleList, Constants::AppType appType);
/**
* @brief Reboot uninstall system and system vendor bundles.
* @return
*/
void ProcessRebootBundleUninstall();
/**
* @brief Get bundle dir by scan.
* @param bundleDirs Indicates the return bundleDirs.
* @return
*/
void GetBundleDirFromScan(std::list<std::string> &bundleDirs);
/**
* @brief Process scan dir.
* @param dir Indicates the dir.
* @param bundleDirs Indicates the return bundleDirs.
* @return
*/
void ProcessScanDir(const std::string &dir, std::list<std::string> &bundleDirs);
/**
* @brief Get bundle dir by pre bundle profile.
* @param scanInfos Indicates the scanInfos contains installed info.
* @param uninstallBundleNames Indicates the uninstall bundleNames.
* @param preBundleConfigInfos Indicates the preBundleConfigInfos.
* @return
*/
void GetBundleDirFromPreBundleProFile(
std::set<PreScanInfo> &scanInfos,
std::set<std::string> &uninstallBundleNames,
std::set<PreBundleConfigInfo> &preBundleConfigInfos);
/**
* @brief Process parse pre bundle profile.
* @param scanInfos Indicates the scanInfos contains installed info.
* @param uninstallBundleNames Indicates the uninstall bundleNames.
* @param preBundleConfigInfos Indicates the preBundleConfigInfos.
* @return
*/
void ParsePreBundleProFile(
std::string dir,
std::set<PreScanInfo> &scanInfos,
std::set<std::string> &uninstallBundleNames,
std::set<PreBundleConfigInfo> &preBundleConfigInfos);
/**
* @brief Set the flag indicates that all system and vendor applications installed.
* @return
*/
void SetAllInstallFlag() const;
/**
* @brief start scan.
* @param userId Indicates the userId.
* @return
*/
void OnStartScanning(int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief start scan.
* @param userId Indicates the userId.
* @return
*/
void RebootStartScanning(int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief Install system and system vendor bundles.
* @param userId Indicates userId.
* @return
*/
void RebootProcessSystemBundle(int32_t userId = Constants::UNSPECIFIED_USERID);
/**
* @brief Get bundleinfo of HAP by path.
* @param hapFilePath Indicates the absolute file path of the HAP.
@ -83,19 +200,6 @@ private:
*/
bool ParseHapFiles(const std::string &hapFilePath,
std::unordered_map<std::string, InnerBundleInfo> &infos);
/**
* @brief Reboot install system and system vendor bundles.
* @param bundleList Indicates store bundle list.
* @param appType Indicates the bundle type.
* @return
*/
void RebootBundleInstall(
const std::list<std::string> &bundleList, Constants::AppType appType);
/**
* @brief Reboot uninstall system and system vendor bundles.
* @return
*/
void RebootBundleUninstall();
/**
* @brief To check the version code and bundleName in all haps.
* @param infos .Indicates all innerBundleInfo for all haps need to be installed.
@ -132,26 +236,11 @@ private:
*/
void AddParseInfosToMap(const std::string &bundleName,
const std::unordered_map<std::string, InnerBundleInfo> &infos);
/**
* @brief Obtains the PreInstallBundleInfo objects.
* @return Returns true if this function is successfully called; returns false otherwise.
*/
bool LoadAllPreInstallBundleInfos();
/**
* @brief Reboot Install system and system vendor bundles.
* @param scanDir Indicates the scanDir.
* @param appType Indicates the bundle type.
* @return
*/
void RebootProcessBundleInstall(
const std::string &scanDir, Constants::AppType appType);
// Used to save the information parsed by Hap in the scanned directory.
std::map<std::string, std::unordered_map<std::string, InnerBundleInfo>> hapParseInfoMap_;
// used to save application information that already exists in the Db.
std::map<std::string, PreInstallBundleInfo> loadExistData_;
std::vector<std::string> scanPaths_;
};
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -16,10 +16,12 @@
#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_PARSER_H
#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_PARSER_H
#include <set>
#include <string>
#include "appexecfwk_errors.h"
#include "inner_bundle_info.h"
#include "pre_scan_info.h"
namespace OHOS {
namespace AppExecFwk {
@ -39,6 +41,30 @@ public:
* @return Returns ERR_OK if the bundle successfully parsed; returns ErrCode otherwise.
*/
ErrCode ParseSysCap(const std::string &pathName, std::vector<std::string> &sysCaps) const;
/**
* @brief Parse scanInfos by the configFile.
* @param configFile Indicates the path of configFile.
* @param scanInfos Indicates the obtained InnerBundleInfo object.
* @return Returns ERR_OK if the bundle successfully parsed; returns ErrCode otherwise.
*/
ErrCode ParsePreInstallConfig(
const std::string &configFile, std::set<PreScanInfo> &scanInfos) const;
/**
* @brief Parse bundleNames by the configFile.
* @param configFile Indicates the path of configFile.
* @param bundleNames Indicates the bundleNames.
* @return Returns ERR_OK if the bundle successfully parsed; returns ErrCode otherwise.
*/
ErrCode ParsePreUnInstallConfig(
const std::string &configFile, std::set<std::string> &bundleNames) const;
/**
* @brief Parse PreBundleConfigInfo by the configFile.
* @param configFile Indicates the path of configFile.
* @param preBundleConfigInfos Indicates the obtained preBundleConfigInfo object.
* @return Returns ERR_OK if the bundle successfully parsed; returns ErrCode otherwise.
*/
ErrCode ParsePreInstallAbilityConfig(
const std::string &configFile, std::set<PreBundleConfigInfo> &preBundleConfigInfos) const;
};
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_BUNDLE_PROFILE_H
#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_BUNDLE_PROFILE_H
#include <set>
#include "appexecfwk_errors.h"
#include "json_util.h"
#include "pre_scan_info.h"
namespace OHOS {
namespace AppExecFwk {
class PreBundleProfile {
public:
/**
* @brief Transform the jsonBuf to scanInfos.
* @param jsonBuf Indicates the jsonBuf.
* @param scanInfos Indicates the scanInfos.
* @return Returns ERR_OK if the information transformed successfully; returns error code otherwise.
*/
ErrCode TransformTo(
const nlohmann::json &jsonBuf, std::set<PreScanInfo> &scanInfos) const;
/**
* @brief Transform the jsonBuf to bundleNames.
* @param jsonBuf Indicates the jsonBuf.
* @param bundleNames Indicates the bundleNames.
* @return Returns ERR_OK if the information transformed successfully; returns error code otherwise.
*/
ErrCode TransformTo(
const nlohmann::json &jsonBuf, std::set<std::string> &bundleNames) const;
/**
* @brief Transform the jsonBuf to preBundleConfigInfos.
* @param jsonBuf Indicates the jsonBuf.
* @param preBundleConfigInfos Indicates the preBundleConfigInfos.
* @return Returns ERR_OK if the information transformed successfully; returns error code otherwise.
*/
ErrCode TransformTo(
const nlohmann::json &jsonBuf, std::set<PreBundleConfigInfo> &preBundleConfigInfos) const;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_BUNDLE_PROFILE_H

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_SCAN_INFO_H
#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_SCAN_INFO_H
#include <string>
namespace OHOS {
namespace AppExecFwk {
namespace {
std::string GetBoolStrVal(bool val)
{
return val ? "true" : "false";
}
}
struct PreBundleConfigInfo {
std::string bundleName;
bool systemapi = false;
bool keepAlive = false;
bool singleton = false;
bool userDataClearable = false;
bool multiProcess = false;
bool bootable = false;
bool notification = false;
bool hideDesktopIcon = false;
bool queryPriority = false;
bool startStaticBroadcast = false;
bool startGuiAbilityBackground = false;
bool operator <(const PreBundleConfigInfo &preBundleConfigInfo) const
{
return bundleName < preBundleConfigInfo.bundleName;
}
void Reset()
{
bundleName.clear();
systemapi = false;
keepAlive = false;
singleton = false;
userDataClearable = false;
multiProcess = false;
bootable = false;
notification = false;
hideDesktopIcon = false;
queryPriority = false;
startStaticBroadcast = false;
startGuiAbilityBackground = false;
}
std::string ToString()
{
return "[ bundleName = " + bundleName + ", systemapi = " + GetBoolStrVal(systemapi)
+ ", singleton = " + GetBoolStrVal(singleton) + "]";
}
};
struct PreScanInfo {
std::string bundleDir;
bool removable = false;
int32_t priority = 0;
bool operator < (const PreScanInfo &preScanInfo) const
{
if (bundleDir == preScanInfo.bundleDir) {
return false;
}
return priority >= preScanInfo.priority;
}
friend bool operator == (const PreScanInfo& oldPreScanInfo, const PreScanInfo& newPreScanInfo)
{
return oldPreScanInfo.bundleDir == newPreScanInfo.bundleDir;
}
void Reset()
{
bundleDir.clear();
removable = false;
priority = 0;
}
std::string ToString()
{
return "[ bundleDir = " + bundleDir + ", removable = " + GetBoolStrVal(removable)
+ ", priority = " + std::to_string(priority) + "]";
}
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_PRE_SCAN_INFO_H

View File

@ -19,6 +19,7 @@
#include "app_log_wrapper.h"
#include "bundle_mgr_service.h"
#include "bundle_parser.h"
#include "bundle_scanner.h"
#ifdef CONFIG_POLOCY_ENABLE
#include "config_policy_utils.h"
@ -30,6 +31,17 @@ namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string APP_SUFFIX = "/app";
const std::string PRODUCT_SUFFIX = "/etc/bundle";
std::string GetScanBundleName(const std::string &str)
{
auto index = str.find_last_of('/');
if (index != std::string::npos) {
return str.substr(index + 1);
}
return "";
}
}
BMSEventHandler::BMSEventHandler(const std::shared_ptr<EventRunner> &runner) : EventHandler(runner)
{
@ -45,7 +57,7 @@ void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer &event)
{
switch (event->GetInnerEventId()) {
case BUNDLE_SCAN_START: {
OnStartScanning(Constants::DEFAULT_USERID);
OnBootStartScanning(Constants::DEFAULT_USERID);
SetAllInstallFlag();
DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
break;
@ -55,7 +67,7 @@ void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer &event)
case BMS_START_FINISHED:
break;
case BUNDLE_REBOOT_SCAN_START: {
RebootStartScanning();
OnRebootStartScanning();
SetAllInstallFlag();
DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
break;
@ -66,13 +78,30 @@ void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer &event)
}
}
void BMSEventHandler::OnStartScanning(int32_t userId)
void BMSEventHandler::OnBootStartScanning(int32_t userId)
{
scanPaths_.clear();
ProcessSystemBundleInstall(
Constants::SYSTEM_APP_SCAN_PATH, Constants::AppType::SYSTEM_APP, userId);
ProcessSystemBundleInstall(
Constants::THIRD_SYSTEM_APP_SCAN_PATH, Constants::AppType::THIRD_SYSTEM_APP, userId);
#ifdef USE_PRE_BUNDLE_PROFILE
ProcessBootBundleInstallFromPreBundleProFile(userId);
#else
ProcessBootBundleInstallFromScan(userId);
#endif
PerfProfile::GetInstance().Dump();
}
void BMSEventHandler::ProcessBootBundleInstallFromScan(int32_t userId)
{
APP_LOGD("Process boot bundle install from scan");
std::list<std::string> bundleDirs;
GetBundleDirFromScan(bundleDirs);
for (auto item : bundleDirs) {
ProcessSystemBundleInstall(item, Constants::AppType::SYSTEM_APP, userId);
}
}
void BMSEventHandler::GetBundleDirFromScan(std::list<std::string> &bundleDirs)
{
ProcessScanDir(Constants::SYSTEM_APP_SCAN_PATH, bundleDirs);
ProcessScanDir(Constants::THIRD_SYSTEM_APP_SCAN_PATH, bundleDirs);
#ifdef CONFIG_POLOCY_ENABLE
auto cfgDirList = GetCfgDirList();
if (cfgDirList == nullptr) {
@ -86,46 +115,140 @@ void BMSEventHandler::OnStartScanning(int32_t userId)
}
APP_LOGD("cfgDir: %{public}s ", cfgDir);
ProcessSystemBundleInstall(
cfgDir + APP_SUFFIX, Constants::AppType::SYSTEM_APP, userId);
ProcessScanDir(cfgDir + APP_SUFFIX, bundleDirs);
}
#endif
auto iter = std::find(bundleDirs.begin(), bundleDirs.end(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
if (iter != bundleDirs.end()) {
bundleDirs.erase(iter);
bundleDirs.insert(bundleDirs.begin(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
} else {
iter = std::find(bundleDirs.begin(), bundleDirs.end(), Constants::SYSTEM_RESOURCES_APP_PATH);
if (iter != bundleDirs.end()) {
bundleDirs.erase(iter);
bundleDirs.insert(bundleDirs.begin(), Constants::SYSTEM_RESOURCES_APP_PATH);
}
}
}
void BMSEventHandler::ProcessSystemBundleInstall(
const std::string &scanDir, Constants::AppType appType, int32_t userId)
void BMSEventHandler::ProcessScanDir(const std::string &dir, std::list<std::string> &bundleDirs)
{
APP_LOGD("scan thread start");
if (std::find(scanPaths_.begin(), scanPaths_.end(), scanDir) != scanPaths_.end()) {
APP_LOGD("scanDir(%{public}s) has scan", scanDir.c_str());
BundleScanner scanner;
std::list<std::string> bundleList = scanner.Scan(dir);
for (auto item : bundleList) {
auto iter = std::find(bundleDirs.begin(), bundleDirs.end(), item);
if (iter == bundleDirs.end()) {
bundleDirs.push_back(item);
}
}
}
void BMSEventHandler::ProcessBootBundleInstallFromPreBundleProFile(int32_t userId)
{
APP_LOGD("Process boot bundle install from pre bundle proFile");
std::set<PreScanInfo> scanInfos;
std::set<std::string> uninstallBundleNames;
std::set<PreBundleConfigInfo> preBundleConfigInfos;
GetBundleDirFromPreBundleProFile(scanInfos, uninstallBundleNames, preBundleConfigInfos);
InnerProcessBootPreBundleProFileInstall(scanInfos, uninstallBundleNames, preBundleConfigInfos, userId);
}
void BMSEventHandler::GetBundleDirFromPreBundleProFile(
std::set<PreScanInfo> &scanInfos,
std::set<std::string> &uninstallBundleNames,
std::set<PreBundleConfigInfo> &preBundleConfigInfos)
{
std::set<std::string> preBundleProFileDirs;
// Product catalog
#ifdef CONFIG_POLOCY_ENABLE
auto cfgDirList = GetCfgDirList();
if (cfgDirList == nullptr) {
APP_LOGD("cfgDirList is empty");
return;
}
APP_LOGD("scanDir: %{public}s and userId: %{public}d", scanDir.c_str(), userId);
scanPaths_.emplace_back(scanDir);
auto scanner = std::make_unique<BundleScanner>();
std::list<std::string> bundleList = scanner->Scan(scanDir);
auto iter = std::find(bundleList.begin(), bundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
if (iter != bundleList.end()) {
bundleList.erase(iter);
bundleList.insert(bundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
} else {
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 (auto cfgDir : cfgDirList->paths) {
if (!cfgDir) {
continue;
}
std::string preBundleProFileDir = cfgDir + PRODUCT_SUFFIX;
APP_LOGD("preBundleProFileDir: %{public}s ", preBundleProFileDir.c_str());
if (preBundleProFileDirs.find(preBundleProFileDir) != preBundleProFileDirs.end()) {
APP_LOGE("preBundleProFileDir(%{public}s) has parsed", preBundleProFileDir.c_str());
continue;
}
preBundleProFileDirs.insert(preBundleProFileDir);
ParsePreBundleProFile(preBundleProFileDir, scanInfos, uninstallBundleNames, preBundleConfigInfos);
}
#endif
// Default catalog
if (preBundleProFileDirs.find(Constants::DEFAULT_PRE_BUNDLE_PROFILE) == preBundleProFileDirs.end()) {
ParsePreBundleProFile(
Constants::DEFAULT_PRE_BUNDLE_PROFILE, scanInfos, uninstallBundleNames, preBundleConfigInfos);
}
}
for (const auto &item : bundleList) {
void BMSEventHandler::ParsePreBundleProFile(
std::string dir,
std::set<PreScanInfo> &scanInfos,
std::set<std::string> &uninstallBundleNames,
std::set<PreBundleConfigInfo> &preBundleConfigInfos)
{
BundleParser bundleParser;
bundleParser.ParsePreInstallConfig(
dir + Constants::PREINSTALL_CONFIG, scanInfos);
bundleParser.ParsePreUnInstallConfig(
dir + Constants::PREINSTALL_UNINSTALL_CONFIG, uninstallBundleNames);
bundleParser.ParsePreInstallAbilityConfig(
dir + Constants::PREINSTALL_ABILITY_CONFIG, preBundleConfigInfos);
}
void BMSEventHandler::InnerProcessBootPreBundleProFileInstall(
const std::set<PreScanInfo> &scanInfos,
const std::set<std::string> &uninstallBundleNames,
const std::set<PreBundleConfigInfo> &preBundleConfigInfos,
int32_t userId)
{
for (auto scanInfo : scanInfos) {
APP_LOGD("Inner process boot preBundle proFile install %{public}s", scanInfo.ToString().c_str());
std::string scanBundleName = GetScanBundleName(scanInfo.bundleDir);
if (uninstallBundleNames.find(scanBundleName) != uninstallBundleNames.end()) {
APP_LOGW("bundle(%{public}s) not allowed installed", scanBundleName.c_str());
continue;
}
PreBundleConfigInfo preBundleConfigInfo;
preBundleConfigInfo.bundleName = scanBundleName;
auto iter = preBundleConfigInfos.find(preBundleConfigInfo);
if (iter != preBundleConfigInfos.end()) {
preBundleConfigInfo = *iter;
}
ProcessSystemBundleInstall(scanInfo, preBundleConfigInfo, userId);
}
}
void BMSEventHandler::ProcessSystemBundleInstall(
const PreScanInfo &preScanInfo, const PreBundleConfigInfo &preBundleConfig, int32_t userId)
{
APP_LOGD("Process system bundle install by preScanInfo(%{public}s)", preScanInfo.bundleDir.c_str());
SystemBundleInstaller installer;
APP_LOGD("scan item %{public}s", item.c_str());
if (!installer.InstallSystemBundle(item, appType, userId)) {
APP_LOGW("Install System app:%{public}s error", item.c_str());
if (!installer.InstallSystemBundle(
preScanInfo.bundleDir, Constants::AppType::SYSTEM_APP, userId)) {
APP_LOGW("Install System app:%{public}s error", preScanInfo.bundleDir.c_str());
}
}
PerfProfile::GetInstance().Dump();
void BMSEventHandler::ProcessSystemBundleInstall(
const std::string &bundleDir, Constants::AppType appType, int32_t userId)
{
APP_LOGD("Process system bundle install by bundleDir(%{public}s)", bundleDir.c_str());
SystemBundleInstaller installer;
if (!installer.InstallSystemBundle(bundleDir, appType, userId)) {
APP_LOGW("Install System app:%{public}s error", bundleDir.c_str());
}
}
void BMSEventHandler::SetAllInstallFlag() const
@ -139,45 +262,21 @@ void BMSEventHandler::SetAllInstallFlag() const
dataMgr->SetInitialUserFlag(true);
}
void BMSEventHandler::RebootStartScanning(int32_t userId)
void BMSEventHandler::OnRebootStartScanning(int32_t userId)
{
scanPaths_.clear();
auto future = std::async(std::launch::async, [this, userId] {
RebootProcessSystemBundle(userId);
});
future.get();
ProcessRebootBundle(userId);
}
void BMSEventHandler::RebootProcessSystemBundle(int32_t userId)
void BMSEventHandler::ProcessRebootBundle(int32_t userId)
{
APP_LOGD("reboot scan thread start");
APP_LOGD("Process reboot bundle start");
if (!LoadAllPreInstallBundleInfos()) {
APP_LOGE("Load all preInstall bundleInfos failed.");
return;
}
RebootProcessBundleInstall(
Constants::SYSTEM_APP_SCAN_PATH, Constants::AppType::SYSTEM_APP);
RebootProcessBundleInstall(
Constants::THIRD_SYSTEM_APP_SCAN_PATH, Constants::AppType::THIRD_SYSTEM_APP);
#ifdef CONFIG_POLOCY_ENABLE
auto cfgDirList = GetCfgDirList();
if (cfgDirList == nullptr) {
APP_LOGD("cfgDirList is empty");
return;
}
for (auto cfgDir : cfgDirList->paths) {
if (!cfgDir) {
continue;
}
APP_LOGD("cfgDir: %{public}s ", cfgDir);
RebootProcessBundleInstall(cfgDir + APP_SUFFIX, Constants::AppType::SYSTEM_APP);
}
#endif
RebootBundleUninstall();
ProcessRebootBundleInstall();
ProcessRebootBundleUninstall();
}
bool BMSEventHandler::LoadAllPreInstallBundleInfos()
@ -197,34 +296,55 @@ bool BMSEventHandler::LoadAllPreInstallBundleInfos()
return true;
}
void BMSEventHandler::RebootProcessBundleInstall(
const std::string &scanDir, Constants::AppType appType)
void BMSEventHandler::ProcessRebootBundleInstall()
{
if (std::find(scanPaths_.begin(), scanPaths_.end(), scanDir) != scanPaths_.end()) {
APP_LOGD("Reboot scanDir(%{public}s) has scan", scanDir.c_str());
return;
APP_LOGD("Process reboot bundle install start");
#ifdef USE_PRE_BUNDLE_PROFILE
ProcessRebootBundleInstallFromPreBundleProFile();
#else
ProcessRebootBundleInstallFromScan();
#endif
}
APP_LOGD("Reboot scanDir: %{public}s", scanDir.c_str());
scanPaths_.emplace_back(scanDir);
auto scanner = std::make_unique<BundleScanner>();
std::list<std::string> bundleList = scanner->Scan(scanDir);
auto iter = std::find(bundleList.begin(), bundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
if (iter != bundleList.end()) {
bundleList.erase(iter);
bundleList.insert(bundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH_NEW);
} else {
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);
}
void BMSEventHandler::ProcessRebootBundleInstallFromPreBundleProFile()
{
APP_LOGD("Process reboot bundle install from pre bundle proFile");
std::set<PreScanInfo> scanInfos;
std::set<std::string> uninstallBundleNames;
std::set<PreBundleConfigInfo> preBundleConfigInfos;
GetBundleDirFromPreBundleProFile(scanInfos, uninstallBundleNames, preBundleConfigInfos);
ProcessReBootPreBundleProFileInstall(scanInfos, uninstallBundleNames, preBundleConfigInfos);
}
RebootBundleInstall(bundleList, appType);
void BMSEventHandler::ProcessReBootPreBundleProFileInstall(
const std::set<PreScanInfo> &scanInfos,
const std::set<std::string> &uninstallBundleNames,
const std::set<PreBundleConfigInfo> &preBundleConfigInfos)
{
std::list<std::string> bundleDirs;
for (auto scanInfo : scanInfos) {
APP_LOGD("Process reboot preBundle proFile install %{public}s", scanInfo.ToString().c_str());
std::string scanBundleName = GetScanBundleName(scanInfo.bundleDir);
if (uninstallBundleNames.find(scanBundleName) != uninstallBundleNames.end()) {
APP_LOGW("bundle(%{public}s) not allowed installed", scanBundleName.c_str());
continue;
}
void BMSEventHandler::RebootBundleInstall(
bundleDirs.push_back(scanInfo.bundleDir);
}
InnerProcessRebootBundleInstall(bundleDirs, Constants::AppType::SYSTEM_APP);
}
void BMSEventHandler::ProcessRebootBundleInstallFromScan()
{
APP_LOGD("Process reboot bundle install from scan");
std::list<std::string> bundleDirs;
GetBundleDirFromScan(bundleDirs);
InnerProcessRebootBundleInstall(bundleDirs, Constants::AppType::SYSTEM_APP);
}
void BMSEventHandler::InnerProcessRebootBundleInstall(
const std::list<std::string> &scanPathList, Constants::AppType appType)
{
auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
@ -234,10 +354,10 @@ void BMSEventHandler::RebootBundleInstall(
}
for (auto &scanPathIter : scanPathList) {
APP_LOGD("reboot scan bundle path: %{private}s ", scanPathIter.c_str());
APP_LOGD("reboot scan bundle path: %{public}s ", scanPathIter.c_str());
std::unordered_map<std::string, InnerBundleInfo> infos;
if (!ParseHapFiles(scanPathIter, infos) || infos.empty()) {
APP_LOGE("obtain bundleinfo failed : %{private}s ", scanPathIter.c_str());
APP_LOGE("obtain bundleinfo failed : %{public}s ", scanPathIter.c_str());
continue;
}
@ -335,7 +455,7 @@ void BMSEventHandler::AddParseInfosToMap(
hapParseInfoMap_.at(bundleName) = iterMap;
}
void BMSEventHandler::RebootBundleUninstall()
void BMSEventHandler::ProcessRebootBundleUninstall()
{
APP_LOGD("Reboot scan and OTA uninstall start");
auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();

View File

@ -15,19 +15,24 @@
#include "bundle_parser.h"
#include <fstream>
#include <sstream>
#include <unistd.h>
#include "app_log_wrapper.h"
#include "bundle_constants.h"
#include "bundle_extractor.h"
#include "bundle_profile.h"
#include "module_profile.h"
#include "pre_bundle_profile.h"
#include "rpcid_decode/syscap_tool.h"
#include "securec.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string INSTALL_ABILITY_CONFIGS = "install_ability_configs";
bool ParseStr(const char *buf, const int itemLen, int totalLen, std::vector<std::string> &sysCaps)
{
APP_LOGD("Parse rpcid output start, itemLen:%{public}d totalLen:%{public}d.", itemLen, totalLen);
@ -50,6 +55,42 @@ bool ParseStr(const char *buf, const int itemLen, int totalLen, std::vector<std:
return true;
}
bool ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf)
{
if (access(filePath.c_str(), F_OK) != 0) {
APP_LOGE("can not access the file: %{public}s", filePath.c_str());
return false;
}
std::fstream in;
char errBuf[256];
errBuf[0] = '\0';
in.open(filePath, std::ios_base::in);
if (!in.is_open()) {
strerror_r(errno, errBuf, sizeof(errBuf));
APP_LOGE("the file cannot be open due to %{public}s", errBuf);
return false;
}
in.seekg(0, std::ios::end);
int64_t size = in.tellg();
if (size <= 0) {
APP_LOGE("the file is an empty file");
in.close();
return false;
}
in.seekg(0, std::ios::beg);
jsonBuf = nlohmann::json::parse(in, nullptr, false);
if (jsonBuf.is_discarded()) {
APP_LOGE("bad profile file");
in.close();
return false;
}
return true;
}
}
ErrCode BundleParser::Parse(const std::string &pathName, InnerBundleInfo &innerBundleInfo) const
{
@ -131,5 +172,47 @@ ErrCode BundleParser::ParseSysCap(const std::string &pathName, std::vector<std::
free(outBuffer);
return ERR_OK;
}
ErrCode BundleParser::ParsePreInstallConfig(
const std::string &configFile, std::set<PreScanInfo> &scanInfos) const
{
APP_LOGD("Parse preInstallConfig from %{public}s", configFile.c_str());
nlohmann::json jsonBuf;
if (!ReadFileIntoJson(configFile, jsonBuf)) {
APP_LOGE("Parse preInstallConfig file failed");
return ERR_APPEXECFWK_PARSE_FILE_FAILED;
}
PreBundleProfile preBundleProfile;
return preBundleProfile.TransformTo(jsonBuf, scanInfos);
}
ErrCode BundleParser::ParsePreUnInstallConfig(
const std::string &configFile, std::set<std::string> &bundleNames) const
{
APP_LOGD("Parse PreUnInstallConfig from %{public}s", configFile.c_str());
nlohmann::json jsonBuf;
if (!ReadFileIntoJson(configFile, jsonBuf)) {
APP_LOGE("Parse preUnInstallConfig file failed");
return ERR_APPEXECFWK_PARSE_FILE_FAILED;
}
PreBundleProfile preBundleProfile;
return preBundleProfile.TransformTo(jsonBuf, bundleNames);
}
ErrCode BundleParser::ParsePreInstallAbilityConfig(
const std::string &configFile, std::set<PreBundleConfigInfo> &preBundleConfigInfos) const
{
APP_LOGD("Parse PreInstallAbilityConfig from %{public}s", configFile.c_str());
nlohmann::json jsonBuf;
if (!ReadFileIntoJson(configFile, jsonBuf)) {
APP_LOGE("Parse preInstallAbilityConfig file failed");
return ERR_APPEXECFWK_PARSE_FILE_FAILED;
}
PreBundleProfile preBundleProfile;
return preBundleProfile.TransformTo(jsonBuf, preBundleConfigInfos);
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,287 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pre_bundle_profile.h"
#include "app_log_wrapper.h"
#include "string_ex.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
const std::string INSTALL_LIST = "install_list";
const std::string UNINSTALL_LIST = "uninstall_list";
const std::string INSTALL_ABILITY_CONFIGS = "install_ability_configs";
const std::string BUNDLE_DIR = "bundle_dir";
const std::string REMOVABLE = "removable";
const std::string PRIORITY = "priority";
const std::string BUNDLE_NAME = "bundleName";
const std::string SYSTEMAPI = "systemapi";
const std::string KEEP_ALIVE = "keepAlive";
const std::string SINGLETON = "singleton";
const std::string USER_DATA_CLEARABLE = "userDataClearable";
const std::string MULTI_PROCESS = "multiProcess";
const std::string BOOTABLE = "bootable";
const std::string NOTIFICATION = "notification";
const std::string HIDE_DESKTOP_ICON = "hideDesktopIcon";
const std::string QUERY_PRIORITY = "queryPriority";
const std::string START_STATIC_BROADCAST = "startStaticBroadcast";
const std::string START_GUI_ABLITY_BACKGROUND = "startGuiAbilityBackground";
}
ErrCode PreBundleProfile::TransformTo(
const nlohmann::json &jsonBuf, std::set<PreScanInfo> &scanInfos) const
{
APP_LOGI("transform jsonBuf to PreScanInfos");
if (jsonBuf.is_discarded()) {
APP_LOGE("profile format error");
return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
}
if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) {
return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
}
auto arrays = jsonBuf.at(INSTALL_LIST);
if (!arrays.is_array() || arrays.empty()) {
APP_LOGE("value is not array");
return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
}
PreScanInfo preScanInfo;
for (const auto &array : arrays) {
if (!array.is_object()) {
APP_LOGE("array is not json object");
return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
}
preScanInfo.Reset();
const auto &jsonObjectEnd = array.end();
int32_t parseResult = ERR_OK;
GetValueIfFindKey<std::string>(array,
jsonObjectEnd,
BUNDLE_DIR,
preScanInfo.bundleDir,
JsonType::STRING,
true,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
REMOVABLE,
preScanInfo.removable,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<int32_t>(array,
jsonObjectEnd,
PRIORITY,
preScanInfo.priority,
JsonType::NUMBER,
false,
parseResult,
ArrayType::NOT_ARRAY);
if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
APP_LOGE("bundleDir must exist, and it is empty here");
continue;
}
if (parseResult != ERR_OK) {
APP_LOGE("parse from json failed");
return parseResult;
}
if (std::find(scanInfos.begin(), scanInfos.end(), preScanInfo) != scanInfos.end()) {
APP_LOGE("preScanInfo(%{public}s) has exit", preScanInfo.ToString().c_str());
continue;
}
scanInfos.insert(preScanInfo);
}
return ERR_OK;
}
ErrCode PreBundleProfile::TransformTo(
const nlohmann::json &jsonBuf, std::set<std::string> &bundleNames) const
{
APP_LOGD("transform jsonBuf to bundleNames");
if (jsonBuf.is_discarded()) {
APP_LOGE("profile format error");
return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
}
const auto &jsonObjectEnd = jsonBuf.end();
int32_t parseResult = ERR_OK;
std::vector<std::string> names;
GetValueIfFindKey<std::vector<std::string>>(jsonBuf,
jsonObjectEnd,
UNINSTALL_LIST,
names,
JsonType::ARRAY,
false,
parseResult,
ArrayType::STRING);
for (auto name : names) {
APP_LOGD("bundleNames %{public}s", name.c_str());
bundleNames.insert(name);
}
return parseResult;
}
ErrCode PreBundleProfile::TransformTo(
const nlohmann::json &jsonBuf, std::set<PreBundleConfigInfo> &preBundleConfigInfos) const
{
APP_LOGI("transform jsonBuf to preBundleConfigInfos");
if (jsonBuf.is_discarded()) {
APP_LOGE("profile format error");
return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
}
if (!jsonBuf.is_array() || jsonBuf.empty()) {
APP_LOGE("value is not array");
return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
}
PreBundleConfigInfo preBundleConfigInfo;
for (const auto &array : jsonBuf) {
if (!array.is_object()) {
APP_LOGE("array is not json object");
return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
}
preBundleConfigInfo.Reset();
const auto &jsonObjectEnd = array.end();
int32_t parseResult = ERR_OK;
GetValueIfFindKey<std::string>(array,
jsonObjectEnd,
BUNDLE_NAME,
preBundleConfigInfo.bundleName,
JsonType::STRING,
true,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
SYSTEMAPI,
preBundleConfigInfo.systemapi,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
KEEP_ALIVE,
preBundleConfigInfo.keepAlive,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
SINGLETON,
preBundleConfigInfo.singleton,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
USER_DATA_CLEARABLE,
preBundleConfigInfo.userDataClearable,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
MULTI_PROCESS,
preBundleConfigInfo.multiProcess,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
BOOTABLE,
preBundleConfigInfo.bootable,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
NOTIFICATION,
preBundleConfigInfo.notification,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
HIDE_DESKTOP_ICON,
preBundleConfigInfo.hideDesktopIcon,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
QUERY_PRIORITY,
preBundleConfigInfo.queryPriority,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
START_STATIC_BROADCAST,
preBundleConfigInfo.startStaticBroadcast,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
GetValueIfFindKey<bool>(array,
jsonObjectEnd,
START_GUI_ABLITY_BACKGROUND,
preBundleConfigInfo.startGuiAbilityBackground,
JsonType::BOOLEAN,
false,
parseResult,
ArrayType::NOT_ARRAY);
if (parseResult == ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP) {
APP_LOGE("bundlename must exist, and it is empty here");
continue;
}
if (parseResult != ERR_OK) {
APP_LOGE("parse from json failed");
return parseResult;
}
if (preBundleConfigInfos.find(preBundleConfigInfo) != preBundleConfigInfos.end()) {
APP_LOGE("preBundleConfigInfo(%{public}s) has exit", preBundleConfigInfo.ToString().c_str());
continue;
}
preBundleConfigInfos.insert(preBundleConfigInfo);
}
return ERR_OK;
}
} // namespace AppExecFwk
} // namespace OHOS