1 /*
2 * Copyright (c) 2021-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
16 #include "context_impl.h"
17
18 #include <cerrno>
19 #include <regex>
20
21 #include "app_mgr_client.h"
22 #include "application_context.h"
23 #include "bundle_mgr_helper.h"
24 #include "bundle_mgr_proxy.h"
25 #include "common_event_manager.h"
26 #include "configuration_convertor.h"
27 #include "constants.h"
28 #include "directory_ex.h"
29 #include "file_ex.h"
30 #include "hilog_wrapper.h"
31 #include "ipc_singleton.h"
32 #include "js_runtime_utils.h"
33 #ifdef SUPPORT_GRAPHICS
34 #include "locale_config.h"
35 #endif
36 #include "os_account_manager_wrapper.h"
37 #include "overlay_event_subscriber.h"
38 #include "overlay_module_info.h"
39 #include "parameters.h"
40 #include "running_process_info.h"
41 #include "sys_mgr_client.h"
42 #include "system_ability_definition.h"
43
44 namespace OHOS {
45 namespace AbilityRuntime {
46 using namespace OHOS::AbilityBase::Constants;
47
48 const std::string PATTERN_VERSION = std::string(FILE_SEPARATOR) + "v\\d+" + FILE_SEPARATOR;
49
50 const size_t Context::CONTEXT_TYPE_ID(std::hash<const char*> {} ("Context"));
51 const int64_t ContextImpl::CONTEXT_CREATE_BY_SYSTEM_APP(0x00000001);
52 const mode_t MODE = 0770;
53 const mode_t GROUP_MODE = 02770;
54 const std::string ContextImpl::CONTEXT_DATA_APP("/data/app/");
55 const std::string ContextImpl::CONTEXT_BUNDLE("/bundle/");
56 const std::string ContextImpl::CONTEXT_DISTRIBUTEDFILES_BASE_BEFORE("/mnt/hmdfs/");
57 const std::string ContextImpl::CONTEXT_DISTRIBUTEDFILES_BASE_MIDDLE("/device_view/local/data/");
58 const std::string ContextImpl::CONTEXT_DISTRIBUTEDFILES("distributedfiles");
59 const std::string ContextImpl::CONTEXT_FILE_SEPARATOR("/");
60 const std::string ContextImpl::CONTEXT_DATA("/data/");
61 const std::string ContextImpl::CONTEXT_DATA_STORAGE("/data/storage/");
62 const std::string ContextImpl::CONTEXT_BASE("base");
63 const std::string ContextImpl::CONTEXT_CACHE("cache");
64 const std::string ContextImpl::CONTEXT_PREFERENCES("preferences");
65 const std::string ContextImpl::CONTEXT_GROUP("group");
66 const std::string ContextImpl::CONTEXT_DATABASE("database");
67 const std::string ContextImpl::CONTEXT_TEMP("/temp");
68 const std::string ContextImpl::CONTEXT_FILES("/files");
69 const std::string ContextImpl::CONTEXT_HAPS("/haps");
70 const std::string ContextImpl::CONTEXT_ELS[] = {"el1", "el2", "el3", "el4"};
71 const std::string ContextImpl::CONTEXT_RESOURCE_END = "/resources/resfile";
72 Global::Resource::DeviceType ContextImpl::deviceType_ = Global::Resource::DeviceType::DEVICE_NOT_SET;
73 const std::string OVERLAY_STATE_CHANGED = "usual.event.OVERLAY_STATE_CHANGED";
74 const int32_t TYPE_RESERVE = 1;
75 const int32_t TYPE_OTHERS = 2;
76 const int32_t API11 = 11;
77 const int32_t API_VERSION_MOD = 100;
78 const int AREA2 = 2;
79 const int AREA3 = 3;
80
GetBundleName() const81 std::string ContextImpl::GetBundleName() const
82 {
83 if (parentContext_ != nullptr) {
84 return parentContext_->GetBundleName();
85 }
86 return (applicationInfo_ != nullptr) ? applicationInfo_->bundleName : "";
87 }
88
GetBundleCodeDir()89 std::string ContextImpl::GetBundleCodeDir()
90 {
91 auto appInfo = GetApplicationInfo();
92 if (appInfo == nullptr) {
93 return "";
94 }
95
96 std::string dir;
97 if (IsCreateBySystemApp()) {
98 dir = std::regex_replace(appInfo->codePath, std::regex(ABS_CODE_PATH), LOCAL_BUNDLES);
99 } else {
100 dir = LOCAL_CODE_PATH;
101 }
102 CreateDirIfNotExist(dir, MODE);
103 HILOG_DEBUG("dir:%{public}s", dir.c_str());
104 return dir;
105 }
106
GetCacheDir()107 std::string ContextImpl::GetCacheDir()
108 {
109 std::string dir = GetBaseDir() + CONTEXT_FILE_SEPARATOR + CONTEXT_CACHE;
110 CreateDirIfNotExist(dir, MODE);
111 HILOG_DEBUG("dir:%{public}s", dir.c_str());
112 return dir;
113 }
114
IsUpdatingConfigurations()115 bool ContextImpl::IsUpdatingConfigurations()
116 {
117 return false;
118 }
119
PrintDrawnCompleted()120 bool ContextImpl::PrintDrawnCompleted()
121 {
122 return false;
123 }
124
CreateDirIfNotExistWithCheck(const std::string & dirPath,const mode_t & mode,bool checkExist)125 void ContextImpl::CreateDirIfNotExistWithCheck(const std::string &dirPath, const mode_t &mode, bool checkExist)
126 {
127 if (checkExist) {
128 CreateDirIfNotExist(dirPath, mode);
129 return;
130 }
131 // Check if the dirPath exists on the first call
132 std::lock_guard<std::mutex> lock(checkedDirSetLock_);
133 if (checkedDirSet_.find(dirPath) != checkedDirSet_.end()) {
134 return;
135 }
136 checkedDirSet_.emplace(dirPath);
137 CreateDirIfNotExist(dirPath, mode);
138 }
139
GetDatabaseDirWithCheck(bool checkExist,std::string & databaseDir)140 int32_t ContextImpl::GetDatabaseDirWithCheck(bool checkExist, std::string &databaseDir)
141 {
142 if (IsCreateBySystemApp()) {
143 databaseDir = CONTEXT_DATA_APP + currArea_ + CONTEXT_FILE_SEPARATOR + std::to_string(GetCurrentAccountId())
144 + CONTEXT_FILE_SEPARATOR + CONTEXT_DATABASE + CONTEXT_FILE_SEPARATOR + GetBundleName();
145 } else {
146 databaseDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_DATABASE;
147 }
148 if (parentContext_ != nullptr) {
149 databaseDir = databaseDir + CONTEXT_FILE_SEPARATOR +
150 ((GetHapModuleInfo() == nullptr) ? "" : GetHapModuleInfo()->moduleName);
151 }
152 CreateDirIfNotExistWithCheck(databaseDir, 0, checkExist);
153 return ERR_OK;
154 }
155
GetGroupDatabaseDirWithCheck(const std::string & groupId,bool checkExist,std::string & databaseDir)156 int32_t ContextImpl::GetGroupDatabaseDirWithCheck(const std::string &groupId, bool checkExist, std::string &databaseDir)
157 {
158 int32_t ret = GetGroupDirWithCheck(groupId, checkExist, databaseDir);
159 if (ret != ERR_OK) {
160 return ret;
161 }
162 databaseDir = databaseDir + CONTEXT_FILE_SEPARATOR + CONTEXT_DATABASE;
163 CreateDirIfNotExistWithCheck(databaseDir, GROUP_MODE, checkExist);
164 return ERR_OK;
165 }
166
GetSystemDatabaseDir(const std::string & groupId,bool checkExist,std::string & databaseDir)167 int32_t ContextImpl::GetSystemDatabaseDir(const std::string &groupId, bool checkExist, std::string &databaseDir)
168 {
169 int32_t ret;
170 if (groupId.empty()) {
171 ret = GetDatabaseDirWithCheck(checkExist, databaseDir);
172 } else {
173 ret = GetGroupDatabaseDirWithCheck(groupId, checkExist, databaseDir);
174 }
175 HILOG_DEBUG("databaseDir: %{public}s", databaseDir.c_str());
176 return ret;
177 }
178
GetDatabaseDir()179 std::string ContextImpl::GetDatabaseDir()
180 {
181 std::string dir;
182 GetDatabaseDirWithCheck(true, dir);
183 HILOG_DEBUG("databaseDir: %{public}s", dir.c_str());
184 return dir;
185 }
186
GetPreferencesDirWithCheck(bool checkExist,std::string & preferencesDir)187 int32_t ContextImpl::GetPreferencesDirWithCheck(bool checkExist, std::string &preferencesDir)
188 {
189 preferencesDir = GetBaseDir() + CONTEXT_FILE_SEPARATOR + CONTEXT_PREFERENCES;
190 CreateDirIfNotExistWithCheck(preferencesDir, MODE, checkExist);
191 return ERR_OK;
192 }
193
GetGroupPreferencesDirWithCheck(const std::string & groupId,bool checkExist,std::string & preferencesDir)194 int32_t ContextImpl::GetGroupPreferencesDirWithCheck(const std::string &groupId, bool checkExist,
195 std::string &preferencesDir)
196 {
197 int32_t ret = GetGroupDirWithCheck(groupId, checkExist, preferencesDir);
198 if (ret != ERR_OK) {
199 return ret;
200 }
201 preferencesDir = preferencesDir + CONTEXT_FILE_SEPARATOR + CONTEXT_PREFERENCES;
202 CreateDirIfNotExistWithCheck(preferencesDir, GROUP_MODE, checkExist);
203 return ERR_OK;
204 }
205
GetSystemPreferencesDir(const std::string & groupId,bool checkExist,std::string & preferencesDir)206 int32_t ContextImpl::GetSystemPreferencesDir(const std::string &groupId, bool checkExist, std::string &preferencesDir)
207 {
208 int32_t ret;
209 if (groupId.empty()) {
210 ret = GetPreferencesDirWithCheck(checkExist, preferencesDir);
211 } else {
212 ret = GetGroupPreferencesDirWithCheck(groupId, checkExist, preferencesDir);
213 }
214 HILOG_DEBUG("preferencesDir: %{public}s", preferencesDir.c_str());
215 return ret;
216 }
217
GetPreferencesDir()218 std::string ContextImpl::GetPreferencesDir()
219 {
220 std::string dir;
221 GetPreferencesDirWithCheck(true, dir);
222 HILOG_DEBUG("preferencesDir: %{public}s", dir.c_str());
223 return dir;
224 }
225
GetGroupDirWithCheck(const std::string & groupId,bool checkExist,std::string & groupDir)226 int32_t ContextImpl::GetGroupDirWithCheck(const std::string &groupId, bool checkExist, std::string &groupDir)
227 {
228 if (currArea_ == CONTEXT_ELS[0]) {
229 HILOG_ERROR("GroupDir currently can't supports the el1 level");
230 return ERR_INVALID_VALUE;
231 }
232 int errCode = GetBundleManager();
233 if (errCode != ERR_OK) {
234 HILOG_ERROR("failed, errCode: %{public}d.", errCode);
235 return errCode;
236 }
237 std::string groupDirGet;
238 bool ret = bundleMgr_->GetGroupDir(groupId, groupDirGet);
239 if (!ret || groupDirGet.empty()) {
240 HILOG_ERROR("GetGroupDir failed or groupDirGet is empty");
241 return ERR_INVALID_VALUE;
242 }
243 std::string uuid = groupDirGet.substr(groupDirGet.rfind('/'));
244 groupDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_GROUP + uuid;
245 CreateDirIfNotExistWithCheck(groupDir, MODE, true);
246 return ERR_OK;
247 }
248
GetGroupDir(std::string groupId)249 std::string ContextImpl::GetGroupDir(std::string groupId)
250 {
251 std::string dir;
252 GetGroupDirWithCheck(groupId, true, dir);
253 HILOG_DEBUG("GroupDir:%{public}s", dir.c_str());
254 return dir;
255 }
256
GetTempDir()257 std::string ContextImpl::GetTempDir()
258 {
259 std::string dir = GetBaseDir() + CONTEXT_TEMP;
260 CreateDirIfNotExist(dir, MODE);
261 HILOG_DEBUG("dir:%{public}s", dir.c_str());
262 return dir;
263 }
264
GetAllTempDir(std::vector<std::string> & tempPaths)265 void ContextImpl::GetAllTempDir(std::vector<std::string> &tempPaths)
266 {
267 // Application temp dir
268 auto appTemp = GetTempDir();
269 if (OHOS::FileExists(appTemp)) {
270 tempPaths.push_back(appTemp);
271 }
272 // Module dir
273 if (applicationInfo_ == nullptr) {
274 HILOG_ERROR("The application info is empty");
275 return;
276 }
277
278 std::string baseDir;
279 if (IsCreateBySystemApp()) {
280 baseDir = CONTEXT_DATA_APP + currArea_ + CONTEXT_FILE_SEPARATOR + std::to_string(GetCurrentAccountId()) +
281 CONTEXT_FILE_SEPARATOR + CONTEXT_BASE + CONTEXT_FILE_SEPARATOR + GetBundleName();
282 } else {
283 baseDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_BASE;
284 }
285 for (const auto &moudleItem: applicationInfo_->moduleInfos) {
286 auto moudleTemp = baseDir + CONTEXT_HAPS + CONTEXT_FILE_SEPARATOR + moudleItem.moduleName + CONTEXT_TEMP;
287 if (!OHOS::FileExists(moudleTemp)) {
288 HILOG_WARN("moudle[%{public}s] temp path not exists,path is %{public}s",
289 moudleItem.moduleName.c_str(), moudleTemp.c_str());
290 continue;
291 }
292 tempPaths.push_back(moudleTemp);
293 }
294 }
295
GetResourceDir()296 std::string ContextImpl::GetResourceDir()
297 {
298 std::shared_ptr<AppExecFwk::HapModuleInfo> hapModuleInfoPtr = GetHapModuleInfo();
299 if (hapModuleInfoPtr == nullptr || hapModuleInfoPtr->moduleName.empty()) {
300 return "";
301 }
302 std::string dir = std::string(LOCAL_CODE_PATH) + CONTEXT_FILE_SEPARATOR +
303 hapModuleInfoPtr->moduleName + CONTEXT_RESOURCE_END;
304 if (OHOS::FileExists(dir)) {
305 return dir;
306 }
307 return "";
308 }
309
GetFilesDir()310 std::string ContextImpl::GetFilesDir()
311 {
312 std::string dir = GetBaseDir() + CONTEXT_FILES;
313 CreateDirIfNotExist(dir, MODE);
314 HILOG_DEBUG("dir:%{public}s", dir.c_str());
315 return dir;
316 }
317
GetDistributedFilesDir()318 std::string ContextImpl::GetDistributedFilesDir()
319 {
320 HILOG_DEBUG("called");
321 std::string dir;
322 if (IsCreateBySystemApp()) {
323 dir = CONTEXT_DISTRIBUTEDFILES_BASE_BEFORE + std::to_string(GetCurrentAccountId()) +
324 CONTEXT_DISTRIBUTEDFILES_BASE_MIDDLE + GetBundleName();
325 } else {
326 if (currArea_ == CONTEXT_ELS[1] || currArea_ == CONTEXT_ELS[AREA2] || currArea_ == CONTEXT_ELS[AREA3]) {
327 //when areamode swith to el3/el4, the distributedfiles dir should be always el2's distributedfilesdir dir
328 dir = CONTEXT_DATA_STORAGE + CONTEXT_ELS[1] + CONTEXT_FILE_SEPARATOR + CONTEXT_DISTRIBUTEDFILES;
329 } else {
330 dir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_DISTRIBUTEDFILES;
331 }
332 }
333 CreateDirIfNotExist(dir, 0);
334 HILOG_DEBUG("dir:%{public}s", dir.c_str());
335 return dir;
336 }
337
SwitchArea(int mode)338 void ContextImpl::SwitchArea(int mode)
339 {
340 HILOG_DEBUG("mode:%{public}d.", mode);
341 if (mode < 0 || mode >= (int)(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0]))) {
342 HILOG_ERROR("ContextImpl::SwitchArea, mode is invalid.");
343 return;
344 }
345 currArea_ = CONTEXT_ELS[mode];
346 HILOG_DEBUG("currArea:%{public}s.", currArea_.c_str());
347 }
348
CreateModuleContext(const std::string & moduleName)349 std::shared_ptr<Context> ContextImpl::CreateModuleContext(const std::string &moduleName)
350 {
351 return CreateModuleContext(GetBundleName(), moduleName);
352 }
353
CreateModuleContext(const std::string & bundleName,const std::string & moduleName)354 std::shared_ptr<Context> ContextImpl::CreateModuleContext(const std::string &bundleName, const std::string &moduleName)
355 {
356 HILOG_DEBUG("begin.");
357 if (bundleName.empty() || moduleName.empty()) {
358 HILOG_ERROR("bundleName or moduleName is empty");
359 return nullptr;
360 }
361
362 HILOG_DEBUG("length: %{public}zu, bundleName: %{public}s",
363 (size_t)bundleName.length(), bundleName.c_str());
364
365 int accountId = GetCurrentAccountId();
366 if (accountId == 0) {
367 accountId = GetCurrentActiveAccountId();
368 }
369
370 AppExecFwk::BundleInfo bundleInfo;
371 GetBundleInfo(bundleName, bundleInfo, accountId);
372 if (bundleInfo.name.empty() || bundleInfo.applicationInfo.name.empty()) {
373 HILOG_ERROR("GetBundleInfo is error");
374 ErrCode ret = bundleMgr_->GetDependentBundleInfo(bundleName, bundleInfo,
375 AppExecFwk::GetDependentBundleInfoFlag::GET_ALL_DEPENDENT_BUNDLE_INFO);
376 if (ret != ERR_OK) {
377 HILOG_ERROR("GetDependentBundleInfo failed:%{public}d", ret);
378 return nullptr;
379 }
380 }
381
382 std::shared_ptr<ContextImpl> appContext = std::make_shared<ContextImpl>();
383 if (bundleInfo.applicationInfo.codePath != std::to_string(TYPE_RESERVE) &&
384 bundleInfo.applicationInfo.codePath != std::to_string(TYPE_OTHERS)) {
385 auto info = std::find_if(bundleInfo.hapModuleInfos.begin(), bundleInfo.hapModuleInfos.end(),
386 [&moduleName](const AppExecFwk::HapModuleInfo &hapModuleInfo) {
387 return hapModuleInfo.moduleName == moduleName;
388 });
389 if (info == bundleInfo.hapModuleInfos.end()) {
390 HILOG_ERROR("moduleName is error.");
391 return nullptr;
392 }
393 appContext->InitHapModuleInfo(*info);
394 }
395
396 appContext->SetConfiguration(config_);
397 InitResourceManager(bundleInfo, appContext, GetBundleName() == bundleName, moduleName);
398 appContext->SetApplicationInfo(std::make_shared<AppExecFwk::ApplicationInfo>(bundleInfo.applicationInfo));
399 return appContext;
400 }
401
CreateModuleResourceManager(const std::string & bundleName,const std::string & moduleName)402 std::shared_ptr<Global::Resource::ResourceManager> ContextImpl::CreateModuleResourceManager(
403 const std::string &bundleName, const std::string &moduleName)
404 {
405 HILOG_DEBUG("begin, bundleName: %{public}s, moduleName: %{public}s", bundleName.c_str(), moduleName.c_str());
406 if (bundleName.empty() || moduleName.empty()) {
407 HILOG_ERROR("bundleName is %{public}s, moduleName is %{public}s", bundleName.c_str(), moduleName.c_str());
408 return nullptr;
409 }
410
411 AppExecFwk::BundleInfo bundleInfo;
412 bool currentBundle = false;
413 if (GetBundleInfo(bundleName, bundleInfo, currentBundle) != ERR_OK) {
414 HILOG_ERROR("Failed to GetBundleInfo, bundleName: %{public}s", bundleName.c_str());
415 return nullptr;
416 }
417
418 if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_RESERVE) ||
419 bundleInfo.applicationInfo.codePath == std::to_string(TYPE_OTHERS)) {
420 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = InitOthersResourceManagerInner(
421 bundleInfo, currentBundle, moduleName);
422 if (resourceManager == nullptr) {
423 HILOG_ERROR("InitOthersResourceManagerInner create resourceManager failed");
424 }
425 return resourceManager;
426 }
427
428 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = InitResourceManagerInner(
429 bundleInfo, currentBundle, moduleName);
430 if (resourceManager == nullptr) {
431 HILOG_ERROR("InitResourceManagerInner create resourceManager failed");
432 return nullptr;
433 }
434 UpdateResConfig(resourceManager);
435 return resourceManager;
436 }
437
GetBundleInfo(const std::string & bundleName,AppExecFwk::BundleInfo & bundleInfo,bool & currentBundle)438 int32_t ContextImpl::GetBundleInfo(const std::string &bundleName, AppExecFwk::BundleInfo &bundleInfo,
439 bool ¤tBundle)
440 {
441 std::string currentBundleName;
442 auto appContext = ApplicationContext::GetInstance();
443 if (appContext != nullptr) {
444 currentBundleName = appContext->GetBundleName();
445 }
446 currentBundle = bundleName == currentBundleName;
447
448 int errCode = GetBundleManager();
449 if (errCode != ERR_OK) {
450 HILOG_ERROR("errCode: %{public}d.", errCode);
451 return errCode;
452 }
453
454 if (currentBundle) {
455 bundleMgr_->GetBundleInfoForSelf((
456 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) +
457 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) +
458 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) +
459 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) +
460 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO) +
461 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) +
462 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA)), bundleInfo);
463 } else {
464 int accountId = GetCurrentAccountId();
465 if (accountId == 0) {
466 accountId = GetCurrentActiveAccountId();
467 }
468 bundleMgr_->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, accountId);
469 }
470
471 if (bundleInfo.name.empty() || bundleInfo.applicationInfo.name.empty()) {
472 HILOG_WARN("bundleInfo is empty");
473 ErrCode ret = bundleMgr_->GetUninstalledBundleInfo(bundleName, bundleInfo);
474 if (ret != ERR_OK) {
475 HILOG_ERROR("GetUninstalledBundleInfo failed:%{public}d", ret);
476 return ret;
477 }
478 }
479 return ERR_OK;
480 }
481
GetBundleInfo(const std::string & bundleName,AppExecFwk::BundleInfo & bundleInfo,const int & accountId)482 void ContextImpl::GetBundleInfo(const std::string &bundleName, AppExecFwk::BundleInfo &bundleInfo,
483 const int &accountId)
484 {
485 HILOG_DEBUG("begin");
486 if (bundleMgr_ == nullptr) {
487 int errCode = GetBundleManager();
488 if (errCode != ERR_OK) {
489 HILOG_ERROR("failed, errCode: %{public}d.", errCode);
490 return;
491 }
492 }
493
494 if (bundleName == GetBundleName()) {
495 bundleMgr_->GetBundleInfoForSelf(
496 (static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) +
497 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) +
498 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) +
499 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) +
500 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO) +
501 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) +
502 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA)), bundleInfo);
503 } else {
504 bundleMgr_->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, accountId);
505 }
506 }
507
GetArea()508 int ContextImpl::GetArea()
509 {
510 HILOG_DEBUG("begin");
511 int mode = -1;
512 for (int i = 0; i < (int)(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0])); i++) {
513 if (currArea_ == CONTEXT_ELS[i]) {
514 mode = i;
515 break;
516 }
517 }
518 if (mode == -1) {
519 HILOG_ERROR("not find mode.");
520 return EL_DEFAULT;
521 }
522 HILOG_DEBUG("end");
523 return mode;
524 }
525
GetBaseDir() const526 std::string ContextImpl::GetBaseDir() const
527 {
528 std::string baseDir;
529 if (IsCreateBySystemApp()) {
530 baseDir = CONTEXT_DATA_APP + currArea_ + CONTEXT_FILE_SEPARATOR + std::to_string(GetCurrentAccountId()) +
531 CONTEXT_FILE_SEPARATOR + CONTEXT_BASE + CONTEXT_FILE_SEPARATOR + GetBundleName();
532 } else {
533 baseDir = CONTEXT_DATA_STORAGE + currArea_ + CONTEXT_FILE_SEPARATOR + CONTEXT_BASE;
534 }
535 if (parentContext_ != nullptr) {
536 baseDir = baseDir + CONTEXT_HAPS + CONTEXT_FILE_SEPARATOR +
537 ((GetHapModuleInfo() == nullptr) ? "" : GetHapModuleInfo()->moduleName);
538 }
539
540 HILOG_DEBUG("Dir:%{public}s", baseDir.c_str());
541 return baseDir;
542 }
543
GetCurrentAccountId() const544 int ContextImpl::GetCurrentAccountId() const
545 {
546 int userId = 0;
547 auto instance = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance();
548 if (instance == nullptr) {
549 HILOG_ERROR("Failed to get OsAccountManager instance.");
550 return userId;
551 }
552 instance->GetOsAccountLocalIdFromProcess(userId);
553 return userId;
554 }
555
GetCurrentActiveAccountId() const556 int ContextImpl::GetCurrentActiveAccountId() const
557 {
558 std::vector<int> accountIds;
559 auto instance = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance();
560 if (instance == nullptr) {
561 HILOG_ERROR("Failed to get OsAccountManager instance.");
562 return 0;
563 }
564 ErrCode ret = instance->QueryActiveOsAccountIds(accountIds);
565 if (ret != ERR_OK) {
566 HILOG_ERROR("ContextImpl::GetCurrentActiveAccountId error.");
567 return 0;
568 }
569
570 if (accountIds.size() == 0) {
571 HILOG_ERROR("no accounts.");
572 return 0;
573 }
574
575 if (accountIds.size() > 1) {
576 HILOG_ERROR("no current now.");
577 return 0;
578 }
579
580 return accountIds[0];
581 }
582
CreateBundleContext(const std::string & bundleName)583 std::shared_ptr<Context> ContextImpl::CreateBundleContext(const std::string &bundleName)
584 {
585 HILOG_DEBUG("begin.");
586 if (parentContext_ != nullptr) {
587 return parentContext_->CreateBundleContext(bundleName);
588 }
589
590 if (bundleName.empty()) {
591 HILOG_ERROR("bundleName is empty");
592 return nullptr;
593 }
594
595 int errCode = GetBundleManager();
596 if (errCode != ERR_OK) {
597 HILOG_ERROR("failed, errCode: %{public}d.", errCode);
598 return nullptr;
599 }
600
601 AppExecFwk::BundleInfo bundleInfo;
602 int accountId = GetCurrentAccountId();
603 if (accountId == 0) {
604 accountId = GetCurrentActiveAccountId();
605 }
606 HILOG_DEBUG("length: %{public}zu, bundleName: %{public}s",
607 (size_t)bundleName.length(), bundleName.c_str());
608 bundleMgr_->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, accountId);
609
610 if (bundleInfo.name.empty() || bundleInfo.applicationInfo.name.empty()) {
611 HILOG_ERROR("bundleInfo is empty");
612 return nullptr;
613 }
614
615 std::shared_ptr<ContextImpl> appContext = std::make_shared<ContextImpl>();
616 appContext->SetFlags(CONTEXT_CREATE_BY_SYSTEM_APP);
617 appContext->SetConfiguration(config_);
618
619 // init resourceManager.
620 InitResourceManager(bundleInfo, appContext);
621 appContext->SetApplicationInfo(std::make_shared<AppExecFwk::ApplicationInfo>(bundleInfo.applicationInfo));
622 return appContext;
623 }
624
InitResourceManager(const AppExecFwk::BundleInfo & bundleInfo,const std::shared_ptr<ContextImpl> & appContext,bool currentBundle,const std::string & moduleName)625 void ContextImpl::InitResourceManager(const AppExecFwk::BundleInfo &bundleInfo,
626 const std::shared_ptr<ContextImpl> &appContext, bool currentBundle, const std::string& moduleName)
627 {
628 HILOG_DEBUG("begin, bundleName:%{public}s, moduleName:%{public}s",
629 bundleInfo.name.c_str(), moduleName.c_str());
630
631 if (appContext == nullptr) {
632 HILOG_ERROR("InitResourceManager appContext is nullptr");
633 return;
634 }
635
636 if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_RESERVE) ||
637 bundleInfo.applicationInfo.codePath == std::to_string(TYPE_OTHERS)) {
638 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = InitOthersResourceManagerInner(
639 bundleInfo, currentBundle, moduleName);
640 if (resourceManager == nullptr) {
641 HILOG_ERROR("create resourceManager failed");
642 return;
643 }
644 appContext->SetResourceManager(resourceManager);
645 return;
646 }
647
648 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = InitResourceManagerInner(
649 bundleInfo, currentBundle, moduleName);
650 if (resourceManager == nullptr) {
651 return;
652 }
653 UpdateResConfig(resourceManager);
654 appContext->SetResourceManager(resourceManager);
655 }
656
InitOthersResourceManagerInner(const AppExecFwk::BundleInfo & bundleInfo,bool currentBundle,const std::string & moduleName)657 std::shared_ptr<Global::Resource::ResourceManager> ContextImpl::InitOthersResourceManagerInner(
658 const AppExecFwk::BundleInfo &bundleInfo, bool currentBundle, const std::string& moduleName)
659 {
660 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
661 std::string hapPath;
662 std::vector<std::string> overlayPaths;
663 int32_t appType;
664 if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_RESERVE)) {
665 appType = TYPE_RESERVE;
666 } else if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_OTHERS)) {
667 appType = TYPE_OTHERS;
668 } else {
669 appType = 0;
670 }
671 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager(
672 bundleInfo.name, moduleName, hapPath, overlayPaths, *resConfig, appType));
673 return resourceManager;
674 }
675
InitResourceManagerInner(const AppExecFwk::BundleInfo & bundleInfo,bool currentBundle,const std::string & moduleName)676 std::shared_ptr<Global::Resource::ResourceManager> ContextImpl::InitResourceManagerInner(
677 const AppExecFwk::BundleInfo &bundleInfo, bool currentBundle, const std::string& moduleName)
678 {
679 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = InitOthersResourceManagerInner(
680 bundleInfo, currentBundle, moduleName);
681 if (resourceManager == nullptr) {
682 HILOG_ERROR("Create resourceManager failed");
683 return resourceManager;
684 }
685 if (!moduleName.empty() || !bundleInfo.applicationInfo.multiProjects) {
686 HILOG_DEBUG("hapModuleInfos count: %{public}zu", bundleInfo.hapModuleInfos.size());
687 std::regex inner_pattern(std::string(ABS_CODE_PATH) + std::string(FILE_SEPARATOR) + GetBundleName());
688 std::regex outer_pattern(ABS_CODE_PATH);
689 std::regex hsp_pattern(std::string(ABS_CODE_PATH) + FILE_SEPARATOR + bundleInfo.name + PATTERN_VERSION);
690 std::string hsp_sandbox = std::string(LOCAL_CODE_PATH) + FILE_SEPARATOR + bundleInfo.name + FILE_SEPARATOR;
691 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
692 HILOG_DEBUG("hapModuleInfo abilityInfo size: %{public}zu", hapModuleInfo.abilityInfos.size());
693 if (!moduleName.empty() && hapModuleInfo.moduleName != moduleName) {
694 continue;
695 }
696 std::string loadPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
697 if (loadPath.empty()) {
698 HILOG_DEBUG("loadPath is empty");
699 continue;
700 }
701 if (currentBundle) {
702 loadPath = std::regex_replace(loadPath, inner_pattern, LOCAL_CODE_PATH);
703 } else if (bundleInfo.applicationInfo.bundleType == AppExecFwk::BundleType::SHARED) {
704 loadPath = std::regex_replace(loadPath, hsp_pattern, hsp_sandbox);
705 } else if (bundleInfo.applicationInfo.bundleType == AppExecFwk::BundleType::APP_SERVICE_FWK) {
706 HILOG_DEBUG("System hsp path, not need translate.");
707 } else {
708 loadPath = std::regex_replace(loadPath, outer_pattern, LOCAL_BUNDLES);
709 }
710
711 HILOG_DEBUG("loadPath: %{public}s", loadPath.c_str());
712 // getOverlayPath
713 std::vector<AppExecFwk::OverlayModuleInfo> overlayModuleInfos;
714 auto res = GetOverlayModuleInfos(bundleInfo.name, hapModuleInfo.moduleName, overlayModuleInfos);
715 if (res != ERR_OK) {
716 HILOG_DEBUG("Get overlay paths from bms failed.");
717 }
718 if (overlayModuleInfos.size() == 0) {
719 if (!resourceManager->AddResource(loadPath.c_str())) {
720 HILOG_ERROR("AddResource fail, moduleResPath: %{public}s", loadPath.c_str());
721 }
722 } else {
723 std::vector<std::string> overlayPaths;
724 for (auto it : overlayModuleInfos) {
725 if (std::regex_search(it.hapPath, std::regex(GetBundleName()))) {
726 it.hapPath = std::regex_replace(it.hapPath, inner_pattern, LOCAL_CODE_PATH);
727 } else {
728 it.hapPath = std::regex_replace(it.hapPath, outer_pattern, LOCAL_BUNDLES);
729 }
730 if (it.state == AppExecFwk::OverlayState::OVERLAY_ENABLE) {
731 HILOG_DEBUG("hapPath: %{public}s", it.hapPath.c_str());
732 overlayPaths.emplace_back(it.hapPath);
733 }
734 }
735 HILOG_DEBUG("OverlayPaths size:%{public}zu.", overlayPaths.size());
736 if (!resourceManager->AddResource(loadPath, overlayPaths)) {
737 HILOG_ERROR("AddResource failed");
738 }
739
740 if (currentBundle) {
741 // add listen overlay change
742 overlayModuleInfos_ = overlayModuleInfos;
743 EventFwk::MatchingSkills matchingSkills;
744 matchingSkills.AddEvent(OVERLAY_STATE_CHANGED);
745 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
746 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
747 auto callback = [this, resourceManager, bundleName = bundleInfo.name, moduleName =
748 hapModuleInfo.moduleName, loadPath](const EventFwk::CommonEventData &data) {
749 HILOG_INFO("On overlay changed.");
750 this->OnOverlayChanged(data, resourceManager, bundleName, moduleName, loadPath);
751 };
752 auto subscriber = std::make_shared<AppExecFwk::OverlayEventSubscriber>(subscribeInfo, callback);
753 bool subResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
754 HILOG_INFO("Overlay event subscriber register result is %{public}d", subResult);
755 }
756 }
757 }
758 }
759 return resourceManager;
760 }
761
UpdateResConfig(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager)762 void ContextImpl::UpdateResConfig(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager)
763 {
764 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
765 if (resConfig == nullptr) {
766 HILOG_ERROR("create ResConfig failed");
767 return;
768 }
769
770 if (GetHapModuleInfo() != nullptr && GetApplicationInfo() != nullptr) {
771 std::vector<AppExecFwk::Metadata> metadata = GetHapModuleInfo()->metadata;
772 bool load = std::any_of(metadata.begin(), metadata.end(), [](const auto &metadataItem) {
773 return metadataItem.name == "ContextResourceConfigLoadFromParentTemp" && metadataItem.value == "true";
774 });
775 if (load && GetApplicationInfo()->apiTargetVersion % API_VERSION_MOD >= API11) {
776 std::shared_ptr<Global::Resource::ResourceManager> currentResMgr = GetResourceManager();
777 if (currentResMgr != nullptr) {
778 HILOG_DEBUG("apiVersion: %{public}d, load parent config.", GetApplicationInfo()->apiTargetVersion);
779 currentResMgr->GetResConfig(*resConfig);
780 }
781 }
782 }
783 #ifdef SUPPORT_GRAPHICS
784 UErrorCode status = U_ZERO_ERROR;
785 icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
786 resConfig->SetLocaleInfo(locale);
787 if (resConfig->GetLocaleInfo() != nullptr) {
788 HILOG_DEBUG("ContextImpl::InitResourceManager language: %{public}s, script: %{public}s, region: %{public}s,",
789 resConfig->GetLocaleInfo()->getLanguage(), resConfig->GetLocaleInfo()->getScript(),
790 resConfig->GetLocaleInfo()->getCountry());
791 } else {
792 HILOG_ERROR("ContextImpl::InitResourceManager language: GetLocaleInfo is null.");
793 }
794 #endif
795 resConfig->SetDeviceType(GetDeviceType());
796 resourceManager->UpdateResConfig(*resConfig);
797 }
798
GetBundleManager()799 ErrCode ContextImpl::GetBundleManager()
800 {
801 std::lock_guard<std::mutex> lock(bundleManagerMutex_);
802 if (bundleMgr_ != nullptr && !resetFlag_) {
803 return ERR_OK;
804 }
805
806 bundleMgr_ = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
807 if (bundleMgr_ == nullptr) {
808 HILOG_ERROR("The bundleMgr_ is nullptr.");
809 return ERR_NULL_OBJECT;
810 }
811
812 HILOG_DEBUG("Success.");
813 return ERR_OK;
814 }
815
SetApplicationInfo(const std::shared_ptr<AppExecFwk::ApplicationInfo> & info)816 void ContextImpl::SetApplicationInfo(const std::shared_ptr<AppExecFwk::ApplicationInfo> &info)
817 {
818 if (info == nullptr) {
819 HILOG_ERROR("info is empty");
820 return;
821 }
822 applicationInfo_ = info;
823 }
824
SetResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> & resourceManager)825 void ContextImpl::SetResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> &resourceManager)
826 {
827 HILOG_DEBUG("Start.");
828 resourceManager_ = resourceManager;
829 HILOG_DEBUG("End.");
830 }
831
GetResourceManager() const832 std::shared_ptr<Global::Resource::ResourceManager> ContextImpl::GetResourceManager() const
833 {
834 if (resourceManager_) {
835 return resourceManager_;
836 }
837
838 return parentContext_ != nullptr ? parentContext_->GetResourceManager() : nullptr;
839 }
840
GetApplicationInfo() const841 std::shared_ptr<AppExecFwk::ApplicationInfo> ContextImpl::GetApplicationInfo() const
842 {
843 if (parentContext_ != nullptr) {
844 return parentContext_->GetApplicationInfo();
845 }
846
847 return applicationInfo_;
848 }
849
SetParentContext(const std::shared_ptr<Context> & context)850 void ContextImpl::SetParentContext(const std::shared_ptr<Context> &context)
851 {
852 parentContext_ = context;
853 }
854
GetBundleCodePath() const855 std::string ContextImpl::GetBundleCodePath() const
856 {
857 if (parentContext_ != nullptr) {
858 return parentContext_->GetBundleCodePath();
859 }
860 return (applicationInfo_ != nullptr) ? applicationInfo_->codePath : "";
861 }
862
InitHapModuleInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)863 void ContextImpl::InitHapModuleInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo)
864 {
865 if (hapModuleInfo_ != nullptr || abilityInfo == nullptr) {
866 return;
867 }
868 int errCode = GetBundleManager();
869 if (errCode != ERR_OK) {
870 HILOG_ERROR("failed, errCode: %{public}d.", errCode);
871 return ;
872 }
873
874 hapModuleInfo_ = std::make_shared<AppExecFwk::HapModuleInfo>();
875 if (!bundleMgr_->GetHapModuleInfo(*abilityInfo.get(), *hapModuleInfo_)) {
876 HILOG_ERROR("GetHapModuleInfo failed, will retval false value");
877 }
878 }
879
InitHapModuleInfo(const AppExecFwk::HapModuleInfo & hapModuleInfo)880 void ContextImpl::InitHapModuleInfo(const AppExecFwk::HapModuleInfo &hapModuleInfo)
881 {
882 hapModuleInfo_ = std::make_shared<AppExecFwk::HapModuleInfo>(hapModuleInfo);
883 }
884
GetHapModuleInfo() const885 std::shared_ptr<AppExecFwk::HapModuleInfo> ContextImpl::GetHapModuleInfo() const
886 {
887 if (hapModuleInfo_ == nullptr) {
888 HILOG_DEBUG("hapModuleInfo is empty");
889 }
890 return hapModuleInfo_;
891 }
892
SetFlags(int64_t flags)893 void ContextImpl::SetFlags(int64_t flags)
894 {
895 flags_ = static_cast<uint64_t>(flags_) | static_cast<uint64_t>(CONTEXT_CREATE_BY_SYSTEM_APP);
896 }
897
IsCreateBySystemApp() const898 bool ContextImpl::IsCreateBySystemApp() const
899 {
900 return (static_cast<uint64_t>(flags_) & static_cast<uint64_t>(CONTEXT_CREATE_BY_SYSTEM_APP)) == 1;
901 }
902
903 std::shared_ptr<ApplicationContext> Context::applicationContext_ = nullptr;
904 std::mutex Context::contextMutex_;
905
GetApplicationContext()906 std::shared_ptr<ApplicationContext> Context::GetApplicationContext()
907 {
908 std::lock_guard<std::mutex> lock(contextMutex_);
909 return applicationContext_;
910 }
911
SetToken(const sptr<IRemoteObject> & token)912 void ContextImpl::SetToken(const sptr<IRemoteObject> &token)
913 {
914 if (token == nullptr) {
915 HILOG_DEBUG("application is nullptr");
916 return;
917 }
918 token_ = token;
919 }
920
GetToken()921 sptr<IRemoteObject> ContextImpl::GetToken()
922 {
923 return token_;
924 }
925
CreateDirIfNotExist(const std::string & dirPath,const mode_t & mode) const926 void ContextImpl::CreateDirIfNotExist(const std::string& dirPath, const mode_t& mode) const
927 {
928 if (!OHOS::FileExists(dirPath)) {
929 HILOG_DEBUG("ForceCreateDirectory, dir: %{public}s", dirPath.c_str());
930 bool createDir = OHOS::ForceCreateDirectory(dirPath);
931 if (!createDir) {
932 HILOG_ERROR("create dir %{public}s failed, errno is %{public}d.", dirPath.c_str(), errno);
933 return;
934 }
935 if (mode != 0) {
936 chmod(dirPath.c_str(), mode);
937 }
938 }
939 }
940
SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & config)941 void ContextImpl::SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> &config)
942 {
943 config_ = config;
944 }
945
KillProcessBySelf()946 void ContextImpl::KillProcessBySelf()
947 {
948 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
949 appMgrClient->KillApplicationSelf();
950 }
951
GetProcessRunningInformation(AppExecFwk::RunningProcessInfo & info)952 int32_t ContextImpl::GetProcessRunningInformation(AppExecFwk::RunningProcessInfo &info)
953 {
954 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
955 auto result = appMgrClient->GetProcessRunningInformation(info);
956 HILOG_DEBUG("result is %{public}d.", result);
957 return result;
958 }
959
GetConfiguration() const960 std::shared_ptr<AppExecFwk::Configuration> ContextImpl::GetConfiguration() const
961 {
962 return config_;
963 }
964
GetDeviceType() const965 Global::Resource::DeviceType ContextImpl::GetDeviceType() const
966 {
967 if (deviceType_ != Global::Resource::DeviceType::DEVICE_NOT_SET) {
968 return deviceType_;
969 }
970
971 auto config = GetConfiguration();
972 if (config != nullptr) {
973 auto deviceType = config->GetItem(AAFwk::GlobalConfigurationKey::DEVICE_TYPE);
974 HILOG_DEBUG("deviceType is %{public}s.", deviceType.c_str());
975 deviceType_ = AppExecFwk::ConvertDeviceType(deviceType);
976 }
977
978 if (deviceType_ == Global::Resource::DeviceType::DEVICE_NOT_SET) {
979 deviceType_ = Global::Resource::DeviceType::DEVICE_PHONE;
980 }
981 HILOG_DEBUG("deviceType is %{public}d.", deviceType_);
982 return deviceType_;
983 }
984
GetOverlayModuleInfos(const std::string & bundleName,const std::string & moduleName,std::vector<AppExecFwk::OverlayModuleInfo> & overlayModuleInfos)985 int ContextImpl::GetOverlayModuleInfos(const std::string &bundleName, const std::string &moduleName,
986 std::vector<AppExecFwk::OverlayModuleInfo> &overlayModuleInfos)
987 {
988 int errCode = GetBundleManager();
989 if (errCode != ERR_OK) {
990 HILOG_ERROR("failed, errCode: %{public}d.", errCode);
991 return errCode;
992 }
993
994 auto overlayMgrProxy = bundleMgr_->GetOverlayManagerProxy();
995 if (overlayMgrProxy == nullptr) {
996 HILOG_ERROR("GetOverlayManagerProxy failed.");
997 return ERR_INVALID_VALUE;
998 }
999
1000 auto ret = overlayMgrProxy->GetTargetOverlayModuleInfo(moduleName, overlayModuleInfos);
1001 if (ret != ERR_OK) {
1002 HILOG_DEBUG("GetOverlayModuleInfo form bms failed.");
1003 return ret;
1004 }
1005 std::sort(overlayModuleInfos.begin(), overlayModuleInfos.end(),
1006 [](const AppExecFwk::OverlayModuleInfo& lhs, const AppExecFwk::OverlayModuleInfo& rhs) -> bool {
1007 return lhs.priority > rhs.priority;
1008 });
1009 HILOG_DEBUG("the size of overlay is: %{public}zu", overlayModuleInfos.size());
1010 return ERR_OK;
1011 }
1012
GetAddOverlayPaths(const std::vector<AppExecFwk::OverlayModuleInfo> & overlayModuleInfos)1013 std::vector<std::string> ContextImpl::GetAddOverlayPaths(
1014 const std::vector<AppExecFwk::OverlayModuleInfo> &overlayModuleInfos)
1015 {
1016 std::vector<std::string> addPaths;
1017 for (auto it : overlayModuleInfos) {
1018 auto iter = std::find_if(
1019 overlayModuleInfos_.begin(), overlayModuleInfos_.end(), [it](AppExecFwk::OverlayModuleInfo item) {
1020 return it.moduleName == item.moduleName;
1021 });
1022 if ((iter != overlayModuleInfos_.end()) && (it.state == AppExecFwk::OverlayState::OVERLAY_ENABLE)) {
1023 iter->state = it.state;
1024 ChangeToLocalPath(iter->bundleName, iter->hapPath, iter->hapPath);
1025 HILOG_DEBUG("add path:%{public}s", iter->hapPath.c_str());
1026 addPaths.emplace_back(iter->hapPath);
1027 }
1028 }
1029
1030 return addPaths;
1031 }
1032
GetRemoveOverlayPaths(const std::vector<AppExecFwk::OverlayModuleInfo> & overlayModuleInfos)1033 std::vector<std::string> ContextImpl::GetRemoveOverlayPaths(
1034 const std::vector<AppExecFwk::OverlayModuleInfo> &overlayModuleInfos)
1035 {
1036 std::vector<std::string> removePaths;
1037 for (auto it : overlayModuleInfos) {
1038 auto iter = std::find_if(
1039 overlayModuleInfos_.begin(), overlayModuleInfos_.end(), [it](AppExecFwk::OverlayModuleInfo item) {
1040 return it.moduleName == item.moduleName;
1041 });
1042 if ((iter != overlayModuleInfos_.end()) && (it.state != AppExecFwk::OverlayState::OVERLAY_ENABLE)) {
1043 iter->state = it.state;
1044 ChangeToLocalPath(iter->bundleName, iter->hapPath, iter->hapPath);
1045 HILOG_DEBUG("remove path:%{public}s", iter->hapPath.c_str());
1046 removePaths.emplace_back(iter->hapPath);
1047 }
1048 }
1049
1050 return removePaths;
1051 }
1052
OnOverlayChanged(const EventFwk::CommonEventData & data,const std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,const std::string & bundleName,const std::string & moduleName,const std::string & loadPath)1053 void ContextImpl::OnOverlayChanged(const EventFwk::CommonEventData &data,
1054 const std::shared_ptr<Global::Resource::ResourceManager> &resourceManager, const std::string &bundleName,
1055 const std::string &moduleName, const std::string &loadPath)
1056 {
1057 HILOG_DEBUG("begin.");
1058 auto want = data.GetWant();
1059 std::string action = want.GetAction();
1060 if (action != OVERLAY_STATE_CHANGED) {
1061 HILOG_DEBUG("Not this subscribe, action: %{public}s.", action.c_str());
1062 return;
1063 }
1064 if (GetBundleName() != bundleName) {
1065 HILOG_DEBUG("Not this app, bundleName: %{public}s.", bundleName.c_str());
1066 return;
1067 }
1068 bool isEnable = data.GetWant().GetBoolParam(AppExecFwk::Constants::OVERLAY_STATE, false);
1069 // 1.get overlay hapPath
1070 if (resourceManager == nullptr) {
1071 HILOG_ERROR("resourceManager is nullptr.");
1072 return;
1073 }
1074 if (overlayModuleInfos_.size() == 0) {
1075 HILOG_ERROR("overlayModuleInfos is empty.");
1076 return;
1077 }
1078 std::vector<AppExecFwk::OverlayModuleInfo> overlayModuleInfos;
1079 auto res = GetOverlayModuleInfos(bundleName, moduleName, overlayModuleInfos);
1080 if (res != ERR_OK) {
1081 return;
1082 }
1083
1084 // 2.add/remove overlay hapPath
1085 if (loadPath.empty() || overlayModuleInfos.size() == 0) {
1086 HILOG_WARN("There is not any hapPath in overlayModuleInfo.");
1087 } else {
1088 if (isEnable) {
1089 std::vector<std::string> overlayPaths = GetAddOverlayPaths(overlayModuleInfos);
1090 if (!resourceManager->AddResource(loadPath, overlayPaths)) {
1091 HILOG_ERROR("AddResource error");
1092 }
1093 } else {
1094 std::vector<std::string> overlayPaths = GetRemoveOverlayPaths(overlayModuleInfos);
1095 if (!resourceManager->RemoveResource(loadPath, overlayPaths)) {
1096 HILOG_ERROR("RemoveResource error");
1097 }
1098 }
1099 }
1100 }
1101
ChangeToLocalPath(const std::string & bundleName,const std::string & sourceDir,std::string & localPath)1102 void ContextImpl::ChangeToLocalPath(const std::string &bundleName,
1103 const std::string &sourceDir, std::string &localPath)
1104 {
1105 std::regex pattern(std::string(ABS_CODE_PATH) + std::string(FILE_SEPARATOR) + bundleName);
1106 if (sourceDir.empty()) {
1107 return;
1108 }
1109 if (std::regex_search(localPath, std::regex(bundleName))) {
1110 localPath = std::regex_replace(localPath, pattern, std::string(LOCAL_CODE_PATH));
1111 } else {
1112 localPath = std::regex_replace(localPath, std::regex(ABS_CODE_PATH), LOCAL_BUNDLES);
1113 }
1114 }
1115
ClearUpApplicationData()1116 void ContextImpl::ClearUpApplicationData()
1117 {
1118 int errCode = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->ClearUpApplicationDataBySelf();
1119 if (errCode != ERR_OK) {
1120 HILOG_ERROR("Delete bundle side user data by self is fail.");
1121 return;
1122 }
1123 }
1124 } // namespace AbilityRuntime
1125 } // namespace OHOS
1126