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