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