• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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