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