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