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