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 "extend_resource_manager_host_impl.h"
17 
18 #include "account_helper.h"
19 #include "bundle_mgr_service.h"
20 #include "bundle_parser.h"
21 #include "bundle_permission_mgr.h"
22 #ifdef BUNDLE_FRAMEWORK_BUNDLE_RESOURCE
23 #include "bundle_resource/bundle_resource_manager.h"
24 #include "bundle_resource/bundle_resource_parser.h"
25 #include "bundle_resource/resource_info.h"
26 #endif
27 #include "installd_client.h"
28 
29 namespace OHOS {
30 namespace AppExecFwk {
31 namespace {
32 const std::string SEPARATOR = "/";
33 constexpr const char* EXT_RESOURCE_FILE_SUFFIX = ".hsp";
34 
IsFileNameValid(const std::string & fileName)35 bool IsFileNameValid(const std::string &fileName)
36 {
37     if (fileName.find("..") != std::string::npos
38         || fileName.find("/") != std::string::npos
39         || fileName.find("\\") != std::string::npos
40         || fileName.find("%") != std::string::npos) {
41         return false;
42     }
43     return true;
44 }
45 
IsValidPath(const std::string & path)46 bool IsValidPath(const std::string &path)
47 {
48     if (path.find("..") != std::string::npos) {
49         return false;
50     }
51     return true;
52 }
53 
GetFileName(const std::string & sourcePath)54 std::string GetFileName(const std::string &sourcePath)
55 {
56     size_t pos = sourcePath.find_last_of(SEPARATOR);
57     if (pos == std::string::npos) {
58         APP_LOGE("invalid sourcePath %{public}s", sourcePath.c_str());
59         return sourcePath;
60     }
61     return sourcePath.substr(pos + 1);
62 }
63 
BuildResourcePath(const std::string & bundleName)64 std::string BuildResourcePath(const std::string &bundleName)
65 {
66     std::string filePath;
67     filePath.append(Constants::BUNDLE_CODE_DIR).append(ServiceConstants::PATH_SEPARATOR)
68         .append(bundleName).append(ServiceConstants::PATH_SEPARATOR)
69         .append(ServiceConstants::EXT_RESOURCE_FILE_PATH).append(ServiceConstants::PATH_SEPARATOR);
70     return filePath;
71 }
72 
ConvertToExtendResourceInfo(const std::string & bundleName,const InnerBundleInfo & innerBundleInfo,ExtendResourceInfo & extendResourceInfo)73 void ConvertToExtendResourceInfo(
74     const std::string &bundleName,
75     const InnerBundleInfo &innerBundleInfo,
76     ExtendResourceInfo &extendResourceInfo)
77 {
78     extendResourceInfo.moduleName = innerBundleInfo.GetCurModuleName();
79     extendResourceInfo.iconId = innerBundleInfo.GetIconId();
80     std::string path = BuildResourcePath(bundleName);
81     path.append(extendResourceInfo.moduleName).append(EXT_RESOURCE_FILE_SUFFIX);
82     extendResourceInfo.filePath = path;
83 }
84 }
ExtendResourceManagerHostImpl()85 ExtendResourceManagerHostImpl::ExtendResourceManagerHostImpl()
86 {
87     APP_LOGI("create ExtendResourceManagerHostImpl");
88 }
89 
~ExtendResourceManagerHostImpl()90 ExtendResourceManagerHostImpl::~ExtendResourceManagerHostImpl()
91 {
92     APP_LOGI("destroy ExtendResourceManagerHostImpl");
93 }
94 
AddExtResource(const std::string & bundleName,const std::vector<std::string> & filePaths)95 ErrCode ExtendResourceManagerHostImpl::AddExtResource(
96     const std::string &bundleName, const std::vector<std::string> &filePaths)
97 {
98     ErrCode ret = BeforeAddExtResource(bundleName, filePaths);
99     CHECK_RESULT(ret, "BeforeAddExtResource failed %{public}d");
100     ret = ProcessAddExtResource(bundleName, filePaths);
101     CHECK_RESULT(ret, "InnerEnableDynamicIcon failed %{public}d");
102     return ERR_OK;
103 }
104 
BeforeAddExtResource(const std::string & bundleName,const std::vector<std::string> & filePaths)105 ErrCode ExtendResourceManagerHostImpl::BeforeAddExtResource(
106     const std::string &bundleName, const std::vector<std::string> &filePaths)
107 {
108     if (bundleName.empty()) {
109         APP_LOGE("fail to AddExtResource due to bundleName is empty");
110         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
111     }
112 
113     if (filePaths.empty()) {
114         APP_LOGE("fail to AddExtResource due to filePaths is empty");
115         return ERR_EXT_RESOURCE_MANAGER_INVALID_PATH_FAILED;
116     }
117 
118     if (!BundlePermissionMgr::IsSystemApp()) {
119         APP_LOGE("Non-system app calling system api");
120         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
121     }
122 
123     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(
124         Constants::PERMISSION_INSTALL_BUNDLE)) {
125         APP_LOGE("verify permission failed");
126         return ERR_APPEXECFWK_PERMISSION_DENIED;
127     }
128 
129     for (const auto &filePath: filePaths) {
130         if (!CheckFileParam(filePath)) {
131             APP_LOGE("CheckFile failed");
132             return ERR_EXT_RESOURCE_MANAGER_INVALID_PATH_FAILED;
133         }
134     }
135 
136     return ERR_OK;
137 }
138 
CheckFileParam(const std::string & filePath)139 bool ExtendResourceManagerHostImpl::CheckFileParam(const std::string &filePath)
140 {
141     if (!IsValidPath(filePath)) {
142         APP_LOGE("CheckFile filePath(%{public}s) failed due to invalid path", filePath.c_str());
143         return false;
144     }
145     if (!BundleUtil::CheckFileType(filePath, EXT_RESOURCE_FILE_SUFFIX)) {
146         APP_LOGE("CheckFile filePath(%{public}s) failed due to suffix error", filePath.c_str());
147         return false;
148     }
149     if (!BundleUtil::StartWith(filePath, ServiceConstants::HAP_COPY_PATH)) {
150         APP_LOGE("CheckFile filePath(%{public}s) failed due to prefix error", filePath.c_str());
151         return false;
152     }
153     return true;
154 }
155 
ProcessAddExtResource(const std::string & bundleName,const std::vector<std::string> & filePaths)156 ErrCode ExtendResourceManagerHostImpl::ProcessAddExtResource(
157     const std::string &bundleName, const std::vector<std::string> &filePaths)
158 {
159     InnerBundleInfo info;
160     if (!GetInnerBundleInfo(bundleName, info)) {
161         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
162         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
163     }
164 
165     std::vector<std::string> newFilePaths;
166     ErrCode ret = CopyToTempDir(bundleName, filePaths, newFilePaths);
167     CHECK_RESULT(ret, "CopyToTempDir failed %{public}d");
168 
169     std::vector<ExtendResourceInfo> extendResourceInfos;
170     if (ParseExtendResourceFile(bundleName, newFilePaths, extendResourceInfos) != ERR_OK) {
171         APP_LOGE("parse %{public}s extendResource failed", bundleName.c_str());
172         RollBack(newFilePaths);
173         return ERR_EXT_RESOURCE_MANAGER_PARSE_FILE_FAILED;
174     }
175 
176     InnerSaveExtendResourceInfo(bundleName, newFilePaths, extendResourceInfos);
177     return ERR_OK;
178 }
179 
InnerSaveExtendResourceInfo(const std::string & bundleName,const std::vector<std::string> & filePaths,const std::vector<ExtendResourceInfo> & extendResourceInfos)180 void ExtendResourceManagerHostImpl::InnerSaveExtendResourceInfo(
181     const std::string &bundleName,
182     const std::vector<std::string> &filePaths,
183     const std::vector<ExtendResourceInfo> &extendResourceInfos)
184 {
185     ErrCode ret = ERR_OK;
186     std::vector<ExtendResourceInfo> newExtendResourceInfos;
187     for (uint32_t i = 0; i < filePaths.size(); ++i) {
188         ret = InstalldClient::GetInstance()->MoveFile(
189             filePaths[i], extendResourceInfos[i].filePath);
190         if (ret != ERR_OK) {
191             APP_LOGW("MoveFile %{public}s file failed %{public}d",
192                 extendResourceInfos[i].moduleName.c_str(), ret);
193             continue;
194         }
195 
196         newExtendResourceInfos.emplace_back(extendResourceInfos[i]);
197     }
198     UpateExtResourcesDb(bundleName, newExtendResourceInfos);
199 }
200 
ParseExtendResourceFile(const std::string & bundleName,const std::vector<std::string> & filePaths,std::vector<ExtendResourceInfo> & extendResourceInfos)201 ErrCode ExtendResourceManagerHostImpl::ParseExtendResourceFile(
202     const std::string &bundleName,
203     const std::vector<std::string> &filePaths,
204     std::vector<ExtendResourceInfo> &extendResourceInfos)
205 {
206     BundleInstallChecker bundleChecker;
207     std::vector<Security::Verify::HapVerifyResult> hapVerifyRes;
208     ErrCode ret = bundleChecker.CheckMultipleHapsSignInfo(filePaths, hapVerifyRes);
209     CHECK_RESULT(ret, "Check sign failed %{public}d");
210 
211     for (uint32_t i = 0; i < filePaths.size(); ++i) {
212         BundleParser bundleParser;
213         InnerBundleInfo innerBundleInfo;
214         ErrCode result = bundleParser.Parse(filePaths[i], innerBundleInfo);
215         if (result != ERR_OK) {
216             APP_LOGE("parse bundle info %{public}s failed, err %{public}d",
217                 filePaths[i].c_str(), result);
218             return result;
219         }
220 
221         ExtendResourceInfo extendResourceInfo;
222         ConvertToExtendResourceInfo(bundleName, innerBundleInfo, extendResourceInfo);
223         extendResourceInfos.emplace_back(extendResourceInfo);
224     }
225 
226     return ERR_OK;
227 }
228 
MkdirIfNotExist(const std::string & dir)229 ErrCode ExtendResourceManagerHostImpl::MkdirIfNotExist(const std::string &dir)
230 {
231     bool isDirExist = false;
232     ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
233     if (result != ERR_OK) {
234         APP_LOGE("Check if dir exist failed %{public}d", result);
235         return result;
236     }
237     if (!isDirExist) {
238         result = InstalldClient::GetInstance()->CreateBundleDir(dir);
239         if (result != ERR_OK) {
240             APP_LOGE("Create dir failed %{public}d", result);
241             return result;
242         }
243     }
244     return result;
245 }
246 
CopyToTempDir(const std::string & bundleName,const std::vector<std::string> & oldFilePaths,std::vector<std::string> & newFilePaths)247 ErrCode ExtendResourceManagerHostImpl::CopyToTempDir(const std::string &bundleName,
248     const std::vector<std::string> &oldFilePaths, std::vector<std::string> &newFilePaths)
249 {
250     for (const auto &oldFile : oldFilePaths) {
251         std::string tempFile = BuildResourcePath(bundleName);
252         ErrCode ret = MkdirIfNotExist(tempFile);
253         if (ret != ERR_OK) {
254             APP_LOGE("mkdir fileDir %{public}s failed %{public}d", tempFile.c_str(), ret);
255             RollBack(newFilePaths);
256             return ret;
257         }
258         tempFile.append(GetFileName(oldFile));
259         ret = InstalldClient::GetInstance()->MoveFile(oldFile, tempFile);
260         if (ret != ERR_OK) {
261             APP_LOGE("MoveFile file %{public}s failed %{public}d", tempFile.c_str(), ret);
262             RollBack(newFilePaths);
263             return ret;
264         }
265         newFilePaths.emplace_back(tempFile);
266     }
267     return ERR_OK;
268 }
269 
GetInnerBundleInfo(const std::string & bundleName,InnerBundleInfo & info)270 bool ExtendResourceManagerHostImpl::GetInnerBundleInfo(
271     const std::string &bundleName, InnerBundleInfo &info)
272 {
273     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
274     if (dataMgr == nullptr) {
275         APP_LOGE("Get dataMgr shared_ptr nullptr");
276         return false;
277     }
278     return dataMgr->FetchInnerBundleInfo(bundleName, info);
279 }
280 
UpateExtResourcesDb(const std::string & bundleName,const std::vector<ExtendResourceInfo> & extendResourceInfos)281 bool ExtendResourceManagerHostImpl::UpateExtResourcesDb(const std::string &bundleName,
282     const std::vector<ExtendResourceInfo> &extendResourceInfos)
283 {
284     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
285     if (dataMgr == nullptr) {
286         APP_LOGE("Get dataMgr shared_ptr nullptr");
287         return false;
288     }
289     return dataMgr->UpateExtResources(bundleName, extendResourceInfos);
290 }
291 
RemoveExtResourcesDb(const std::string & bundleName,const std::vector<std::string> & moduleNames)292 bool ExtendResourceManagerHostImpl::RemoveExtResourcesDb(const std::string &bundleName,
293     const std::vector<std::string> &moduleNames)
294 {
295     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
296     if (dataMgr == nullptr) {
297         APP_LOGE("Get dataMgr shared_ptr nullptr");
298         return false;
299     }
300     return dataMgr->RemoveExtResources(bundleName, moduleNames);
301 }
302 
RollBack(const std::vector<std::string> & filePaths)303 void ExtendResourceManagerHostImpl::RollBack(const std::vector<std::string> &filePaths)
304 {
305     for (const auto &filePath : filePaths) {
306         ErrCode result = InstalldClient::GetInstance()->RemoveDir(filePath);
307         if (result != ERR_OK) {
308             APP_LOGE("Remove failed %{public}s", filePath.c_str());
309         }
310     }
311 }
312 
RemoveExtResource(const std::string & bundleName,const std::vector<std::string> & moduleNames)313 ErrCode ExtendResourceManagerHostImpl::RemoveExtResource(
314     const std::string &bundleName, const std::vector<std::string> &moduleNames)
315 {
316     if (bundleName.empty()) {
317         APP_LOGE("fail to RemoveExtResource due to bundleName is empty");
318         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
319     }
320 
321     if (moduleNames.empty()) {
322         APP_LOGE("fail to RemoveExtResource due to moduleName is empty");
323         return ERR_EXT_RESOURCE_MANAGER_REMOVE_EXT_RESOURCE_FAILED;
324     }
325 
326     if (!BundlePermissionMgr::IsSystemApp()) {
327         APP_LOGE("Non-system app calling system api");
328         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
329     }
330 
331     if (!BundlePermissionMgr::VerifyCallingPermissionsForAll({
332         Constants::PERMISSION_INSTALL_BUNDLE, ServiceConstants::PERMISSION_UNINSTALL_BUNDLE})) {
333         APP_LOGE("verify permission failed");
334         return ERR_APPEXECFWK_PERMISSION_DENIED;
335     }
336 
337     std::vector<ExtendResourceInfo> extendResourceInfos;
338     ErrCode ret = CheckModuleExist(bundleName, moduleNames, extendResourceInfos);
339     CHECK_RESULT(ret, "Check mpdule exist failed %{public}d");
340     InnerRemoveExtendResources(bundleName, moduleNames, extendResourceInfos);
341     return ERR_OK;
342 }
343 
InnerRemoveExtendResources(const std::string & bundleName,const std::vector<std::string> & moduleNames,std::vector<ExtendResourceInfo> & extResourceInfos)344 void ExtendResourceManagerHostImpl::InnerRemoveExtendResources(
345     const std::string &bundleName, const std::vector<std::string> &moduleNames,
346     std::vector<ExtendResourceInfo> &extResourceInfos)
347 {
348     for (const auto &extResourceInfo : extResourceInfos) {
349         ErrCode result = InstalldClient::GetInstance()->RemoveDir(extResourceInfo.filePath);
350         if (result != ERR_OK) {
351             APP_LOGE("Remove failed %{public}s", extResourceInfo.filePath.c_str());
352         }
353     }
354     RemoveExtResourcesDb(bundleName, moduleNames);
355 }
356 
CheckModuleExist(const std::string & bundleName,const std::vector<std::string> & moduleNames,std::vector<ExtendResourceInfo> & collectorExtResourceInfos)357 ErrCode ExtendResourceManagerHostImpl::CheckModuleExist(
358     const std::string &bundleName, const std::vector<std::string> &moduleNames,
359     std::vector<ExtendResourceInfo> &collectorExtResourceInfos)
360 {
361     InnerBundleInfo info;
362     if (!GetInnerBundleInfo(bundleName, info)) {
363         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
364         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
365     }
366 
367     std::map<std::string, ExtendResourceInfo> extendResourceInfos = info.GetExtendResourceInfos();
368     for (const auto &moduleName : moduleNames) {
369         auto iter = extendResourceInfos.find(moduleName);
370         if (iter == extendResourceInfos.end()) {
371             APP_LOGE("Module not exist %{public}s", moduleName.c_str());
372             return ERR_EXT_RESOURCE_MANAGER_REMOVE_EXT_RESOURCE_FAILED;
373         }
374 
375         collectorExtResourceInfos.emplace_back(iter->second);
376     }
377     return ERR_OK;
378 }
379 
GetExtResource(const std::string & bundleName,std::vector<std::string> & moduleNames)380 ErrCode ExtendResourceManagerHostImpl::GetExtResource(
381     const std::string &bundleName, std::vector<std::string> &moduleNames)
382 {
383     if (bundleName.empty()) {
384         APP_LOGE("fail to GetExtResource due to param is empty");
385         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
386     }
387 
388     if (!BundlePermissionMgr::IsSystemApp()) {
389         APP_LOGE("Non-system app calling system api");
390         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
391     }
392 
393     if (!BundlePermissionMgr::VerifyCallingPermissionsForAll({
394         Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED, Constants::PERMISSION_GET_BUNDLE_INFO})) {
395         APP_LOGE("verify permission failed");
396         return ERR_APPEXECFWK_PERMISSION_DENIED;
397     }
398 
399     InnerBundleInfo info;
400     if (!GetInnerBundleInfo(bundleName, info)) {
401         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
402         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
403     }
404 
405     std::map<std::string, ExtendResourceInfo> extendResourceInfos = info.GetExtendResourceInfos();
406     if (extendResourceInfos.empty()) {
407         APP_LOGE("%{public}s no extend Resources", bundleName.c_str());
408         return ERR_EXT_RESOURCE_MANAGER_GET_EXT_RESOURCE_FAILED;
409     }
410 
411     for (const auto &extendResourceInfo : extendResourceInfos) {
412         moduleNames.emplace_back(extendResourceInfo.first);
413     }
414 
415     return ERR_OK;
416 }
417 
EnableDynamicIcon(const std::string & bundleName,const std::string & moduleName)418 ErrCode ExtendResourceManagerHostImpl::EnableDynamicIcon(
419     const std::string &bundleName, const std::string &moduleName)
420 {
421     APP_LOGI("EnableDynamicIcon %{public}s, %{public}s",
422         bundleName.c_str(), moduleName.c_str());
423     if (bundleName.empty()) {
424         APP_LOGE("fail to EnableDynamicIcon due to bundleName is empty");
425         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
426     }
427 
428     if (moduleName.empty()) {
429         APP_LOGE("fail to EnableDynamicIcon due to moduleName is empty");
430         return ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST;
431     }
432 
433     if (!BundlePermissionMgr::IsSystemApp()) {
434         APP_LOGE("Non-system app calling system api");
435         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
436     }
437 
438     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(
439         Constants::PERMISSION_ACCESS_DYNAMIC_ICON)) {
440         APP_LOGE("verify permission failed");
441         return ERR_APPEXECFWK_PERMISSION_DENIED;
442     }
443 
444     ExtendResourceInfo extendResourceInfo;
445     ErrCode ret = GetExtendResourceInfo(bundleName, moduleName, extendResourceInfo);
446     CHECK_RESULT(ret, "GetExtendResourceInfo failed %{public}d");
447     if (!ParseBundleResource(bundleName, extendResourceInfo)) {
448         APP_LOGE("%{public}s no extend Resources", bundleName.c_str());
449         return ERR_EXT_RESOURCE_MANAGER_ENABLE_DYNAMIC_ICON_FAILED;
450     }
451 
452     SaveCurDynamicIcon(bundleName, moduleName);
453     SendBroadcast(bundleName, true);
454     return ERR_OK;
455 }
456 
SaveCurDynamicIcon(const std::string & bundleName,const std::string & moduleName)457 void ExtendResourceManagerHostImpl::SaveCurDynamicIcon(
458     const std::string &bundleName, const std::string &moduleName)
459 {
460     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
461     if (dataMgr == nullptr) {
462         APP_LOGE("Get dataMgr shared_ptr nullptr");
463         return;
464     }
465 
466     dataMgr->UpateCurDynamicIconModule(bundleName, moduleName);
467 }
468 
SendBroadcast(const std::string & bundleName,bool isEnableDynamicIcon)469 void ExtendResourceManagerHostImpl::SendBroadcast(
470     const std::string &bundleName, bool isEnableDynamicIcon)
471 {
472     std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
473     commonEventMgr->NotifyDynamicIconEvent(bundleName, isEnableDynamicIcon);
474 }
475 
ParseBundleResource(const std::string & bundleName,const ExtendResourceInfo & extendResourceInfo)476 bool ExtendResourceManagerHostImpl::ParseBundleResource(
477     const std::string &bundleName, const ExtendResourceInfo &extendResourceInfo)
478 {
479     APP_LOGI("ParseBundleResource %{public}s", bundleName.c_str());
480 #ifdef BUNDLE_FRAMEWORK_BUNDLE_RESOURCE
481     BundleResourceParser bundleResourceParser;
482     ResourceInfo info;
483     info.bundleName_ = bundleName;
484     info.iconId_ = extendResourceInfo.iconId;
485     if (!bundleResourceParser.ParseIconResourceByPath(extendResourceInfo.filePath,
486         extendResourceInfo.iconId, info)) {
487         APP_LOGW("ParseIconResourceByPath failed, bundleName:%{public}s", bundleName.c_str());
488         return false;
489     }
490     if (info.icon_.empty()) {
491         APP_LOGE("icon empty %{public}s", bundleName.c_str());
492         return false;
493     }
494     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
495     if (manager == nullptr) {
496         APP_LOGE("failed, manager is nullptr");
497         return false;
498     }
499     if (!manager->UpdateBundleIcon(bundleName, info)) {
500         APP_LOGE("UpdateBundleIcon failed, bundleName:%{public}s", bundleName.c_str());
501         return false;
502     }
503     return true;
504 #else
505     APP_LOGI("bundle resource not support");
506     return false;
507 #endif
508 }
509 
GetExtendResourceInfo(const std::string & bundleName,const std::string & moduleName,ExtendResourceInfo & extendResourceInfo)510 ErrCode ExtendResourceManagerHostImpl::GetExtendResourceInfo(const std::string &bundleName,
511     const std::string &moduleName, ExtendResourceInfo &extendResourceInfo)
512 {
513     InnerBundleInfo info;
514     if (!GetInnerBundleInfo(bundleName, info)) {
515         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
516         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
517     }
518     std::map<std::string, ExtendResourceInfo> extendResourceInfos = info.GetExtendResourceInfos();
519     if (extendResourceInfos.empty()) {
520         APP_LOGE("%{public}s no extend Resources", bundleName.c_str());
521         return ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST;
522     }
523     auto iter = extendResourceInfos.find(moduleName);
524     if (iter == extendResourceInfos.end()) {
525         APP_LOGE("%{public}s no %{public}s extend Resources", bundleName.c_str(), moduleName.c_str());
526         return ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST;
527     }
528     extendResourceInfo = iter->second;
529     return ERR_OK;
530 }
531 
DisableDynamicIcon(const std::string & bundleName)532 ErrCode ExtendResourceManagerHostImpl::DisableDynamicIcon(const std::string &bundleName)
533 {
534     APP_LOGI("DisableDynamicIcon %{public}s", bundleName.c_str());
535     if (bundleName.empty()) {
536         APP_LOGE("fail to DisableDynamicIcon due to param is empty");
537         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
538     }
539 
540     if (!BundlePermissionMgr::IsSystemApp()) {
541         APP_LOGE("Non-system app calling system api");
542         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
543     }
544 
545     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(
546         Constants::PERMISSION_ACCESS_DYNAMIC_ICON)) {
547         APP_LOGE("verify permission failed");
548         return ERR_APPEXECFWK_PERMISSION_DENIED;
549     }
550 
551     InnerBundleInfo info;
552     if (!GetInnerBundleInfo(bundleName, info)) {
553         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
554         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
555     }
556 
557     std::string curDynamicModule = info.GetCurDynamicIconModule();
558     if (curDynamicModule.empty()) {
559         APP_LOGE("%{public}s no enabled dynamic icon", bundleName.c_str());
560         return ERR_EXT_RESOURCE_MANAGER_DISABLE_DYNAMIC_ICON_FAILED;
561     }
562 
563     SaveCurDynamicIcon(bundleName, "");
564     ResetBundleResourceIcon(bundleName);
565     SendBroadcast(bundleName, false);
566     return ERR_OK;
567 }
568 
ResetBundleResourceIcon(const std::string & bundleName)569 bool ExtendResourceManagerHostImpl::ResetBundleResourceIcon(const std::string &bundleName)
570 {
571 #ifdef BUNDLE_FRAMEWORK_BUNDLE_RESOURCE
572     APP_LOGI("ResetBundleResourceIcon %{public}s", bundleName.c_str());
573     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
574     if (manager == nullptr) {
575         APP_LOGE("failed, manager is nullptr");
576         return false;
577     }
578 
579     // Delete dynamic icon resource
580     if (!manager->DeleteResourceInfo(bundleName)) {
581         APP_LOGE("DeleteResourceInfo failed, bundleName:%{public}s", bundleName.c_str());
582         return false;
583     }
584 
585     // Reset default icon
586     int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
587     if ((currentUserId <= 0)) {
588         currentUserId = Constants::START_USERID;
589     }
590     if (!manager->AddResourceInfoByBundleName(bundleName, currentUserId)) {
591         APP_LOGE("No default icon, bundleName:%{public}s", bundleName.c_str());
592     }
593     return true;
594 #else
595     return false;
596 #endif
597 }
598 
GetDynamicIcon(const std::string & bundleName,std::string & moudleName)599 ErrCode ExtendResourceManagerHostImpl::GetDynamicIcon(
600     const std::string &bundleName, std::string &moudleName)
601 {
602     if (bundleName.empty()) {
603         APP_LOGE("fail to GetDynamicIcon due to param is empty");
604         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
605     }
606 
607     if (!BundlePermissionMgr::IsSystemApp()) {
608         APP_LOGE("Non-system app calling system api");
609         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
610     }
611 
612     if (!BundlePermissionMgr::VerifyCallingPermissionsForAll({
613         Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED, Constants::PERMISSION_GET_BUNDLE_INFO})) {
614         APP_LOGE("verify permission failed");
615         return ERR_APPEXECFWK_PERMISSION_DENIED;
616     }
617 
618     InnerBundleInfo info;
619     if (!GetInnerBundleInfo(bundleName, info)) {
620         APP_LOGE("GetInnerBundleInfo failed %{public}s", bundleName.c_str());
621         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
622     }
623 
624     std::string curDynamicModule = info.GetCurDynamicIconModule();
625     if (curDynamicModule.empty()) {
626         APP_LOGE("%{public}s no enabled dynamic icon", bundleName.c_str());
627         return ERR_EXT_RESOURCE_MANAGER_GET_DYNAMIC_ICON_FAILED;
628     }
629 
630     moudleName = curDynamicModule;
631     return ERR_OK;
632 }
633 
CreateFd(const std::string & fileName,int32_t & fd,std::string & path)634 ErrCode ExtendResourceManagerHostImpl::CreateFd(
635     const std::string &fileName, int32_t &fd, std::string &path)
636 {
637     if (fileName.empty()) {
638         APP_LOGE("fail to CreateFd due to param is empty");
639         return ERR_EXT_RESOURCE_MANAGER_CREATE_FD_FAILED;
640     }
641     if (!BundlePermissionMgr::IsSystemApp()) {
642         APP_LOGE("Non-system app calling system api");
643         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
644     }
645     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(
646         Constants::PERMISSION_INSTALL_BUNDLE)) {
647         APP_LOGE("verify permission failed");
648         return ERR_APPEXECFWK_PERMISSION_DENIED;
649     }
650     if (!BundleUtil::CheckFileType(fileName, EXT_RESOURCE_FILE_SUFFIX)) {
651         APP_LOGE("not hsp file");
652         return ERR_EXT_RESOURCE_MANAGER_CREATE_FD_FAILED;
653     }
654     if (!IsFileNameValid(fileName)) {
655         APP_LOGE("invalid fileName");
656         return ERR_EXT_RESOURCE_MANAGER_CREATE_FD_FAILED;
657     }
658     std::string tmpDir = BundleUtil::CreateInstallTempDir(
659         ++id_, DirType::EXT_RESOURCE_FILE_DIR);
660     if (tmpDir.empty()) {
661         APP_LOGE("create tmp dir failed");
662         return ERR_EXT_RESOURCE_MANAGER_CREATE_FD_FAILED;
663     }
664     path = tmpDir + fileName;
665     if ((fd = BundleUtil::CreateFileDescriptor(path, 0)) < 0) {
666         APP_LOGE("create file descriptor failed");
667         BundleUtil::DeleteDir(tmpDir);
668         return ERR_EXT_RESOURCE_MANAGER_CREATE_FD_FAILED;
669     }
670     return ERR_OK;
671 }
672 } // AppExecFwk
673 } // namespace OHOS
674