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