1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "parser_util.h" 17 18#include <fstream> 19#include <unistd.h> 20 21#include "config_policy_utils.h" 22#include "hilog_tag_wrapper.h" 23 24namespace OHOS { 25namespace AbilityRuntime { 26namespace { 27constexpr const char *DEFAULT_PRE_BUNDLE_ROOT_DIR = "/system"; 28constexpr const char *PRODUCT_SUFFIX = "/etc/app"; 29constexpr const char *INSTALL_LIST_CAPABILITY_CONFIG = "/install_list_capability.json"; 30constexpr const char *INSTALL_LIST = "install_list"; 31constexpr const char *BUNDLE_NAME = "bundleName"; 32constexpr const char *KEEP_ALIVE = "keepAlive"; 33constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable"; 34constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList"; 35 36} // namespace 37ParserUtil &ParserUtil::GetInstance() 38{ 39 static ParserUtil instance; 40 return instance; 41} 42 43void ParserUtil::GetResidentProcessRawData(std::vector<std::tuple<std::string, std::string, std::string>> &list) 44{ 45 std::vector<std::string> rootDirList; 46 GetPreInstallRootDirList(rootDirList); 47 48 for (auto &root : rootDirList) { 49 auto fileDir = root.append(PRODUCT_SUFFIX).append(INSTALL_LIST_CAPABILITY_CONFIG); 50 TAG_LOGD(AAFwkTag::ABILITYMGR, "Search file dir : %{public}s", fileDir.c_str()); 51 ParsePreInstallAbilityConfig(fileDir, list); 52 } 53} 54 55void ParserUtil::ParsePreInstallAbilityConfig( 56 const std::string &filePath, std::vector<std::tuple<std::string, std::string, std::string>> &list) 57{ 58 nlohmann::json jsonBuf; 59 if (!ReadFileIntoJson(filePath, jsonBuf)) { 60 return; 61 } 62 63 if (jsonBuf.is_discarded()) { 64 return; 65 } 66 67 FilterInfoFromJson(jsonBuf, list); 68} 69 70bool ParserUtil::FilterInfoFromJson( 71 nlohmann::json &jsonBuf, std::vector<std::tuple<std::string, std::string, std::string>> &list) 72{ 73 if (jsonBuf.is_discarded()) { 74 TAG_LOGE(AAFwkTag::ABILITYMGR, "format error"); 75 return false; 76 } 77 78 if (jsonBuf.find(INSTALL_LIST) == jsonBuf.end()) { 79 TAG_LOGE(AAFwkTag::ABILITYMGR, "installList absent"); 80 return false; 81 } 82 83 auto arrays = jsonBuf.at(INSTALL_LIST); 84 if (!arrays.is_array() || arrays.empty()) { 85 TAG_LOGE(AAFwkTag::ABILITYMGR, "not found"); 86 return false; 87 } 88 89 std::string bundleName; 90 std::string KeepAliveEnable = "1"; 91 std::string KeepAliveConfiguredList; 92 for (const auto &array : arrays) { 93 if (!array.is_object()) { 94 continue; 95 } 96 97 // Judgment logic exists, not found, not bool, not resident process 98 if (!(array.find(KEEP_ALIVE) != array.end() && array.at(KEEP_ALIVE).is_boolean() && 99 array.at(KEEP_ALIVE).get<bool>())) { 100 continue; 101 } 102 103 if (!(array.find(BUNDLE_NAME) != array.end() && array.at(BUNDLE_NAME).is_string())) { 104 continue; 105 } 106 107 bundleName = array.at(BUNDLE_NAME).get<std::string>(); 108 109 if (array.find(KEEP_ALIVE_ENABLE) != array.end() && array.at(KEEP_ALIVE_ENABLE).is_boolean()) { 110 auto val = array.at(KEEP_ALIVE_ENABLE).get<bool>(); 111 KeepAliveEnable = std::to_string(val); 112 } 113 114 if (array.find(KEEP_ALIVE_CONFIGURED_LIST) != array.end() && array.at(KEEP_ALIVE_CONFIGURED_LIST).is_array()) { 115 // Save directly in the form of an array and parse it when in use 116 KeepAliveConfiguredList = array.at(KEEP_ALIVE_CONFIGURED_LIST).dump(); 117 } 118 119 list.emplace_back(std::make_tuple(bundleName, KeepAliveEnable, KeepAliveConfiguredList)); 120 bundleName.clear(); 121 KeepAliveEnable = "1"; 122 KeepAliveConfiguredList.clear(); 123 } 124 125 return true; 126} 127 128void ParserUtil::GetPreInstallRootDirList(std::vector<std::string> &rootDirList) 129{ 130 auto cfgDirList = GetCfgDirList(); 131 if (cfgDirList != nullptr) { 132 for (const auto &cfgDir : cfgDirList->paths) { 133 if (cfgDir == nullptr) { 134 continue; 135 } 136 rootDirList.emplace_back(cfgDir); 137 } 138 139 FreeCfgDirList(cfgDirList); 140 } 141 bool ret = std::find(rootDirList.begin(), rootDirList.end(), DEFAULT_PRE_BUNDLE_ROOT_DIR) != rootDirList.end(); 142 if (!ret) { 143 rootDirList.emplace_back(DEFAULT_PRE_BUNDLE_ROOT_DIR); 144 } 145} 146 147bool ParserUtil::ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf) 148{ 149 if (access(filePath.c_str(), F_OK) != 0) { 150 TAG_LOGE(AAFwkTag::ABILITYMGR, "path not exist"); 151 return false; 152 } 153 154 if (filePath.empty()) { 155 TAG_LOGE(AAFwkTag::ABILITYMGR, "empty path"); 156 return false; 157 } 158 159 char path[PATH_MAX] = {0}; 160 if (realpath(filePath.c_str(), path) == nullptr) { 161 TAG_LOGE(AAFwkTag::ABILITYMGR, "realpath error:%{public}d", errno); 162 return false; 163 } 164 165 std::ifstream fin(path); 166 if (!fin.is_open()) { 167 TAG_LOGE(AAFwkTag::ABILITYMGR, "path exception"); 168 return false; 169 } 170 171 fin.seekg(0, std::ios::end); 172 int64_t size = fin.tellg(); 173 if (size <= 0) { 174 TAG_LOGE(AAFwkTag::ABILITYMGR, "empty file"); 175 fin.close(); 176 return false; 177 } 178 179 fin.seekg(0, std::ios::beg); 180 jsonBuf = nlohmann::json::parse(fin, nullptr, false); 181 fin.close(); 182 if (jsonBuf.is_discarded()) { 183 TAG_LOGE(AAFwkTag::ABILITYMGR, "bad profile"); 184 return false; 185 } 186 return true; 187} 188} // namespace AbilityRuntime 189} // namespace OHOS