1 /*
2 * Copyright (c) 2023 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 #define LOG_TAG "CustomUtdInstaller"
16
17 #include <regex>
18 #include <sstream>
19 #include <vector>
20
21 #include "error_code.h"
22 #include "log_print.h"
23 #include "if_system_ability_manager.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "utd_graph.h"
27 #include "custom_utd_json_parser.h"
28 #include "custom_utd_store.h"
29 #include "preset_type_descriptors.h"
30 #include "custom_utd_installer.h"
31
32 namespace OHOS {
33 namespace UDMF {
34 constexpr const char *CUSTOM_UTD_PATH = "/data/service/el1/";
35 constexpr const char *CUSTOM_UTD_FILE = "/distributeddata/utd/utd-adt.json";
CustomUtdInstaller()36 CustomUtdInstaller::CustomUtdInstaller()
37 {
38 }
39
~CustomUtdInstaller()40 CustomUtdInstaller::~CustomUtdInstaller()
41 {
42 }
43
GetInstance()44 CustomUtdInstaller &CustomUtdInstaller::GetInstance()
45 {
46 static CustomUtdInstaller instance;
47 return instance;
48 }
49
GetBundleManager()50 sptr<AppExecFwk::IBundleMgr> CustomUtdInstaller::GetBundleManager()
51 {
52 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53 if (samgrProxy == nullptr) {
54 ZLOGE("samgrProxy is null.");
55 return nullptr;
56 }
57 auto bmsProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
58 if (bmsProxy == nullptr) {
59 ZLOGE("failed to get bms from samgrProxy.");
60 return nullptr;
61 }
62 return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy);
63 }
64
InstallUtd(const std::string & bundleName,int32_t user)65 int32_t CustomUtdInstaller::InstallUtd(const std::string &bundleName, int32_t user)
66 {
67 std::string path = CUSTOM_UTD_PATH + std::to_string(user) + CUSTOM_UTD_FILE;
68 std::vector<TypeDescriptorCfg> customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(path);
69 std::vector <TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes();
70 std::vector <std::string> modules = GetHapModules(bundleName, user);
71 bool isSucc = true;
72 for (std::string module : modules) {
73 auto utdTypes = GetModuleCustomUtdTypes(bundleName, module, user);
74 if (utdTypes.first.empty() && utdTypes.second.empty()) {
75 ZLOGD("Module custom utd types is empty.");
76 continue;
77 }
78 if (!UtdCfgsChecker::GetInstance().CheckTypeDescriptors(utdTypes, presetTypes, customTyepCfgs, bundleName)) {
79 ZLOGE("Parse json failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(),
80 bundleName.c_str());
81 isSucc = false;
82 continue;
83 }
84 if (SaveCustomUtds(utdTypes, customTyepCfgs, bundleName, path) != E_OK) {
85 ZLOGE("Install save custom utds failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(),
86 bundleName.c_str());
87 isSucc = false;
88 continue;
89 }
90 }
91 if (!isSucc) {
92 return E_ERROR;
93 }
94 return E_OK;
95 }
96
UninstallUtd(const std::string & bundleName,int32_t user)97 int32_t CustomUtdInstaller::UninstallUtd(const std::string &bundleName, int32_t user)
98 {
99 std::string path = CUSTOM_UTD_PATH + std::to_string(user) + CUSTOM_UTD_FILE;
100 std::vector<TypeDescriptorCfg> customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(path);
101 std::vector<TypeDescriptorCfg> deletionMock;
102 if (!customTyepCfgs.empty()) {
103 deletionMock.insert(deletionMock.end(), customTyepCfgs.begin(), customTyepCfgs.end());
104 }
105 for (auto iter = deletionMock.begin(); iter != deletionMock.end();) {
106 auto it = find (iter->installerBundles.begin(), iter->installerBundles.end(), bundleName);
107 if (it != iter->installerBundles.end()) {
108 iter->installerBundles.erase(it);
109 }
110 if (iter->installerBundles.empty()) {
111 iter = deletionMock.erase(iter);
112 } else {
113 iter++;
114 }
115 }
116 std::vector <TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes();
117 if (!UtdCfgsChecker::GetInstance().CheckBelongingToTypes(deletionMock, presetTypes)) {
118 ZLOGW("Uninstall error, because of belongingToTypes check failed.");
119 return E_ERROR;
120 }
121 for (auto customIter = customTyepCfgs.begin(); customIter != customTyepCfgs.end();) {
122 auto InstallerIter = find (customIter->installerBundles.begin(), customIter->installerBundles.end(),
123 bundleName);
124 if (InstallerIter != customIter->installerBundles.end()) {
125 customIter->installerBundles.erase(InstallerIter);
126 }
127 if (customIter->installerBundles.empty()) {
128 customIter = customTyepCfgs.erase(customIter);
129 } else {
130 customIter++;
131 }
132 }
133 if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) {
134 ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str());
135 return E_ERROR;
136 }
137 return E_OK;
138 }
139
GetHapModules(const std::string & bundleName,int32_t user)140 std::vector<std::string> CustomUtdInstaller::GetHapModules(const std::string &bundleName, int32_t user)
141 {
142 auto bundlemgr = GetBundleManager();
143 if (bundlemgr == nullptr) {
144 ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str());
145 return {};
146 }
147 AppExecFwk::BundleInfo bundleInfo;
148 if (!bundlemgr->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, user)) {
149 ZLOGE("Get local bundle info failed, bundleName: %{public}s.", bundleName.c_str());
150 }
151 return bundleInfo.hapModuleNames;
152 }
153
GetModuleCustomUtdTypes(const std::string & bundleName,const std::string & moduleName,int32_t user)154 CustomUtdCfgs CustomUtdInstaller::GetModuleCustomUtdTypes(const std::string &bundleName,
155 const std::string &moduleName, int32_t user)
156 {
157 auto bundlemgr = GetBundleManager();
158 std::string jsonStr;
159 CustomUtdCfgs typeCfgs;
160 if (bundlemgr == nullptr) {
161 ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str());
162 return typeCfgs;
163 }
164 auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, moduleName, jsonStr,
165 user);
166 if (status != NO_ERROR) {
167 ZLOGD("get json profile failed, bundleName: %{public}s.", bundleName.c_str());
168 return typeCfgs;
169 }
170 if (jsonStr.empty()) {
171 ZLOGE("JsonStr is empty, bundleName: %{public}s.", bundleName.c_str());
172 return typeCfgs;
173 }
174 std::vector<TypeDescriptorCfg> declarationType;
175 std::vector<TypeDescriptorCfg> referenceType;
176
177 CustomUtdJsonParser customUtdJsonParser_;
178 bool res = customUtdJsonParser_.ParseUserCustomUtdJson(jsonStr, declarationType, referenceType);
179 if (!jsonStr.empty() && res) {
180 typeCfgs.first = declarationType;
181 typeCfgs.second = referenceType;
182 }
183 return typeCfgs;
184 }
185
SaveCustomUtds(const CustomUtdCfgs & utdTypes,std::vector<TypeDescriptorCfg> customTyepCfgs,const std::string & bundleName,const std::string & path)186 int32_t CustomUtdInstaller::SaveCustomUtds(const CustomUtdCfgs &utdTypes, std::vector<TypeDescriptorCfg> customTyepCfgs,
187 const std::string &bundleName, const std::string &path)
188 {
189 for (TypeDescriptorCfg declarationType : utdTypes.first) {
190 for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) {
191 if (iter->typeId == declarationType.typeId) {
192 declarationType.installerBundles = iter->installerBundles;
193 iter = customTyepCfgs.erase(iter);
194 } else {
195 iter ++;
196 }
197 }
198 declarationType.installerBundles.emplace(bundleName);
199 declarationType.ownerBundle = bundleName;
200 customTyepCfgs.push_back(declarationType);
201 }
202 for (TypeDescriptorCfg referenceType : utdTypes.second) {
203 bool found = false;
204 for (auto &typeCfg : customTyepCfgs) {
205 if (typeCfg.typeId == referenceType.typeId) {
206 typeCfg.installerBundles.emplace(bundleName);
207 found = true;
208 break;
209 }
210 }
211 if (!found) {
212 referenceType.installerBundles.emplace(bundleName);
213 customTyepCfgs.push_back(referenceType);
214 }
215 }
216 if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) {
217 ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str());
218 return E_ERROR;
219 }
220 return E_OK;
221 }
222 }
223 }