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 CONTAINER_SECURITY_VERIFY(parcel, customizeDataSize, &customizeDatas);
106 for (auto i = 0; i < customizeDataSize; ++i) {
107 FormCustomizeData customizeData;
108 std::string customizeName = Str16ToStr8(parcel.ReadString16());
109 std::string customizeValue = Str16ToStr8(parcel.ReadString16());
110 customizeData.name = customizeName;
111 customizeData.value = customizeValue;
112 customizeDatas.emplace_back(customizeData);
113 }
114 return true;
115 }
116
ReadFromParcel(Parcel & parcel)117 bool FormInfo::ReadFromParcel(Parcel &parcel)
118 {
119 name = Str16ToStr8(parcel.ReadString16());
120 package = Str16ToStr8(parcel.ReadString16());
121 bundleName = Str16ToStr8(parcel.ReadString16());
122 moduleName = Str16ToStr8(parcel.ReadString16());
123 abilityName = Str16ToStr8(parcel.ReadString16());
124 description = Str16ToStr8(parcel.ReadString16());
125 formConfigAbility = Str16ToStr8(parcel.ReadString16());
126 scheduledUpdateTime = Str16ToStr8(parcel.ReadString16());
127 jsComponentName = Str16ToStr8(parcel.ReadString16());
128 relatedBundleName = Str16ToStr8(parcel.ReadString16());
129 originalBundleName = Str16ToStr8(parcel.ReadString16());
130 deepLink = Str16ToStr8(parcel.ReadString16());
131 src = Str16ToStr8(parcel.ReadString16());
132 updateEnabled = parcel.ReadBool();
133 defaultFlag = parcel.ReadBool();
134 formVisibleNotify = parcel.ReadBool();
135 isStatic = parcel.ReadBool();
136 defaultDimension = parcel.ReadInt32();
137 descriptionId = parcel.ReadInt32();
138 updateDuration = parcel.ReadInt32();
139
140 int32_t typeData;
141 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, typeData);
142 type = static_cast<FormType>(typeData);
143
144 int32_t uiSyntaxData;
145 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uiSyntaxData);
146 uiSyntax = static_cast<FormType>(uiSyntaxData);
147
148 int32_t colorModeData;
149 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, colorModeData);
150 colorMode = static_cast<FormsColorMode>(colorModeData);
151
152 int32_t supportDimensionSize;
153 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
154 CONTAINER_SECURITY_VERIFY(parcel, supportDimensionSize, &supportDimensions);
155 for (int32_t i = 0; i < supportDimensionSize; i++) {
156 supportDimensions.emplace_back(parcel.ReadInt32());
157 }
158
159 int32_t landscapeLayoutsSize;
160 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
161 CONTAINER_SECURITY_VERIFY(parcel, landscapeLayoutsSize, &landscapeLayouts);
162 for (auto i = 0; i < landscapeLayoutsSize; i++) {
163 landscapeLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
164 }
165
166 int32_t portraitLayoutsSize;
167 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
168 CONTAINER_SECURITY_VERIFY(parcel, portraitLayoutsSize, &portraitLayouts);
169 for (auto i = 0; i < portraitLayoutsSize; i++) {
170 portraitLayouts.emplace_back(Str16ToStr8(parcel.ReadString16()));
171 }
172
173 if (!ReadCustomizeData(parcel)) {
174 return false;
175 }
176
177 window.designWidth = parcel.ReadInt32();
178 window.autoDesignWidth = parcel.ReadBool();
179 return true;
180 }
181
Unmarshalling(Parcel & parcel)182 FormInfo *FormInfo::Unmarshalling(Parcel &parcel)
183 {
184 std::unique_ptr<FormInfo> info = std::make_unique<FormInfo>();
185 if (!info->ReadFromParcel(parcel)) {
186 APP_LOGW("read from parcel failed");
187 info = nullptr;
188 }
189 return info.release();
190 }
191
Marshalling(Parcel & parcel) const192 bool FormInfo::Marshalling(Parcel &parcel) const
193 {
194 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(name));
195 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(package));
196 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName));
197 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleName));
198 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(abilityName));
199 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(description));
200 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(formConfigAbility));
201 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(scheduledUpdateTime));
202 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(jsComponentName));
203 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(relatedBundleName));
204 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(originalBundleName));
205 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(deepLink));
206 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(src));
207 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, updateEnabled);
208 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, defaultFlag);
209 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, formVisibleNotify);
210 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStatic);
211 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, defaultDimension);
212 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, descriptionId);
213 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, updateDuration);
214 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(type));
215 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(uiSyntax));
216 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(colorMode));
217
218 const auto supportDimensionSize = static_cast<int32_t>(supportDimensions.size());
219 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensionSize);
220 for (auto i = 0; i < supportDimensionSize; i++) {
221 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportDimensions[i]);
222 }
223
224 const auto landscapeLayoutsSize = static_cast<int32_t>(landscapeLayouts.size());
225 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, landscapeLayoutsSize);
226 for (auto i = 0; i < landscapeLayoutsSize; i++) {
227 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(landscapeLayouts[i]));
228 }
229
230 const auto portraitLayoutsSize = static_cast<int32_t>(portraitLayouts.size());
231 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, portraitLayoutsSize);
232 for (auto i = 0; i < portraitLayoutsSize; i++) {
233 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(portraitLayouts[i]));
234 }
235
236 const auto customizeDataSize = static_cast<int32_t>(customizeDatas.size());
237 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, customizeDataSize);
238 for (auto i = 0; i < customizeDataSize; i++) {
239 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].name));
240 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customizeDatas[i].value));
241 }
242
243 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, window.designWidth);
244 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, window.autoDesignWidth);
245 return true;
246 }
247
IsValid() const248 bool FormInfo::IsValid() const
249 {
250 if (!window.autoDesignWidth && window.designWidth <= 0) {
251 APP_LOGW("Invalid FormInfo, window.designWidth <= 0.");
252 return false;
253 }
254 return true;
255 }
256
to_json(nlohmann::json & jsonObject,const FormCustomizeData & customizeDatas)257 void to_json(nlohmann::json &jsonObject, const FormCustomizeData &customizeDatas)
258 {
259 jsonObject = nlohmann::json{
260 {JSON_KEY_NAME, customizeDatas.name},
261 {JSON_KEY_VALUE, customizeDatas.value}
262 };
263 }
264
to_json(nlohmann::json & jsonObject,const FormWindow & formWindow)265 void to_json(nlohmann::json &jsonObject, const FormWindow &formWindow)
266 {
267 jsonObject[JSON_KEY_DESIGN_WIDTH] = formWindow.designWidth;
268 jsonObject[JSON_KEY_AUTO_DESIGN_WIDTH] = formWindow.autoDesignWidth;
269 }
270
to_json(nlohmann::json & jsonObject,const FormInfo & formInfo)271 void to_json(nlohmann::json &jsonObject, const FormInfo &formInfo)
272 {
273 jsonObject = nlohmann::json{
274 {JSON_KEY_NAME, formInfo.name},
275 {JSON_KEY_PACKAGE, formInfo.package},
276 {Constants::BUNDLE_NAME, formInfo.bundleName},
277 {Constants::MODULE_NAME, formInfo.moduleName},
278 {Constants::ABILITY_NAME, formInfo.abilityName},
279 {JSON_KEY_DESCRIPTION, formInfo.description},
280 {JSON_KEY_RELATED_BUNDLE_NAME, formInfo.relatedBundleName},
281 {JSON_KEY_JS_COMPONENT_NAME, formInfo.jsComponentName},
282 {JSON_KEY_DEEP_LINK, formInfo.deepLink},
283 {JSON_KEY_SRC, formInfo.src},
284 {JSON_KEY_FORMCONFIG_ABILITY, formInfo.formConfigAbility},
285 {JSON_KEY_SCHEDULED_UPDATE_TIME, formInfo.scheduledUpdateTime},
286 {JSON_KEY_ORIGINAL_BUNDLE_NAME, formInfo.originalBundleName},
287 {JSON_KEY_DESCRIPTION_ID, formInfo.descriptionId},
288 {JSON_KEY_UPDATE_DURATION, formInfo.updateDuration},
289 {JSON_KEY_DEFAULT_DIMENSION, formInfo.defaultDimension},
290 {JSON_KEY_DEFAULT_FLAG, formInfo.defaultFlag},
291 {JSON_KEY_FORM_VISIBLE_NOTIFY, formInfo.formVisibleNotify},
292 {JSON_KEY_UPDATE_ENABLED, formInfo.updateEnabled},
293 {JSON_KEY_IS_STATIC, formInfo.isStatic},
294 {JSON_KEY_TYPE, formInfo.type},
295 {JSON_KEY_UI_SYNTAX, formInfo.uiSyntax},
296 {JSON_KEY_COLOR_MODE, formInfo.colorMode},
297 {JSON_KEY_SUPPORT_DIMENSIONS, formInfo.supportDimensions},
298 {JSON_KEY_CUSTOMIZE_DATA, formInfo.customizeDatas},
299 {JSON_KEY_LANDSCAPE_LAYOUTS, formInfo.landscapeLayouts},
300 {JSON_KEY_PORTRAIT_LAYOUTS, formInfo.portraitLayouts},
301 {JSON_KEY_WINDOW, formInfo.window}
302 };
303 }
304
from_json(const nlohmann::json & jsonObject,FormCustomizeData & customizeDatas)305 void from_json(const nlohmann::json &jsonObject, FormCustomizeData &customizeDatas)
306 {
307 customizeDatas.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
308 customizeDatas.value = jsonObject.at(JSON_KEY_VALUE).get<std::string>();
309 }
310
from_json(const nlohmann::json & jsonObject,FormWindow & formWindow)311 void from_json(const nlohmann::json &jsonObject, FormWindow &formWindow)
312 {
313 formWindow.designWidth = jsonObject.at(JSON_KEY_DESIGN_WIDTH).get<int32_t>();
314 formWindow.autoDesignWidth = jsonObject.at(JSON_KEY_AUTO_DESIGN_WIDTH).get<bool>();
315 }
316
from_json(const nlohmann::json & jsonObject,FormInfo & formInfo)317 void from_json(const nlohmann::json &jsonObject, FormInfo &formInfo)
318 {
319 formInfo.bundleName = jsonObject.at(Constants::BUNDLE_NAME).get<std::string>();
320 formInfo.package = jsonObject.at(JSON_KEY_PACKAGE).get<std::string>();
321 formInfo.moduleName = jsonObject.at(Constants::MODULE_NAME).get<std::string>();
322 formInfo.abilityName = jsonObject.at(Constants::ABILITY_NAME).get<std::string>();
323 formInfo.name = jsonObject.at(JSON_KEY_NAME).get<std::string>();
324 formInfo.description = jsonObject.at(JSON_KEY_DESCRIPTION).get<std::string>();
325 formInfo.relatedBundleName = jsonObject.at(JSON_KEY_RELATED_BUNDLE_NAME).get<std::string>();
326 formInfo.jsComponentName = jsonObject.at(JSON_KEY_JS_COMPONENT_NAME).get<std::string>();
327 formInfo.deepLink = jsonObject.at(JSON_KEY_DEEP_LINK).get<std::string>();
328 formInfo.formConfigAbility = jsonObject.at(JSON_KEY_FORMCONFIG_ABILITY).get<std::string>();
329 formInfo.scheduledUpdateTime = jsonObject.at(JSON_KEY_SCHEDULED_UPDATE_TIME).get<std::string>();
330 formInfo.src = jsonObject.at(JSON_KEY_SRC).get<std::string>();
331 formInfo.originalBundleName = jsonObject.at(JSON_KEY_ORIGINAL_BUNDLE_NAME).get<std::string>();
332 formInfo.descriptionId = jsonObject.at(JSON_KEY_DESCRIPTION_ID).get<int32_t>();
333 formInfo.updateDuration = jsonObject.at(JSON_KEY_UPDATE_DURATION).get<int32_t>();
334 formInfo.defaultDimension = jsonObject.at(JSON_KEY_DEFAULT_DIMENSION).get<int32_t>();
335 formInfo.defaultFlag = jsonObject.at(JSON_KEY_DEFAULT_FLAG).get<bool>();
336 formInfo.formVisibleNotify = jsonObject.at(JSON_KEY_FORM_VISIBLE_NOTIFY).get<bool>();
337 formInfo.updateEnabled = jsonObject.at(JSON_KEY_UPDATE_ENABLED).get<bool>();
338 formInfo.isStatic = jsonObject.at(JSON_KEY_IS_STATIC).get<bool>();
339 formInfo.type = jsonObject.at(JSON_KEY_TYPE).get<FormType>();
340 formInfo.colorMode = jsonObject.at(JSON_KEY_COLOR_MODE).get<FormsColorMode>();
341 formInfo.supportDimensions = jsonObject.at(JSON_KEY_SUPPORT_DIMENSIONS).get<std::vector<int32_t>>();
342 formInfo.customizeDatas = jsonObject.at(JSON_KEY_CUSTOMIZE_DATA).get<std::vector<FormCustomizeData>>();
343 formInfo.landscapeLayouts = jsonObject.at(JSON_KEY_LANDSCAPE_LAYOUTS).get<std::vector<std::string>>();
344 formInfo.portraitLayouts = jsonObject.at(JSON_KEY_PORTRAIT_LAYOUTS).get<std::vector<std::string>>();
345 formInfo.window = jsonObject.at(JSON_KEY_WINDOW).get<FormWindow>();
346
347 int32_t parseResult = ERR_OK;
348 const auto &jsonObjectEnd = jsonObject.end();
349 GetValueIfFindKey<FormType>(jsonObject,
350 jsonObjectEnd,
351 JSON_KEY_UI_SYNTAX,
352 formInfo.uiSyntax,
353 JsonType::NUMBER,
354 false,
355 parseResult,
356 ArrayType::NOT_ARRAY);
357 }
358 } // namespace AppExecFwk
359 } // namespace OHOS
360