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"};
36 constexpr int DIR_DEFAULT_PERM = 0770;
37 }
GetConfiguration()38 std::shared_ptr<AppExecFwk::Configuration> AbilityStageContext::GetConfiguration()
39 {
40 return configuration_;
41 }
42
SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)43 void AbilityStageContext::SetConfiguration(const std::shared_ptr<AppExecFwk::Configuration> &configuration)
44 {
45 configuration_ = configuration;
46 }
47
GetApplicationInfo() const48 std::shared_ptr<AppExecFwk::ApplicationInfo> AbilityStageContext::GetApplicationInfo() const
49 {
50 return applicationInfo_;
51 }
52
GetHapModuleInfo() const53 std::shared_ptr<AppExecFwk::HapModuleInfo> AbilityStageContext::GetHapModuleInfo() const
54 {
55 return hapModuleInfo_;
56 }
57
GetOptions()58 Options AbilityStageContext::GetOptions()
59 {
60 return options_;
61 }
62
SetOptions(const Options & options)63 void AbilityStageContext::SetOptions(const Options &options)
64 {
65 options_ = options;
66
67 auto pos = options_.previewPath.find(CONTEXT_FILE_SEPARATOR);
68 if (pos == std::string::npos) {
69 fileSeparator_ = CONTEXT_FILE_OPPOSITE_SEPARATOR;
70 }
71
72 applicationInfo_ = std::make_shared<AppExecFwk::ApplicationInfo>(options.applicationInfo);
73 if (applicationInfo_ != nullptr) {
74 applicationInfo_->name = options_.bundleName;
75 }
76 hapModuleInfo_ = std::make_shared<AppExecFwk::HapModuleInfo>(options.hapModuleInfo);
77 if (hapModuleInfo_ != nullptr) {
78 for (auto &ability : hapModuleInfo_->abilityInfos) {
79 ability.bundleName = options_.bundleName;
80 ability.moduleName = options_.moduleName;
81 }
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
GetFilesDir()127 std::string AbilityStageContext::GetFilesDir()
128 {
129 if (GetPreviewPath().empty()) {
130 return "";
131 }
132
133 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_FILES;
134 CreateMultiDir(dir);
135 return dir;
136 }
137
GetDatabaseDir()138 std::string AbilityStageContext::GetDatabaseDir()
139 {
140 auto preivewDir = GetPreviewPath();
141 if (preivewDir.empty()) {
142 return "";
143 }
144
145 auto dir = preivewDir + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_DATABASE +
146 fileSeparator_ + options_.moduleName;
147 CreateMultiDir(dir);
148 return dir;
149 }
150
GetPreferencesDir()151 std::string AbilityStageContext::GetPreferencesDir()
152 {
153 if (GetPreviewPath().empty()) {
154 return "";
155 }
156
157 auto dir = GetBaseDir() + fileSeparator_ + CONTEXT_PREFERENCES;
158 CreateMultiDir(dir);
159 return dir;
160 }
161
GetDistributedFilesDir()162 std::string AbilityStageContext::GetDistributedFilesDir()
163 {
164 auto preivewDir = GetPreviewPath();
165 if (preivewDir.empty()) {
166 return "";
167 }
168
169 auto dir = preivewDir + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_DISTRIBUTEDFILES;
170 CreateMultiDir(dir);
171 return dir;
172 }
173
SwitchArea(int mode)174 void AbilityStageContext::SwitchArea(int mode)
175 {
176 HILOG_DEBUG("called, mode:%{public}d.", mode);
177 if (mode < 0 || mode >= static_cast<int>(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0]))) {
178 HILOG_ERROR("mode is invalid.");
179 return;
180 }
181 currArea_ = CONTEXT_ELS[mode];
182 }
183
GetArea()184 int AbilityStageContext::GetArea()
185 {
186 HILOG_DEBUG("called");
187 int mode = -1;
188 for (int i = 0; i < static_cast<int>(sizeof(CONTEXT_ELS) / sizeof(CONTEXT_ELS[0])); i++) {
189 if (currArea_ == CONTEXT_ELS[i]) {
190 mode = i;
191 break;
192 }
193 }
194 if (mode == -1) {
195 HILOG_ERROR("Not find mode.");
196 return EL_DEFAULT;
197 }
198 return mode;
199 }
200
GetBaseDir()201 std::string AbilityStageContext::GetBaseDir()
202 {
203 auto previewPath = GetPreviewPath();
204 if (previewPath.empty()) {
205 return "";
206 }
207
208 return previewPath + fileSeparator_ + currArea_ + fileSeparator_ + CONTEXT_BASE + fileSeparator_ +
209 CONTEXT_HAPS + fileSeparator_ + options_.moduleName;
210 }
211
GetPreviewPath()212 std::string AbilityStageContext::GetPreviewPath()
213 {
214 return options_.previewPath;
215 }
216
Access(const std::string & path)217 bool AbilityStageContext::Access(const std::string &path)
218 {
219 HILOG_DEBUG("Access: dir: %{public}s", path.c_str());
220 std::unique_ptr<uv_fs_t, decltype(AbilityStageContext::FsReqCleanup)*> access_req = {
221 new uv_fs_t, AbilityStageContext::FsReqCleanup };
222 if (!access_req) {
223 HILOG_ERROR("Failed to request heap memory.");
224 return false;
225 }
226
227 return (uv_fs_access(nullptr, access_req.get(), path.c_str(), 0, nullptr) == 0);
228 }
229
Mkdir(const std::string & path)230 void AbilityStageContext::Mkdir(const std::string &path)
231 {
232 HILOG_DEBUG("Mkdir: dir: %{public}s", path.c_str());
233 std::unique_ptr<uv_fs_t, decltype(AbilityStageContext::FsReqCleanup)*> mkdir_req = {
234 new uv_fs_t, AbilityStageContext::FsReqCleanup };
235 if (!mkdir_req) {
236 HILOG_ERROR("Failed to request heap memory.");
237 return;
238 }
239
240 int ret = uv_fs_mkdir(nullptr, mkdir_req.get(), path.c_str(), DIR_DEFAULT_PERM, nullptr);
241 if (ret < 0) {
242 HILOG_ERROR("Failed to create directory");
243 }
244 }
245
CreateMultiDir(const std::string & path)246 bool AbilityStageContext::CreateMultiDir(const std::string &path)
247 {
248 if (path.empty()) {
249 HILOG_DEBUG("path is empty");
250 return false;
251 }
252
253 if (Access(path)) {
254 HILOG_DEBUG("path is already exist");
255 return true;
256 }
257
258 std::string tempStr = path;
259 tempStr += fileSeparator_;
260
261 std::string::size_type pos = 0;
262 std::string::size_type prePos = 0;
263 std::string strFolderPath;
264
265 while ((pos = tempStr.find(fileSeparator_, pos)) != std::string::npos) {
266 strFolderPath = tempStr.substr(0, pos);
267 if (Access(strFolderPath)) {
268 pos = pos + 1;
269 prePos = pos;
270 continue;
271 }
272
273 Mkdir(strFolderPath);
274 pos = pos + 1;
275 prePos = pos;
276 }
277
278 return Access(tempStr);
279 }
280
FsReqCleanup(uv_fs_t * req)281 void AbilityStageContext::FsReqCleanup(uv_fs_t *req)
282 {
283 uv_fs_req_cleanup(req);
284 if (req) {
285 delete req;
286 req = nullptr;
287 }
288 }
289 } // namespace AbilityRuntime
290 } // namespace OHOS
291