1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "context_container.h"
16 
17 #include <regex>
18 
19 #include "ability_manager_client.h"
20 #include "ability_manager_errors.h"
21 #include "app_context.h"
22 #include "bundle_constants.h"
23 #include "bundle_mgr_helper.h"
24 #include "constants.h"
25 #include "hilog_tag_wrapper.h"
26 #include "parameters.h"
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 // for api7 demo special
31 constexpr int CURRENT_ACCOUNT_ID = 100;
32 const int32_t TYPE_RESERVE = 1;
33 const int32_t TYPE_OTHERS = 2;
34 
AttachBaseContext(const std::shared_ptr<ContextDeal> & base)35 void ContextContainer::AttachBaseContext(const std::shared_ptr<ContextDeal> &base)
36 {
37     if (base == nullptr) {
38         TAG_LOGE(AAFwkTag::APPKIT, "base is nullptr");
39         return;
40     }
41     baseContext_ = base;
42 }
43 
DetachBaseContext()44 void ContextContainer::DetachBaseContext()
45 {
46     if (baseContext_ != nullptr) {
47         baseContext_.reset();
48     }
49     baseContext_ = nullptr;
50 }
51 
GetProcessInfo() const52 std::shared_ptr<ProcessInfo> ContextContainer::GetProcessInfo() const
53 {
54     return processInfo_;
55 }
56 
SetProcessInfo(const std::shared_ptr<ProcessInfo> & info)57 void ContextContainer::SetProcessInfo(const std::shared_ptr<ProcessInfo> &info)
58 {
59     if (info == nullptr) {
60         TAG_LOGE(AAFwkTag::APPKIT, "info is empty");
61         return;
62     }
63     processInfo_ = info;
64 }
65 
GetApplicationInfo() const66 std::shared_ptr<ApplicationInfo> ContextContainer::GetApplicationInfo() const
67 {
68     if (baseContext_ != nullptr) {
69         return baseContext_->GetApplicationInfo();
70     } else {
71         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
72         return nullptr;
73     }
74 }
75 
GetApplicationContext() const76 std::shared_ptr<Context> ContextContainer::GetApplicationContext() const
77 {
78     if (baseContext_ != nullptr) {
79         return baseContext_->GetApplicationContext();
80     } else {
81         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
82         return nullptr;
83     }
84 }
85 
GetBundleCodePath()86 std::string ContextContainer::GetBundleCodePath()
87 {
88     if (baseContext_ != nullptr) {
89         return baseContext_->GetBundleCodePath();
90     } else {
91         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
92         return "";
93     }
94 }
95 
GetAbilityInfo()96 const std::shared_ptr<AbilityInfo> ContextContainer::GetAbilityInfo()
97 {
98     if (baseContext_ != nullptr) {
99         return baseContext_->GetAbilityInfo();
100     } else {
101         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
102         return nullptr;
103     }
104 }
105 
GetContext()106 std::shared_ptr<Context> ContextContainer::GetContext()
107 {
108     if (baseContext_ != nullptr) {
109         return baseContext_->GetContext();
110     } else {
111         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
112         return nullptr;
113     }
114 }
115 
GetBundleManager() const116 std::shared_ptr<BundleMgrHelper> ContextContainer::GetBundleManager() const
117 {
118     if (baseContext_ != nullptr) {
119         return baseContext_->GetBundleManager();
120     } else {
121         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
122         return nullptr;
123     }
124 }
125 
GetResourceManager() const126 std::shared_ptr<Global::Resource::ResourceManager> ContextContainer::GetResourceManager() const
127 {
128     if (baseContext_ != nullptr) {
129         return baseContext_->GetResourceManager();
130     } else {
131         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
132         return nullptr;
133     }
134 }
135 
GetDatabaseDir()136 std::string ContextContainer::GetDatabaseDir()
137 {
138     if (baseContext_ != nullptr) {
139         return baseContext_->GetDatabaseDir();
140     } else {
141         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
142         return "";
143     }
144 }
145 
GetDataDir()146 std::string ContextContainer::GetDataDir()
147 {
148     if (baseContext_ != nullptr) {
149         return baseContext_->GetDataDir();
150     } else {
151         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
152         return "";
153     }
154 }
155 
GetDir(const std::string & name,int mode)156 std::string ContextContainer::GetDir(const std::string &name, int mode)
157 {
158     if (baseContext_ != nullptr) {
159         return baseContext_->GetDir(name, mode);
160     } else {
161         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
162         return "";
163     }
164 }
165 
GetFilesDir()166 std::string ContextContainer::GetFilesDir()
167 {
168     if (baseContext_ != nullptr) {
169         return baseContext_->GetFilesDir();
170     } else {
171         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
172         return "";
173     }
174 }
175 
GetBundleName() const176 std::string ContextContainer::GetBundleName() const
177 {
178     if (baseContext_ != nullptr) {
179         return baseContext_->GetBundleName();
180     } else {
181         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
182         return "";
183     }
184 }
185 
GetBundleResourcePath()186 std::string ContextContainer::GetBundleResourcePath()
187 {
188     if (baseContext_ != nullptr) {
189         return baseContext_->GetBundleResourcePath();
190     } else {
191         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
192         return "";
193     }
194 }
195 
GetAbilityManager()196 sptr<AAFwk::IAbilityManager> ContextContainer::GetAbilityManager()
197 {
198     if (baseContext_ != nullptr) {
199         return baseContext_->GetAbilityManager();
200     } else {
201         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
202         return nullptr;
203     }
204 }
205 
GetAppType()206 std::string ContextContainer::GetAppType()
207 {
208     if (baseContext_ != nullptr) {
209         return baseContext_->GetAppType();
210     } else {
211         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
212         return "";
213     }
214 }
215 
SetPattern(int patternId)216 void ContextContainer::SetPattern(int patternId)
217 {
218     if (baseContext_ != nullptr) {
219         baseContext_->SetPattern(patternId);
220     } else {
221         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
222     }
223 }
224 
GetHapModuleInfo()225 std::shared_ptr<HapModuleInfo> ContextContainer::GetHapModuleInfo()
226 {
227     if (baseContext_ != nullptr) {
228         return baseContext_->GetHapModuleInfo();
229     } else {
230         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
231         return nullptr;
232     }
233 }
234 
GetProcessName()235 std::string ContextContainer::GetProcessName()
236 {
237     return (processInfo_ != nullptr) ? processInfo_->GetProcessName() : "";
238 }
239 
CreateBundleContext(std::string bundleName,int flag,int accountId)240 std::shared_ptr<Context> ContextContainer::CreateBundleContext(std::string bundleName, int flag, int accountId)
241 {
242     if (bundleName.empty()) {
243         TAG_LOGE(AAFwkTag::APPKIT, "The bundleName is empty");
244         return nullptr;
245     }
246 
247     if (strcmp(bundleName.c_str(), GetBundleName().c_str()) == 0) {
248         return GetApplicationContext();
249     }
250 
251     std::shared_ptr<BundleMgrHelper> bundleMgr = GetBundleManager();
252     if (bundleMgr == nullptr) {
253         TAG_LOGE(AAFwkTag::APPKIT, "The bundleMgr is nullptr");
254         return nullptr;
255     }
256 
257     BundleInfo bundleInfo;
258     TAG_LOGI(AAFwkTag::APPKIT, "Length: %{public}zu, bundleName: %{public}s, accountId is %{public}d",
259         bundleName.length(),
260         bundleName.c_str(),
261         accountId);
262     int realAccountId = CURRENT_ACCOUNT_ID;
263     if (accountId != DEFAULT_ACCOUNT_ID) {
264         realAccountId = accountId;
265     }
266     bundleMgr->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, realAccountId);
267 
268     if (bundleInfo.name.empty() || bundleInfo.applicationInfo.name.empty()) {
269         TAG_LOGE(AAFwkTag::APPKIT, "Failed to get Bundle Info");
270         return nullptr;
271     }
272 
273     std::shared_ptr<AppContext> appContext = std::make_shared<AppContext>();
274     std::shared_ptr<ContextDeal> deal = std::make_shared<ContextDeal>(true);
275 
276     // init resourceManager.
277     InitResourceManager(bundleInfo, deal);
278 
279     deal->SetApplicationInfo(std::make_shared<ApplicationInfo>(bundleInfo.applicationInfo));
280     appContext->AttachBaseContext(deal);
281     return appContext;
282 }
283 
InitResourceManager(BundleInfo & bundleInfo,std::shared_ptr<ContextDeal> & deal)284 void ContextContainer::InitResourceManager(BundleInfo &bundleInfo, std::shared_ptr<ContextDeal> &deal)
285 {
286     TAG_LOGD(AAFwkTag::APPKIT, "InitResourceManager begin, bundleName:%{public}s, codePath:%{public}s",
287         bundleInfo.name.c_str(), bundleInfo.applicationInfo.codePath.c_str());
288     if (deal == nullptr) {
289         TAG_LOGE(AAFwkTag::APPKIT, "InitResourceManager deal is nullptr");
290         return;
291     }
292     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
293     std::string moduleName;
294     std::string hapPath;
295     std::vector<std::string> overlayPaths;
296     int32_t appType;
297     if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_RESERVE)) {
298         appType = TYPE_RESERVE;
299     } else if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_OTHERS)) {
300         appType = TYPE_OTHERS;
301     } else {
302         appType = 0;
303     }
304     if (bundleInfo.applicationInfo.codePath == std::to_string(TYPE_RESERVE) ||
305         bundleInfo.applicationInfo.codePath == std::to_string(TYPE_OTHERS)) {
306         std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager(
307             bundleInfo.name, moduleName, hapPath, overlayPaths, *resConfig, appType));
308         if (resourceManager == nullptr) {
309             TAG_LOGE(AAFwkTag::APPKIT, "failed to create resourceManager");
310             return;
311         }
312         deal->initResourceManager(resourceManager);
313         return;
314     }
315 
316     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager(
317         bundleInfo.name, moduleName, hapPath, overlayPaths, *resConfig, appType));
318     if (resourceManager == nullptr) {
319         TAG_LOGE(AAFwkTag::APPKIT, "create resourceManager failed");
320         return;
321     }
322     LoadResources(bundleInfo, resourceManager, resConfig, deal);
323 }
324 
LoadResources(BundleInfo & bundleInfo,std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,std::unique_ptr<Global::Resource::ResConfig> & resConfig,std::shared_ptr<ContextDeal> & deal)325 void ContextContainer::LoadResources(BundleInfo &bundleInfo,
326     std::shared_ptr<Global::Resource::ResourceManager> &resourceManager,
327     std::unique_ptr<Global::Resource::ResConfig> &resConfig, std::shared_ptr<ContextDeal> &deal)
328 {
329     TAG_LOGD(AAFwkTag::APPKIT, "hapModuleInfos count: %{public}zu",
330         bundleInfo.hapModuleInfos.size());
331     std::regex pattern(AbilityBase::Constants::ABS_CODE_PATH);
332     for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
333         std::string loadPath;
334         if (!hapModuleInfo.hapPath.empty()) {
335             loadPath = hapModuleInfo.hapPath;
336         } else {
337             loadPath = hapModuleInfo.resourcePath;
338         }
339         if (loadPath.empty()) {
340             continue;
341         }
342         loadPath = std::regex_replace(loadPath, pattern, AbilityBase::Constants::LOCAL_BUNDLES);
343         TAG_LOGD(AAFwkTag::APPKIT, "loadPath: %{private}s", loadPath.c_str());
344         if (!resourceManager->AddResource(loadPath.c_str())) {
345             TAG_LOGE(AAFwkTag::APPKIT, "ContextContainer::InitResourceManager AddResource failed");
346         }
347     }
348 
349     resConfig->SetLocaleInfo("zh", "Hans", "CN");
350 #ifdef SUPPORT_GRAPHICS
351     if (resConfig->GetLocaleInfo() != nullptr) {
352         TAG_LOGI(AAFwkTag::APPKIT,
353             "language: %{public}s, script: %{public}s, region: %{public}s,",
354             resConfig->GetLocaleInfo()->getLanguage(),
355             resConfig->GetLocaleInfo()->getScript(),
356             resConfig->GetLocaleInfo()->getCountry());
357     } else {
358         TAG_LOGI(AAFwkTag::APPKIT, "language: GetLocaleInfo is null.");
359     }
360 #endif
361     resourceManager->UpdateResConfig(*resConfig);
362     deal->initResourceManager(resourceManager);
363 }
364 
GetCaller()365 Uri ContextContainer::GetCaller()
366 {
367     Uri uri(uriString_);
368     return uri;
369 }
370 
SetUriString(const std::string & uri)371 void ContextContainer::SetUriString(const std::string &uri)
372 {
373     uriString_ = uri;
374 }
375 
GetString(int resId)376 std::string ContextContainer::GetString(int resId)
377 {
378     if (baseContext_ != nullptr) {
379         std::string ret = baseContext_->GetString(resId);
380         return ret;
381     } else {
382         TAG_LOGE(AAFwkTag::APPKIT, "GetString baseContext_ is nullptr");
383         return "";
384     }
385 }
386 
GetStringArray(int resId)387 std::vector<std::string> ContextContainer::GetStringArray(int resId)
388 {
389     if (baseContext_ != nullptr) {
390         return baseContext_->GetStringArray(resId);
391     } else {
392         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
393         return std::vector<std::string>();
394     }
395 }
396 
GetIntArray(int resId)397 std::vector<int> ContextContainer::GetIntArray(int resId)
398 {
399     if (baseContext_ != nullptr) {
400         return baseContext_->GetIntArray(resId);
401     } else {
402         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
403         return std::vector<int>();
404     }
405 }
406 
GetTheme()407 std::map<std::string, std::string> ContextContainer::GetTheme()
408 {
409     if (baseContext_ != nullptr) {
410         return baseContext_->GetTheme();
411     } else {
412         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
413         return std::map<std::string, std::string>();
414     }
415 }
416 
SetTheme(int themeId)417 void ContextContainer::SetTheme(int themeId)
418 {
419     if (baseContext_ != nullptr) {
420         baseContext_->SetTheme(themeId);
421     } else {
422         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
423     }
424 }
425 
GetPattern()426 std::map<std::string, std::string> ContextContainer::GetPattern()
427 {
428     if (baseContext_ != nullptr) {
429         return baseContext_->GetPattern();
430     } else {
431         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
432         return std::map<std::string, std::string>();
433     }
434 }
435 
GetColor(int resId)436 int ContextContainer::GetColor(int resId)
437 {
438     if (baseContext_ != nullptr) {
439         return baseContext_->GetColor(resId);
440     } else {
441         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
442         return INVALID_RESOURCE_VALUE;
443     }
444 }
445 
GetThemeId()446 int ContextContainer::GetThemeId()
447 {
448     if (baseContext_ != nullptr) {
449         return baseContext_->GetThemeId();
450     } else {
451         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
452         return -1;
453     }
454 }
455 
GetDisplayOrientation()456 int ContextContainer::GetDisplayOrientation()
457 {
458     if (baseContext_ != nullptr) {
459         return baseContext_->GetDisplayOrientation();
460     } else {
461         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
462         return static_cast<int>(DisplayOrientation::UNSPECIFIED);
463     }
464 }
465 
GetPreferencesDir()466 std::string ContextContainer::GetPreferencesDir()
467 {
468     if (baseContext_ != nullptr) {
469         return baseContext_->GetPreferencesDir();
470     } else {
471         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
472         return "";
473     }
474 }
475 
SetColorMode(int mode)476 void ContextContainer::SetColorMode(int mode)
477 {
478     if (baseContext_ == nullptr) {
479         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
480         return;
481     }
482 
483     baseContext_->SetColorMode(mode);
484 }
485 
GetColorMode()486 int ContextContainer::GetColorMode()
487 {
488     if (baseContext_ == nullptr) {
489         TAG_LOGE(AAFwkTag::APPKIT, "baseContext_ is nullptr");
490         return -1;
491     }
492 
493     return baseContext_->GetColorMode();
494 }
495 
GetMissionId()496 int ContextContainer::GetMissionId()
497 {
498     return lifeCycleStateInfo_.missionId;
499 }
500 
SetLifeCycleStateInfo(const AAFwk::LifeCycleStateInfo & info)501 void ContextContainer::SetLifeCycleStateInfo(const AAFwk::LifeCycleStateInfo &info)
502 {
503     lifeCycleStateInfo_ = info;
504 }
505 
GetLifeCycleStateInfo() const506 AAFwk::LifeCycleStateInfo ContextContainer::GetLifeCycleStateInfo() const
507 {
508     return lifeCycleStateInfo_;
509 }
510 }  // namespace AppExecFwk
511 }  // namespace OHOS
512