1 /*
2 * Copyright (c) 2021-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 "form_info.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include <unistd.h>
22
23 #include "app_log_wrapper.h"
24 #include "bundle_constants.h"
25 #include "json_serializer.h"
26 #include "json_util.h"
27 #include "nlohmann/json.hpp"
28 #include "parcel_macro.h"
29 #include "string_ex.h"
30
31 namespace OHOS {
32 namespace AppExecFwk {
33 namespace {
34 const std::string JSON_KEY_COLOR_MODE = "colorMode";
35 const std::string JSON_KEY_PACKAGE = "package";
36 const std::string JSON_KEY_SUPPORT_DIMENSIONS = "supportDimensions";
37 const std::string JSON_KEY_DEFAULT_DIMENSION = "defaultDimension";
38 const std::string JSON_KEY_UPDATE_ENABLED = "updateEnabled";
39 const std::string JSON_KEY_SCHEDULED_UPDATE_TIME = "scheduledUpdateTime";
40 const std::string JSON_KEY_UPDATE_DURATION = "updateDuration";
41 const std::string JSON_KEY_DEEP_LINK = "deepLink";
42 const std::string JSON_KEY_JS_COMPONENT_NAME = "jsComponentName";
43 const std::string JSON_KEY_VALUE = "value";
44 const std::string JSON_KEY_NAME = "name";
45 const std::string JSON_KEY_ORIGINAL_BUNDLE_NAME = "originalBundleName";
46 const std::string JSON_KEY_CUSTOMIZE_DATA = "customizeData";
47 const std::string JSON_KEY_DESCRIPTION = "description";
48 const std::string JSON_KEY_DESCRIPTION_ID = "descriptionId";
49 const std::string JSON_KEY_TYPE = "type";
50 const std::string JSON_KEY_UI_SYNTAX = "uiSyntax";
51 const std::string JSON_KEY_LANDSCAPE_LAYOUTS = "landscapeLayouts";
52 const std::string JSON_KEY_FORMCONFIG_ABILITY = "formConfigAbility";
53 const std::string JSON_KEY_FORM_VISIBLE_NOTIFY = "formVisibleNotify";
54 const std::string JSON_KEY_RELATED_BUNDLE_NAME = "relatedBundleName";
55 const std::string JSON_KEY_DEFAULT_FLAG = "defaultFlag";
56 const std::string JSON_KEY_PORTRAIT_LAYOUTS = "portraitLayouts";
57 const std::string JSON_KEY_SRC = "src";
58 const std::string JSON_KEY_WINDOW = "window";
59 const std::string JSON_KEY_DESIGN_WIDTH = "designWidth";
60 const std::string JSON_KEY_AUTO_DESIGN_WIDTH = "autoDesignWidth";
61 const std::string JSON_KEY_IS_STATIC = "isStatic";
62 } // namespace
63
FormInfo(const ExtensionAbilityInfo & abilityInfo,const ExtensionFormInfo & formInfo)64 FormInfo::FormInfo(const ExtensionAbilityInfo &abilityInfo, const ExtensionFormInfo &formInfo)
65 {
66 package = abilityInfo.bundleName + abilityInfo.moduleName;
67 bundleName = abilityInfo.bundleName;
68 originalBundleName = abilityInfo.bundleName;
69 relatedBundleName = abilityInfo.bundleName;
70 moduleName = abilityInfo.moduleName;
71 abilityName = abilityInfo.name;
72 name = formInfo.name;
73 description = formInfo.description;
74 jsComponentName = "";
75 deepLink = "";
76 formConfigAbility = formInfo.formConfigAbility;
77 scheduledUpdateTime = formInfo.scheduledUpdateTime;
78 src = formInfo.src;
79 window.designWidth = formInfo.window.designWidth;
80 window.autoDesignWidth = formInfo.window.autoDesignWidth;
81 std::size_t pos = formInfo.description.find(":");
82 if (pos != std::string::npos) {
83 descriptionId = atoi(formInfo.description.substr(pos + 1, formInfo.description.length() - pos - 1).c_str());
84 }
85 updateDuration = formInfo.updateDuration;
86 defaultDimension = formInfo.defaultDimension;
87 defaultFlag = formInfo.isDefault;
88 formVisibleNotify = formInfo.formVisibleNotify;
89 updateEnabled = formInfo.updateEnabled;
90 type = formInfo.type;
91 uiSyntax = formInfo.uiSyntax;
92 colorMode = formInfo.colorMode;
93 for (const auto &dimension : formInfo.supportDimensions) {
94 supportDimensions.push_back(dimension);
95 }
96 for (const auto &metadata : formInfo.metadata) {
97 customizeDatas.push_back(metadata);
98 }
99 }
100
ReadCustomizeData(Parcel & parcel)101 bool FormInfo::ReadCustomizeData(Parcel &parcel)
102 {
103 int32_t customizeDataSize = 0;
104 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, customizeDataSize);
105 for (auto i = 0; i < customizeDataSize; ++i) {
106 FormCustomizeData customizeData;
107 std::string customizeName = Str16ToStr8(parcel.ReadString16());
108 std::string customizeValue = Str16ToStr8(parcel.ReadString16());
109 customizeData.name = customizeName;
110 customizeData.value = customizeValue;
111 customizeDatas.emplace_back(customizeData);
112 }
113 return true;
114 }
115
ReadFromParcel(Parcel & parcel)116 bool FormInfo::ReadFromParcel(Parcel &parcel)
117 {
118 name = Str16ToStr8(parcel.ReadString16());
119 package = Str16ToStr8(parcel.ReadString16());
120 bundleName = Str16ToStr8(parcel.ReadString16());
121 moduleName = Str16ToStr8(parcel.ReadString16());
122 abilityName = Str16ToStr8(parcel.ReadString16());
123 description = Str16ToStr8(parcel.ReadString16());
124 formConfigAbility = Str16ToStr8(parcel.ReadString16());
125 scheduledUpdateTime = Str16ToStr8(parcel.ReadString16());
126 jsComponentName = Str16ToStr8(parcel.ReadString16());
127 relatedBundleName = Str16ToStr8(parcel.ReadString16());
128 originalBundleName = Str16ToStr8(parcel.ReadString16());
129 deepLink = Str16ToStr8(parcel.ReadString16());
130 src = Str16ToStr8(parcel.ReadString16());
131 updateEnabled = parcel.ReadBool();
132 defaultFlag = parcel.ReadBool();
133 formVisibleNotify = parcel.ReadBool();
134 isStatic = parcel.ReadBool();
135 defaultDimension = parcel.ReadInt32();
136 descriptionId = parcel.ReadInt32();
137 updateDuration = parcel.ReadInt32();
138
139 int32_t typeData;
140 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
141 type = static_cast<FormType>(typeData);
142
143 int32_t uiSyntaxData;
144 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uiSyntaxData);
145 uiSyntax = static_cast<FormType>(uiSyntaxData);
146
147 int32_t colorModeData;
148 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, colorModeData);
149 colorMode = static_cast<FormsColorMode>(colorModeData);
150
151 int32_t supportDimensionSize;
152 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
153
154 for (int32_t i = 0; i < supportDimensionSize; i++) {
155 supportDimensions.emplace_back(parcel.ReadInt32());
156 }
157
158 int32_t landscapeLayoutsSize;
159 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
160 for (auto i = 0; i < landscapeLayoutsSize; i++) {
161 landscapeLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
162 }
163
164 int32_t portraitLayoutsSize;
165 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
166 for (auto i = 0; i < portraitLayoutsSize; i++) {
167 portraitLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
168 }
169
170 if (!ReadCustomizeData(parcel)) {
171 return false;
172 }
173
174 window.designWidth = parcel.ReadInt32();
175 window.autoDesignWidth = parcel.ReadBool();
176 return true;
177 }
178
Unmarshalling(Parcel & parcel)179 FormInfo *FormInfo::Unmarshalling(Parcel &parcel)
180 {
181 std::unique_ptr<FormInfo> info = std::make_unique<FormInfo>();
182 if (!info->ReadFromParcel(parcel)) {
183 APP_LOGW("read from parcel failed");
184 info = nullptr;
185 }
186 return info.release();
187 }
188
Marshalling(Parcel & parcel) const189 bool FormInfo::Marshalling(Parcel &parcel) const
190 {
191 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(name));
192 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(package));
193 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName));
194 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleName));
195 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(abilityName));
196 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(description));
197 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(formConfigAbility));
198 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(scheduledUpdateTime));
199 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(jsComponentName));
200 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(relatedBundleName));
201 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(originalBundleName));
202 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(deepLink));
203 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(src));
204 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, updateEnabled);
205 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, defaultFlag);
206 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, formVisibleNotify);
207 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStatic);
208 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, defaultDimension);
209 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, descriptionId);
210 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, updateDuration);
211 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(type));
212 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(uiSyntax));
213 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(colorMode));
214
215 const auto supportDimensionSize = static_cast<int32_t>(supportDimensions.size());
216 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
217 for (auto i = 0; i < supportDimensionSize; i++) {
218 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensions[i]);
219 }
220
221 const auto landscapeLayoutsSize = static_cast<int32_t>(landscapeLayouts.size());
222 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
223 for (auto i = 0; i < landscapeLayoutsSize; i++) {
224 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(landscapeLayouts[i]));
225 }
226
227 const auto portraitLayoutsSize = static_cast<int32_t>(portraitLayouts.size());
228 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
229 for (auto i = 0; i < portraitLayoutsSize; i++) {
230 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(portraitLayouts[i]));
231 }
232
233 const auto customizeDataSize = static_cast<int32_t>(customizeDatas.size());
234 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, customizeDataSize);
235 for (auto i = 0; i < customizeDataSize; i++) {
236 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].name));
237 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].value));
238 }
239
240 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, window.designWidth);
241 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, window.autoDesignWidth);
242 return true;
243 }
244
IsValid() const245 bool FormInfo::IsValid() const
246 {
247 if (!window.autoDesignWidth && window.designWidth <= 0) {
248 APP_LOGW("Invalid FormInfo, window.designWidth <= 0.");
249 return false;
250 }
251 return true;
252 }
253
to_json(nlohmann::json & jsonObject,const FormCustomizeData & customizeDatas)254 void to_json(nlohmann::json &jsonObject, const FormCustomizeData &customizeDatas)
255 {
256 jsonObject = nlohmann::json{
257 {JSON_KEY_NAME, customizeDatas.name},
258 {JSON_KEY_VALUE, customizeDatas.value}
259 };
260 }
261
to_json(nlohmann::json & jsonObject,const FormWindow & formWindow)262 void to_json(nlohmann::json &jsonObject, const FormWindow &formWindow)
263 {
264 jsonObject[JSON_KEY_DESIGN_WIDTH] = formWindow.designWidth;
265 jsonObject[JSON_KEY_AUTO_DESIGN_WIDTH] = formWindow.autoDesignWidth;
266 }
267
to_json(nlohmann::json & jsonObject,const FormInfo & formInfo)268 void to_json(nlohmann::json &jsonObject, const FormInfo &formInfo)
269 {
270 jsonObject = nlohmann::json{
271 {JSON_KEY_NAME, formInfo.name},
272 {JSON_KEY_PACKAGE, formInfo.package},
273 {Constants::BUNDLE_NAME, formInfo.bundleName},
274 {Constants::MODULE_NAME, formInfo.moduleName},
275 {Constants::ABILITY_NAME, formInfo.abilityName},
276 {JSON_KEY_DESCRIPTION, formInfo.description},
277 {JSON_KEY_RELATED_BUNDLE_NAME, formInfo.relatedBundleName},
278 {JSON_KEY_JS_COMPONENT_NAME, formInfo.jsComponentName},
279 {JSON_KEY_DEEP_LINK, formInfo.deepLink},
280 {JSON_KEY_SRC, formInfo.src},
281 {JSON_KEY_FORMCONFIG_ABILITY, formInfo.formConfigAbility},
282 {JSON_KEY_SCHEDULED_UPDATE_TIME, formInfo.scheduledUpdateTime},
283 {JSON_KEY_ORIGINAL_BUNDLE_NAME, formInfo.originalBundleName},
284 {JSON_KEY_DESCRIPTION_ID, formInfo.descriptionId},
285 {JSON_KEY_UPDATE_DURATION, formInfo.updateDuration},
286 {JSON_KEY_DEFAULT_DIMENSION, formInfo.defaultDimension},
287 {JSON_KEY_DEFAULT_FLAG, formInfo.defaultFlag},
288 {JSON_KEY_FORM_VISIBLE_NOTIFY, formInfo.formVisibleNotify},
289 {JSON_KEY_UPDATE_ENABLED, formInfo.updateEnabled},
290 {JSON_KEY_IS_STATIC, formInfo.isStatic},
291 {JSON_KEY_TYPE, formInfo.type},
292 {JSON_KEY_UI_SYNTAX, formInfo.uiSyntax},
293 {JSON_KEY_COLOR_MODE, formInfo.colorMode},
294 {JSON_KEY_SUPPORT_DIMENSIONS, formInfo.supportDimensions},
295 {JSON_KEY_CUSTOMIZE_DATA, formInfo.customizeDatas},
296 {JSON_KEY_LANDSCAPE_LAYOUTS, formInfo.landscapeLayouts},
297 {JSON_KEY_PORTRAIT_LAYOUTS, formInfo.portraitLayouts},
298 {JSON_KEY_WINDOW, formInfo.window}
299 };
300 }
301
from_json(const nlohmann::json & jsonObject,FormCustomizeData & customizeDatas)302 void from_json(const nlohmann::json &jsonObject, FormCustomizeData &customizeDatas)
303 {
304 customizeDatas.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
305 customizeDatas.value = jsonObject.at(JSON_KEY_VALUE).get<std::string>();
306 }
307
from_json(const nlohmann::json & jsonObject,FormWindow & formWindow)308 void from_json(const nlohmann::json &jsonObject, FormWindow &formWindow)
309 {
310 formWindow.designWidth = jsonObject.at(JSON_KEY_DESIGN_WIDTH).get<int32_t>();
311 formWindow.autoDesignWidth = jsonObject.at(JSON_KEY_AUTO_DESIGN_WIDTH).get<bool>();
312 }
313
from_json(const nlohmann::json & jsonObject,FormInfo & formInfo)314 void from_json(const nlohmann::json &jsonObject, FormInfo &formInfo)
315 {
316 formInfo.bundleName = jsonObject.at(Constants::BUNDLE_NAME).get<std::string>();
317 formInfo.package = jsonObject.at(JSON_KEY_PACKAGE).get<std::string>();
318 formInfo.moduleName = jsonObject.at(Constants::MODULE_NAME).get<std::string>();
319 formInfo.abilityName = jsonObject.at(Constants::ABILITY_NAME).get<std::string>();
320 formInfo.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
321 formInfo.description = jsonObject.at(JSON_KEY_DESCRIPTION).get<std::string>();
322 formInfo.relatedBundleName = jsonObject.at(JSON_KEY_RELATED_BUNDLE_NAME).get<std::string>();
323 formInfo.jsComponentName = jsonObject.at(JSON_KEY_JS_COMPONENT_NAME).get<std::string>();
324 formInfo.deepLink = jsonObject.at(JSON_KEY_DEEP_LINK).get<std::string>();
325 formInfo.formConfigAbility = jsonObject.at(JSON_KEY_FORMCONFIG_ABILITY).get<std::string>();
326 formInfo.scheduledUpdateTime = jsonObject.at(JSON_KEY_SCHEDULED_UPDATE_TIME).get<std::string>();
327 formInfo.src = jsonObject.at(JSON_KEY_SRC).get<std::string>();
328 formInfo.originalBundleName = jsonObject.at(JSON_KEY_ORIGINAL_BUNDLE_NAME).get<std::string>();
329 formInfo.descriptionId = jsonObject.at(JSON_KEY_DESCRIPTION_ID).get<int32_t>();
330 formInfo.updateDuration = jsonObject.at(JSON_KEY_UPDATE_DURATION).get<int32_t>();
331 formInfo.defaultDimension = jsonObject.at(JSON_KEY_DEFAULT_DIMENSION).get<int32_t>();
332 formInfo.defaultFlag = jsonObject.at(JSON_KEY_DEFAULT_FLAG).get<bool>();
333 formInfo.formVisibleNotify = jsonObject.at(JSON_KEY_FORM_VISIBLE_NOTIFY).get<bool>();
334 formInfo.updateEnabled = jsonObject.at(JSON_KEY_UPDATE_ENABLED).get<bool>();
335 formInfo.isStatic = jsonObject.at(JSON_KEY_IS_STATIC).get<bool>();
336 formInfo.type = jsonObject.at(JSON_KEY_TYPE).get<FormType>();
337 formInfo.colorMode = jsonObject.at(JSON_KEY_COLOR_MODE).get<FormsColorMode>();
338 formInfo.supportDimensions = jsonObject.at(JSON_KEY_SUPPORT_DIMENSIONS).get<std::vector<int32_t>>();
339 formInfo.customizeDatas = jsonObject.at(JSON_KEY_CUSTOMIZE_DATA).get<std::vector<FormCustomizeData>>();
340 formInfo.landscapeLayouts = jsonObject.at(JSON_KEY_LANDSCAPE_LAYOUTS).get<std::vector<std::string>>();
341 formInfo.portraitLayouts = jsonObject.at(JSON_KEY_PORTRAIT_LAYOUTS).get<std::vector<std::string>>();
342 formInfo.window = jsonObject.at(JSON_KEY_WINDOW).get<FormWindow>();
343
344 int32_t parseResult = ERR_OK;
345 const auto &jsonObjectEnd = jsonObject.end();
346 GetValueIfFindKey<FormType>(jsonObject,
347 jsonObjectEnd,
348 JSON_KEY_UI_SYNTAX,
349 formInfo.uiSyntax,
350 JsonType::NUMBER,
351 false,
352 parseResult,
353 ArrayType::NOT_ARRAY);
354 }
355 } // namespace AppExecFwk
356 } // namespace OHOS
357