1 /*
2 * Copyright (c) 2023-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
16 #include "ability_stage_context.h"
17
18 #include <cstring>
19
20 #include "hilog_tag_wrapper.h"
21
22 namespace OHOS {
23 namespace AbilityRuntime {
24 namespace {
25 constexpr const char *CONTEXT_DISTRIBUTEDFILES("distributedfiles");
26 constexpr const char *CONTEXT_CLOUD("cloud");
27 constexpr const char *CONTEXT_FILE_SEPARATOR("/");
28 constexpr const char *CONTEXT_FILE_OPPOSITE_SEPARATOR("\\");
29 constexpr const char *CONTEXT_BASE("base");
30 constexpr const char *CONTEXT_CACHE("cache");
31 constexpr const char *CONTEXT_PREFERENCES("preferences");
32 constexpr const char *CONTEXT_DATABASE("database");
33 constexpr const char *CONTEXT_TEMP("temp");
34 constexpr const char *CONTEXT_FILES("files");
35 constexpr const char *CONTEXT_HAPS("haps");
36 constexpr const char *CONTEXT_ASSET("asset");
37 constexpr const char *CONTEXT_ELS[] = {"el1", "el2", "el3", "el4", "el5"};
38 constexpr const char *CONTEXT_RESOURCE_BASE("/data/storage/el1/bundle");
39 constexpr const char *CONTEXT_RESOURCE_END("/resources/resfile");
40 constexpr int DIR_DEFAULT_PERM = 0770;
41 }
42 const size_t AbilityStageContext::CONTEXT_TYPE_ID(std::hash<const char*> {} ("AbilityStageContext"));
43
AbilityStageContext()44 AbilityStageContext::AbilityStageContext()
45 {
46 contextImpl_ = std::make_shared<ContextImpl>();
47 }
GetConfiguration()48 std::shared_ptr<AppExecFwk::Configuration> AbilityStageContext::GetConfiguration()
49 {
50 if (contextImpl_ == nullptr) {
51 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
52 return nullptr;
53 }
54
55 return contextImpl_->GetConfiguration();
56 }
57
SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)58 void AbilityStageContext::SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> &configuration)
59 {
60 if (contextImpl_ == nullptr) {
61 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
62 return;
63 }
64
65 contextImpl_->SetConfiguration(configuration);
66 }
67
GetApplicationInfo() const68 std::shared_ptr<AppExecFwk::ApplicationInfo> AbilityStageContext::GetApplicationInfo() const
69 {
70 if (contextImpl_ == nullptr) {
71 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
72 return nullptr;
73 }
74
75 return contextImpl_->GetApplicationInfo();
76 }
77
SetApplicationInfo(const std::shared_ptr<AppExecFwk::ApplicationInfo> & info)78 void AbilityStageContext::SetApplicationInfo(const std::shared_ptr<AppExecFwk::ApplicationInfo> &info)
79 {
80 if (contextImpl_ == nullptr) {
81 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
82 return;
83 }
84
85 contextImpl_->SetApplicationInfo(info);
86 }
87
GetHapModuleInfo() const88 std::shared_ptr<AppExecFwk::HapModuleInfo> AbilityStageContext::GetHapModuleInfo() const
89 {
90 if (contextImpl_ == nullptr) {
91 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
92 return nullptr;
93 }
94
95 return contextImpl_->GetHapModuleInfo();
96 }
97
SetHapModuleInfo(const std::shared_ptr<AppExecFwk::HapModuleInfo> & info)98 void AbilityStageContext::SetHapModuleInfo(const std::shared_ptr<AppExecFwk::HapModuleInfo> &info)
99 {
100 if (contextImpl_ == nullptr) {
101 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
102 return;
103 }
104
105 contextImpl_->InitHapModuleInfo(*info);
106 }
107
GetOptions()108 Options AbilityStageContext::GetOptions()
109 {
110 return options_;
111 }
112
SetOptions(const Options & options)113 void AbilityStageContext::SetOptions(const Options &options)
114 {
115 options_ = options;
116
117 auto pos = options_.previewPath.find(CONTEXT_FILE_SEPARATOR);
118 if (pos == std::string::npos) {
119 fileSeparator_ = CONTEXT_FILE_OPPOSITE_SEPARATOR;
120 }
121
122 if (contextImpl_ != nullptr) {
123 contextImpl_->SetOptions(options);
124 }
125 }
126
GetBundleName() const127 std::string AbilityStageContext::GetBundleName() const
128 {
129 return options_.bundleName;
130 }
131
GetBundleCodePath()132 std::string AbilityStageContext::GetBundleCodePath()
133 {
134 std::string path;
135 auto pos = options_.assetPath.find(CONTEXT_ASSET);
136 if (pos != std::string::npos) {
137 path = options_.assetPath.substr(0, pos);
138 }
139 return path;
140 }
141
GetBundleCodeDir()142 std::string AbilityStageContext::GetBundleCodeDir()
143 {
144 return GetPreviewPath();
145 }
146
GetCacheDir()147 std::string AbilityStageContext::GetCacheDir()
148 {
149 if (GetPreviewPath().empty()) {
150 return "";
151 }
152
153 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_CACHE;
154 CreateMultiDir(dir);
155 return dir;
156 }
157
GetTempDir()158 std::string AbilityStageContext::GetTempDir()
159 {
160 if (GetPreviewPath().empty()) {
161 return "";
162 }
163
164 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_TEMP;
165 CreateMultiDir(dir);
166 return dir;
167 }
168
GetResourceDir()169 std::string AbilityStageContext::GetResourceDir()
170 {
171 std::shared_ptr<AppExecFwk::HapModuleInfo> hapModuleInfoPtr = GetHapModuleInfo();
172 if (hapModuleInfoPtr == nullptr || hapModuleInfoPtr->moduleName.empty()) {
173 return "";
174 }
175 auto dir = std::string(CONTEXT_RESOURCE_BASE) +
176 CONTEXT_FILE_SEPARATOR + hapModuleInfoPtr->moduleName + CONTEXT_RESOURCE_END;
177 if (Access(dir)) {
178 return dir;
179 }
180 return "";
181 }
182
GetFilesDir()183 std::string AbilityStageContext::GetFilesDir()
184 {
185 if (GetPreviewPath().empty()) {
186 return "";
187 }
188
189 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_FILES;
190 CreateMultiDir(dir);
191 return dir;
192 }
193
GetDatabaseDir()194 std::string AbilityStageContext::GetDatabaseDir()
195 {
196 auto preivewDir = GetPreviewPath();
197 if (preivewDir.empty()) {
198 return "";
199 }
200
201 auto dir = preivewDir + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_DATABASE +
202 fileSeparator_ + options_.moduleName;
203 CreateMultiDir(dir);
204 return dir;
205 }
206
GetPreferencesDir()207 std::string AbilityStageContext::GetPreferencesDir()
208 {
209 if (GetPreviewPath().empty()) {
210 return "";
211 }
212
213 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_PREFERENCES;
214 CreateMultiDir(dir);
215 return dir;
216 }
217
GetDistributedFilesDir()218 std::string AbilityStageContext::GetDistributedFilesDir()
219 {
220 auto preivewDir = GetPreviewPath();
221 if (preivewDir.empty()) {
222 return "";
223 }
224
225 auto dir = preivewDir + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_DISTRIBUTEDFILES;
226 CreateMultiDir(dir);
227 return dir;
228 }
229
GetCloudFileDir()230 std::string AbilityStageContext::GetCloudFileDir()
231 {
232 auto preivewDir = GetPreviewPath();
233 if (preivewDir.empty()) {
234 return "";
235 }
236
237 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_CLOUD;
238 CreateMultiDir(dir);
239 return dir;
240 }
241
SwitchArea(int mode)242 void AbilityStageContext::SwitchArea(int mode)
243 {
244 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called, mode:%{public}d", mode);
245 if (mode < 0 || mode >= static_cast<int>(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0]))) {
246 TAG_LOGE(AAFwkTag::ABILITY_SIM, "mode invalid");
247 return;
248 }
249 currArea_ = CONTEXT_ELS[mode];
250 }
251
GetArea()252 int AbilityStageContext::GetArea()
253 {
254 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
255 int mode = -1;
256 for (int i = 0; i < static_cast<int>(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0])); i++) {
257 if (currArea_ == CONTEXT_ELS[i]) {
258 mode = i;
259 break;
260 }
261 }
262 if (mode == -1) {
263 TAG_LOGE(AAFwkTag::ABILITY_SIM, "Not find mode");
264 return EL_DEFAULT;
265 }
266 return mode;
267 }
268
GetBaseDir()269 std::string AbilityStageContext::GetBaseDir()
270 {
271 auto previewPath = GetPreviewPath();
272 if (previewPath.empty()) {
273 return "";
274 }
275
276 return previewPath + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_BASE + fileSeparator_ +
277 CONTEXT_HAPS + fileSeparator_ + options_.moduleName;
278 }
279
GetPreviewPath()280 std::string AbilityStageContext::GetPreviewPath()
281 {
282 return options_.previewPath;
283 }
284
Access(const std::string & path)285 bool AbilityStageContext::Access(const std::string &path)
286 {
287 TAG_LOGD(AAFwkTag::ABILITY_SIM, "Access: dir: %{public}s", path.c_str());
288 std::unique_ptr<uv_fs_t, decltype(AbilityStageContext::FsReqCleanup)*> access_req = {
289 new uv_fs_t, AbilityStageContext::FsReqCleanup };
290 if (!access_req) {
291 TAG_LOGE(AAFwkTag::ABILITY_SIM, "request heap memory failed");
292 return false;
293 }
294
295 return (uv_fs_access(nullptr, access_req.get(), path.c_str(), 0, nullptr) == 0);
296 }
297
Mkdir(const std::string & path)298 void AbilityStageContext::Mkdir(const std::string &path)
299 {
300 TAG_LOGD(AAFwkTag::ABILITY_SIM, "Mkdir: dir: %{public}s", path.c_str());
301 std::unique_ptr<uv_fs_t, decltype(AbilityStageContext::FsReqCleanup)*> mkdir_req = {
302 new uv_fs_t, AbilityStageContext::FsReqCleanup };
303 if (!mkdir_req) {
304 TAG_LOGE(AAFwkTag::ABILITY_SIM, "request heap memory failed");
305 return;
306 }
307
308 int ret = uv_fs_mkdir(nullptr, mkdir_req.get(), path.c_str(), DIR_DEFAULT_PERM, nullptr);
309 if (ret < 0) {
310 TAG_LOGE(AAFwkTag::ABILITY_SIM, "create directory failed");
311 }
312 }
313
CreateMultiDir(const std::string & path)314 bool AbilityStageContext::CreateMultiDir(const std::string &path)
315 {
316 if (path.empty()) {
317 TAG_LOGD(AAFwkTag::ABILITY_SIM, "empty path");
318 return false;
319 }
320
321 if (Access(path)) {
322 TAG_LOGD(AAFwkTag::ABILITY_SIM, "path existed");
323 return true;
324 }
325
326 std::string tempStr = path;
327 tempStr += fileSeparator_;
328
329 std::string::size_type pos = 0;
330 std::string::size_type prePos = 0;
331 std::string strFolderPath;
332
333 while ((pos = tempStr.find(fileSeparator_, pos)) != std::string::npos) {
334 strFolderPath = tempStr.substr(0, pos);
335 if (Access(strFolderPath)) {
336 pos = pos + 1;
337 prePos = pos;
338 continue;
339 }
340
341 Mkdir(strFolderPath);
342 pos = pos + 1;
343 prePos = pos;
344 }
345
346 return Access(tempStr);
347 }
348
FsReqCleanup(uv_fs_t * req)349 void AbilityStageContext::FsReqCleanup(uv_fs_t *req)
350 {
351 uv_fs_req_cleanup(req);
352 if (req) {
353 delete req;
354 req = nullptr;
355 }
356 }
357
CreateModuleContext(const std::string & moduleName)358 std::shared_ptr<Context> AbilityStageContext::CreateModuleContext(const std::string &moduleName)
359 {
360 if (contextImpl_ == nullptr) {
361 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
362 return nullptr;
363 }
364 return contextImpl_->CreateModuleContext(moduleName);
365 }
366
CreateModuleContext(const std::string & bundleName,const std::string & moduleName)367 std::shared_ptr<Context> AbilityStageContext::CreateModuleContext(
368 const std::string &bundleName, const std::string &moduleName)
369 {
370 if (contextImpl_ == nullptr) {
371 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
372 return nullptr;
373 }
374 return contextImpl_->CreateModuleContext(bundleName, moduleName);
375 }
376
GetResourceManager() const377 std::shared_ptr<Global::Resource::ResourceManager> AbilityStageContext::GetResourceManager() const
378 {
379 if (contextImpl_ == nullptr) {
380 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null contextImpl");
381 return nullptr;
382 }
383 return contextImpl_->GetResourceManager();
384 }
385
SetResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> & resMgr)386 void AbilityStageContext::SetResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> &resMgr)
387 {
388 if (contextImpl_) {
389 contextImpl_->SetResourceManager(resMgr);
390 }
391 }
392 } // namespace AbilityRuntime
393 } // namespace OHOS
394