• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 <map>
17 #include <set>
18 #include "json_util.h"
19 #include "nlohmann/json.hpp"
20 #include "extension_form_profile.h"
21 
22 namespace OHOS {
23 namespace AppExecFwk {
24 namespace {
25 thread_local int32_t parseResult;
26 
27 const int32_t MAX_FORM_NAME = 127;
28 const std::map<std::string, FormsColorMode> formColorModeMap = {
29     {"auto",  FormsColorMode::AUTO_MODE},
30     {"dark",  FormsColorMode::DARK_MODE},
31     {"light", FormsColorMode::LIGHT_MODE}
32 };
33 const std::map<std::string, int32_t> dimensionMap = {
34     {"1*2", 1},
35     {"2*2", 2},
36     {"2*4", 3},
37     {"4*4", 4},
38     {"2*1", 5}
39 };
40 const std::map<std::string, FormType> formTypeMap = {
41     {"JS", FormType::JS},
42     {"eTS", FormType::ETS}
43 };
44 
45 const std::map<std::string, FormType> uiSyntaxMap = {
46     {"hml", FormType::JS},
47     {"arkts", FormType::ETS}
48 };
49 
50 struct Window {
51     int32_t designWidth = 720;
52     bool autoDesignWidth = false;
53 };
54 
55 struct Metadata {
56     std::string name;
57     std::string value;
58 };
59 
60 struct ExtensionFormProfileInfo {
61     std::string name;
62     std::string description;
63     std::string src;
64     Window window;
65     std::string colorMode = "auto";
66     std::string formConfigAbility;
67     std::string type = "JS";
68     std::string uiSyntax = "hml";
69     bool formVisibleNotify = false;
70     bool isDefault = false;
71     bool updateEnabled = false;
72     std::string scheduledUpdateTime = "";
73     int32_t updateDuration = 0;
74     std::string defaultDimension;
75     std::vector<std::string> supportDimensions {};
76     std::vector<Metadata> metadata {};
77 };
78 
79 struct ExtensionFormProfileInfoVec {
80     std::vector<ExtensionFormProfileInfo> forms {};
81 };
82 
from_json(const nlohmann::json & jsonObject,Metadata & metadata)83 void from_json(const nlohmann::json &jsonObject, Metadata &metadata)
84 {
85     const auto &jsonObjectEnd = jsonObject.end();
86     GetValueIfFindKey<std::string>(jsonObject,
87         jsonObjectEnd,
88         ExtensionFormProfileReader::METADATA_NAME,
89         metadata.name,
90         JsonType::STRING,
91         false,
92         parseResult,
93         ArrayType::NOT_ARRAY);
94     GetValueIfFindKey<std::string>(jsonObject,
95         jsonObjectEnd,
96         ExtensionFormProfileReader::METADATA_VALUE,
97         metadata.value,
98         JsonType::STRING,
99         false,
100         parseResult,
101         ArrayType::NOT_ARRAY);
102 }
103 
from_json(const nlohmann::json & jsonObject,Window & window)104 void from_json(const nlohmann::json &jsonObject, Window &window)
105 {
106     const auto &jsonObjectEnd = jsonObject.end();
107     GetValueIfFindKey<int32_t>(jsonObject,
108         jsonObjectEnd,
109         ExtensionFormProfileReader::WINDOW_DESIGN_WIDTH,
110         window.designWidth,
111         JsonType::NUMBER,
112         false,
113         parseResult,
114         ArrayType::NOT_ARRAY);
115     GetValueIfFindKey<bool>(jsonObject,
116         jsonObjectEnd,
117         ExtensionFormProfileReader::WINDOW_AUTO_DESIGN_WIDTH,
118         window.autoDesignWidth,
119         JsonType::BOOLEAN,
120         false,
121         parseResult,
122         ArrayType::NOT_ARRAY);
123 }
124 
from_json(const nlohmann::json & jsonObject,ExtensionFormProfileInfo & extensionFormProfileInfo)125 void from_json(const nlohmann::json &jsonObject, ExtensionFormProfileInfo &extensionFormProfileInfo)
126 {
127     const auto &jsonObjectEnd = jsonObject.end();
128     GetValueIfFindKey<std::string>(jsonObject,
129         jsonObjectEnd,
130         ExtensionFormProfileReader::NAME,
131         extensionFormProfileInfo.name,
132         JsonType::STRING,
133         true,
134         parseResult,
135         ArrayType::NOT_ARRAY);
136     GetValueIfFindKey<std::string>(jsonObject,
137         jsonObjectEnd,
138         ExtensionFormProfileReader::DESCRIPTION,
139         extensionFormProfileInfo.description,
140         JsonType::STRING,
141         false,
142         parseResult,
143         ArrayType::NOT_ARRAY);
144     GetValueIfFindKey<std::string>(jsonObject,
145         jsonObjectEnd,
146         ExtensionFormProfileReader::SRC,
147         extensionFormProfileInfo.src,
148         JsonType::STRING,
149         false,
150         parseResult,
151         ArrayType::NOT_ARRAY);
152     GetValueIfFindKey<Window>(jsonObject,
153         jsonObjectEnd,
154         ExtensionFormProfileReader::WINDOW,
155         extensionFormProfileInfo.window,
156         JsonType::OBJECT,
157         false,
158         parseResult,
159         ArrayType::NOT_ARRAY);
160     GetValueIfFindKey<std::string>(jsonObject,
161         jsonObjectEnd,
162         ExtensionFormProfileReader::COLOR_MODE,
163         extensionFormProfileInfo.colorMode,
164         JsonType::STRING,
165         false,
166         parseResult,
167         ArrayType::NOT_ARRAY);
168     GetValueIfFindKey<std::string>(jsonObject,
169         jsonObjectEnd,
170         ExtensionFormProfileReader::FORM_CONFIG_ABILITY,
171         extensionFormProfileInfo.formConfigAbility,
172         JsonType::STRING,
173         false,
174         parseResult,
175         ArrayType::NOT_ARRAY);
176     GetValueIfFindKey<std::string>(jsonObject,
177         jsonObjectEnd,
178         ExtensionFormProfileReader::TYPE,
179         extensionFormProfileInfo.type,
180         JsonType::STRING,
181         false,
182         parseResult,
183         ArrayType::NOT_ARRAY);
184     GetValueIfFindKey<std::string>(jsonObject,
185         jsonObjectEnd,
186         ExtensionFormProfileReader::UI_SYNTAX,
187         extensionFormProfileInfo.uiSyntax,
188         JsonType::STRING,
189         false,
190         parseResult,
191         ArrayType::NOT_ARRAY);
192     GetValueIfFindKey<bool>(jsonObject,
193         jsonObjectEnd,
194         ExtensionFormProfileReader::FORM_VISIBLE_NOTIFY,
195         extensionFormProfileInfo.formVisibleNotify,
196         JsonType::BOOLEAN,
197         false,
198         parseResult,
199         ArrayType::NOT_ARRAY);
200     GetValueIfFindKey<bool>(jsonObject,
201         jsonObjectEnd,
202         ExtensionFormProfileReader::IS_DEFAULT,
203         extensionFormProfileInfo.isDefault,
204         JsonType::BOOLEAN,
205         true,
206         parseResult,
207         ArrayType::NOT_ARRAY);
208     GetValueIfFindKey<bool>(jsonObject,
209         jsonObjectEnd,
210         ExtensionFormProfileReader::UPDATE_ENABLED,
211         extensionFormProfileInfo.updateEnabled,
212         JsonType::BOOLEAN,
213         true,
214         parseResult,
215         ArrayType::NOT_ARRAY);
216     GetValueIfFindKey<std::string>(jsonObject,
217         jsonObjectEnd,
218         ExtensionFormProfileReader::SCHEDULED_UPDATE_TIME,
219         extensionFormProfileInfo.scheduledUpdateTime,
220         JsonType::STRING,
221         false,
222         parseResult,
223         ArrayType::NOT_ARRAY);
224     GetValueIfFindKey<int32_t>(jsonObject,
225         jsonObjectEnd,
226         ExtensionFormProfileReader::UPDATE_DURATION,
227         extensionFormProfileInfo.updateDuration,
228         JsonType::NUMBER,
229         false,
230         parseResult,
231         ArrayType::NOT_ARRAY);
232     GetValueIfFindKey<std::string>(jsonObject,
233         jsonObjectEnd,
234         ExtensionFormProfileReader::DEFAULT_DIMENSION,
235         extensionFormProfileInfo.defaultDimension,
236         JsonType::STRING,
237         true,
238         parseResult,
239         ArrayType::NOT_ARRAY);
240     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
241         jsonObjectEnd,
242         ExtensionFormProfileReader::SUPPORT_DIMENSIONS,
243         extensionFormProfileInfo.supportDimensions,
244         JsonType::ARRAY,
245         true,
246         parseResult,
247         ArrayType::STRING);
248     GetValueIfFindKey<std::vector<Metadata>>(jsonObject,
249         jsonObjectEnd,
250         ExtensionFormProfileReader::METADATA,
251         extensionFormProfileInfo.metadata,
252         JsonType::ARRAY,
253         false,
254         parseResult,
255         ArrayType::OBJECT);
256 }
257 
from_json(const nlohmann::json & jsonObject,ExtensionFormProfileInfoVec & infos)258 void from_json(const nlohmann::json &jsonObject, ExtensionFormProfileInfoVec &infos)
259 {
260     const auto &jsonObjectEnd = jsonObject.end();
261     GetValueIfFindKey<std::vector<ExtensionFormProfileInfo>>(jsonObject,
262         jsonObjectEnd,
263         ExtensionFormProfileReader::FORMS,
264         infos.forms,
265         JsonType::ARRAY,
266         false,
267         parseResult,
268         ArrayType::OBJECT);
269 }
270 
CheckFormNameIsValid(const std::string & name)271 bool CheckFormNameIsValid(const std::string &name)
272 {
273     if (name.empty()) {
274         return false;
275     }
276     if (name.size() > MAX_FORM_NAME) {
277         return false;
278     }
279     return true;
280 }
281 
GetMetadata(const ExtensionFormProfileInfo & form,ExtensionFormInfo & info)282 bool GetMetadata(const ExtensionFormProfileInfo &form, ExtensionFormInfo &info)
283 {
284     std::set<int32_t> supportDimensionSet {};
285     for (const auto &dimension: form.supportDimensions) {
286         auto dimensionRes = std::find_if(std::begin(dimensionMap),
287             std::end(dimensionMap),
288             [&dimension](const auto &item) { return item.first == dimension; });
289         if (dimensionRes == dimensionMap.end()) {
290             APP_LOGW("dimension is invalid, form name is %{public}s", form.name.c_str());
291             continue;
292         }
293         supportDimensionSet.emplace(dimensionRes->second);
294     }
295 
296     auto dimensionRes = std::find_if(std::begin(dimensionMap),
297         std::end(dimensionMap),
298         [&form](const auto &item) { return item.first == form.defaultDimension; });
299     if (dimensionRes == dimensionMap.end()) {
300         APP_LOGW("defaultDimension is invalid, form name is %{public}s", form.name.c_str());
301         return false;
302     }
303     if (supportDimensionSet.find(dimensionRes->second) == supportDimensionSet.end()) {
304         APP_LOGW("defaultDimension is not in supportDimensions, form name is %{public}s", form.name.c_str());
305         return false;
306     }
307 
308     info.defaultDimension = dimensionRes->second;
309     for (const auto &dimension: supportDimensionSet) {
310         info.supportDimensions.emplace_back(dimension);
311     }
312     return true;
313 }
314 
TransformToExtensionFormInfo(const ExtensionFormProfileInfo & form,ExtensionFormInfo & info)315 bool TransformToExtensionFormInfo(const ExtensionFormProfileInfo &form, ExtensionFormInfo &info)
316 {
317     if (!CheckFormNameIsValid(form.name)) {
318         APP_LOGE("form name is invalid");
319         return false;
320     }
321     info.name = form.name;
322     info.description = form.description;
323     info.src = form.src;
324     info.window.autoDesignWidth = form.window.autoDesignWidth;
325     info.window.designWidth = form.window.designWidth;
326 
327     auto colorMode = std::find_if(std::begin(formColorModeMap),
328         std::end(formColorModeMap),
329         [&form](const auto &item) { return item.first == form.colorMode; });
330     if (colorMode != formColorModeMap.end()) {
331         info.colorMode = colorMode->second;
332     }
333 
334     auto formType = formTypeMap.find(form.type);
335     if (formType != formTypeMap.end()) {
336         info.type = formType->second;
337     }
338 
339     auto uiSyntaxType = uiSyntaxMap.find(form.uiSyntax);
340     if (uiSyntaxType != uiSyntaxMap.end()) {
341         info.uiSyntax = uiSyntaxType->second;
342     }
343 
344     info.formConfigAbility = form.formConfigAbility;
345     info.formVisibleNotify = form.formVisibleNotify;
346     info.isDefault = form.isDefault;
347     info.updateEnabled = form.updateEnabled;
348     info.scheduledUpdateTime = form.scheduledUpdateTime;
349     info.updateDuration = form.updateDuration;
350 
351     if (!GetMetadata(form, info)) {
352         return false;
353     }
354     for (const auto &data: form.metadata) {
355         FormCustomizeData customizeData;
356         customizeData.name = data.name;
357         customizeData.value = data.value;
358         info.metadata.emplace_back(customizeData);
359     }
360     return true;
361 }
362 
TransformToInfos(const ExtensionFormProfileInfoVec & forms,std::vector<ExtensionFormInfo> & infos)363 bool TransformToInfos(const ExtensionFormProfileInfoVec &forms, std::vector<ExtensionFormInfo> &infos)
364 {
365     APP_LOGI("transform ExtensionFormProfileInfo to ExtensionFormInfo");
366     for (const auto &form: forms.forms) {
367         ExtensionFormInfo info;
368         if (!TransformToExtensionFormInfo(form, info)) {
369             return false;
370         }
371         infos.push_back(info);
372     }
373     return true;
374 }
375 } // namespace
376 
TransformTo(const std::string & formProfile,std::vector<ExtensionFormInfo> & infos)377 ErrCode ExtensionFormProfile::TransformTo(const std::string &formProfile, std::vector<ExtensionFormInfo> &infos)
378 {
379     APP_LOGI("transform profile to extension form infos");
380     nlohmann::json jsonObject = nlohmann::json::parse(formProfile, nullptr, false);
381     if (jsonObject.is_discarded()) {
382         APP_LOGE("bad profile");
383         return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
384     }
385 
386     auto forms = jsonObject.get<ExtensionFormProfileInfoVec>();
387     if (parseResult != ERR_OK) {
388         APP_LOGE("parseResult is %{public}d", parseResult);
389         int32_t ret = parseResult;
390         // need recover parse result to ERR_OK
391         parseResult = ERR_OK;
392         return ret;
393     }
394 
395     if (!TransformToInfos(forms, infos)) {
396         return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
397     }
398     return ERR_OK;
399 }
400 }  // namespace AppExecFwk
401 }  // namespace OHOS
402