1 /*
2 * Copyright (c) 2022 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 "client_helper.h"
17
18 #include <string>
19 #include <vector>
20
21 #include "napi_util.h"
22 #include "node_api.h"
23 #include "update_helper.h"
24
25 namespace OHOS {
26 namespace UpdateEngine {
27 enum TaskBodyMemeberMask {
28 VERSION_DIGEST_INFO = 0x00000001,
29 UPGRADE_STATUS = 0x00000010,
30 SUB_STATUS = 0x00000100,
31 PROGRESS = 0x00001000,
32 INSTALL_MODE = 0x00010000,
33 ERROR_MESSAGE = 0x00100000,
34 VERSION_COMPONENT = 0x01000000
35 };
36
37 std::map<EventId, uint32_t> g_taskBodyTemplateMap = {
38 { EventId::EVENT_TASK_RECEIVE, VERSION_DIGEST_INFO },
39 { EventId::EVENT_TASK_CANCEL, VERSION_DIGEST_INFO },
40 { EventId::EVENT_DOWNLOAD_WAIT, VERSION_DIGEST_INFO | UPGRADE_STATUS | INSTALL_MODE },
41 { EventId::EVENT_DOWNLOAD_START, VERSION_DIGEST_INFO | INSTALL_MODE },
42 { EventId::EVENT_DOWNLOAD_UPDATE, VERSION_DIGEST_INFO | UPGRADE_STATUS | PROGRESS | INSTALL_MODE },
43 { EventId::EVENT_DOWNLOAD_PAUSE, VERSION_DIGEST_INFO | UPGRADE_STATUS | PROGRESS | INSTALL_MODE | ERROR_MESSAGE },
44 { EventId::EVENT_DOWNLOAD_RESUME, VERSION_DIGEST_INFO | UPGRADE_STATUS | PROGRESS | INSTALL_MODE },
45 { EventId::EVENT_DOWNLOAD_SUCCESS, VERSION_DIGEST_INFO | INSTALL_MODE },
46 { EventId::EVENT_DOWNLOAD_FAIL, VERSION_DIGEST_INFO | INSTALL_MODE | ERROR_MESSAGE },
47 { EventId::EVENT_UPGRADE_WAIT, VERSION_DIGEST_INFO | INSTALL_MODE | ERROR_MESSAGE },
48 { EventId::EVENT_UPGRADE_START, VERSION_DIGEST_INFO | INSTALL_MODE },
49 { EventId::EVENT_UPGRADE_UPDATE, VERSION_DIGEST_INFO | UPGRADE_STATUS | PROGRESS | INSTALL_MODE },
50 { EventId::EVENT_APPLY_WAIT, VERSION_DIGEST_INFO | UPGRADE_STATUS | ERROR_MESSAGE },
51 { EventId::EVENT_APPLY_START, VERSION_DIGEST_INFO },
52 { EventId::EVENT_UPGRADE_SUCCESS, VERSION_DIGEST_INFO | VERSION_COMPONENT },
53 { EventId::EVENT_UPGRADE_FAIL, VERSION_DIGEST_INFO | VERSION_COMPONENT }
54 };
55
TrimString(std::string & str)56 void ClientHelper::TrimString(std::string &str)
57 {
58 str.erase(0, str.find_first_not_of(" "));
59 str.erase(str.find_last_not_of(" ") + 1);
60 }
61
IsValidUpgradeFile(const std::string & upgradeFile)62 bool ClientHelper::IsValidUpgradeFile(const std::string &upgradeFile)
63 {
64 if (upgradeFile.empty()) {
65 return false;
66 }
67
68 std::string::size_type pos = upgradeFile.find_first_of('/');
69 if (pos != 0) {
70 return false;
71 }
72
73 pos = upgradeFile.find_last_of('.');
74 if (pos == std::string::npos) {
75 return false;
76 }
77
78 std::string postfix = upgradeFile.substr(pos + 1);
79 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower);
80 if (postfix.compare("bin") == 0) {
81 return true;
82 } else if (postfix.compare("zip") == 0) {
83 return true;
84 } else if (postfix.compare("lz4") == 0) {
85 return true;
86 } else if (postfix.compare("gz") == 0) {
87 return true;
88 }
89 return false;
90 }
91
BuildDescInfo(napi_env env,napi_value & obj,const DescriptionInfo & descriptInfo)92 void BuildDescInfo(napi_env env, napi_value &obj, const DescriptionInfo &descriptInfo)
93 {
94 napi_value napiDescriptInfo;
95 napi_create_object(env, &napiDescriptInfo);
96 NapiUtil::SetInt32(env, napiDescriptInfo, "descriptionType", static_cast<int32_t>(descriptInfo.descriptionType));
97 NapiUtil::SetString(env, napiDescriptInfo, "content", descriptInfo.content.c_str());
98 napi_set_named_property(env, obj, "descriptionInfo", napiDescriptInfo);
99 }
100
IsValidData(const ErrorMessage & errorMessage)101 bool IsValidData(const ErrorMessage &errorMessage)
102 {
103 return errorMessage.errorCode != 0;
104 }
105
IsValidData(const ComponentDescription & componentDescription)106 bool IsValidData(const ComponentDescription &componentDescription)
107 {
108 return !componentDescription.componentId.empty();
109 }
110
IsValidData(const VersionComponent & versionComponent)111 bool IsValidData(const VersionComponent &versionComponent)
112 {
113 return versionComponent.componentType != static_cast<uint32_t>(ComponentType::INVALID);
114 }
115
116 template<typename T>
GetValidDataCount(const T dataArray[],size_t arraySize)117 size_t GetValidDataCount(const T dataArray[], size_t arraySize)
118 {
119 size_t validDataCount = 0;
120 for (size_t i = 0; i < arraySize; i++) {
121 if (IsValidData(dataArray[i])) {
122 validDataCount++;
123 }
124 }
125 return validDataCount;
126 }
127
BuildComponentDescriptions(napi_env env,napi_value & obj,const ComponentDescription componentDescriptions[],size_t arraySize)128 void BuildComponentDescriptions(napi_env env, napi_value &obj, const ComponentDescription componentDescriptions[],
129 size_t arraySize)
130 {
131 size_t validComponentCount = GetValidDataCount(componentDescriptions, arraySize);
132 if (validComponentCount == 0) {
133 return;
134 }
135 napi_create_array_with_length(env, validComponentCount, &obj);
136 napi_status status;
137 size_t index = 0;
138 for (size_t i = 0; (i < arraySize) && (index < validComponentCount); i++) {
139 if (IsValidData(componentDescriptions[i])) {
140 napi_value napiComponentDescription;
141 status = napi_create_object(env, &napiComponentDescription);
142 NapiUtil::SetString(env, napiComponentDescription, "componentId",
143 componentDescriptions[i].componentId.c_str());
144 BuildDescInfo(env, napiComponentDescription, componentDescriptions[i].descriptionInfo);
145 napi_set_element(env, obj, index, napiComponentDescription);
146 index++;
147 }
148 }
149 }
150
BuildVersionComponents(napi_env env,napi_value & obj,const VersionComponent versionComponents[],size_t arraySize)151 void BuildVersionComponents(napi_env env, napi_value &obj, const VersionComponent versionComponents[], size_t arraySize)
152 {
153 size_t validComponentCount = GetValidDataCount(versionComponents, arraySize);
154 if (validComponentCount == 0) {
155 return;
156 }
157 napi_value napiVersionComponents;
158 napi_create_array_with_length(env, validComponentCount, &napiVersionComponents);
159 napi_status status;
160 size_t index = 0;
161 for (size_t i = 0; (i < arraySize) && (index < validComponentCount); i++) {
162 if (IsValidData(versionComponents[i])) {
163 napi_value napiVersionComponent;
164 status = napi_create_object(env, &napiVersionComponent);
165 NapiUtil::SetString(env, napiVersionComponent, "componentId", versionComponents[i].componentId.c_str());
166 NapiUtil::SetInt32(env, napiVersionComponent, "componentType", versionComponents[i].componentType);
167 NapiUtil::SetString(env, napiVersionComponent, "upgradeAction",
168 versionComponents[i].upgradeAction.c_str());
169 NapiUtil::SetString(env, napiVersionComponent, "displayVersion",
170 versionComponents[i].displayVersion.c_str());
171 NapiUtil::SetString(env, napiVersionComponent, "innerVersion", versionComponents[i].innerVersion.c_str());
172 NapiUtil::SetInt32(env, napiVersionComponent, "size", versionComponents[i].size);
173 NapiUtil::SetInt32(env, napiVersionComponent, "effectiveMode", versionComponents[i].effectiveMode);
174 BuildDescInfo(env, napiVersionComponent, versionComponents[i].descriptionInfo);
175 napi_set_element(env, napiVersionComponents, index, napiVersionComponent);
176 index++;
177 }
178 }
179 napi_set_named_property(env, obj, "versionComponents", napiVersionComponents);
180 }
181
BuildCurrentVersionInfo(napi_env env,napi_value & obj,const UpdateResult & result)182 int32_t ClientHelper::BuildCurrentVersionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
183 {
184 PARAM_CHECK(result.result.currentVersionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
185 "ClientHelper::BuildCurrentVersionInfo null");
186 CLIENT_LOGI("BuildCurrentVersionInfo");
187 PARAM_CHECK(result.type == SessionType::SESSION_GET_CUR_VERSION,
188 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %{public}d", result.type);
189 napi_status status = napi_create_object(env, &obj);
190 PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
191 "Failed to create napi_create_object %d", static_cast<int32_t>(status));
192
193 CurrentVersionInfo *info = result.result.currentVersionInfo;
194 PARAM_CHECK(info != nullptr, return CAST_INT(ClientStatus::CLIENT_FAIL), "info is null");
195
196 NapiUtil::SetString(env, obj, "osVersion", info->osVersion);
197 NapiUtil::SetString(env, obj, "deviceName", info->deviceName);
198 BuildVersionComponents(env, obj, info->versionComponents, COUNT_OF(info->versionComponents));
199 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
200 }
201
BuildVersionDigestInfo(napi_env env,napi_value & obj,const VersionDigestInfo & versionDigestInfo)202 void BuildVersionDigestInfo(napi_env env, napi_value &obj, const VersionDigestInfo &versionDigestInfo)
203 {
204 napi_value napiVersionDigestInfo;
205 napi_create_object(env, &napiVersionDigestInfo);
206 NapiUtil::SetString(env, napiVersionDigestInfo, "versionDigest", versionDigestInfo.versionDigest);
207 napi_set_named_property(env, obj, "versionDigestInfo", napiVersionDigestInfo);
208 }
209
BuildErrorMessages(napi_env env,napi_value & obj,const std::string & name,const ErrorMessage errorMessages[],size_t arraySize)210 void BuildErrorMessages(napi_env env, napi_value &obj, const std::string &name, const ErrorMessage errorMessages[],
211 size_t arraySize)
212 {
213 size_t validErrorMsgCount = GetValidDataCount(errorMessages, arraySize);
214 if (validErrorMsgCount == 0) {
215 return;
216 }
217
218 napi_value napiErrorMessages;
219 napi_create_array_with_length(env, validErrorMsgCount, &napiErrorMessages);
220 size_t index = 0;
221 for (size_t i = 0; (i < arraySize) && (index < validErrorMsgCount); i++) {
222 if (IsValidData(errorMessages[i])) {
223 napi_value napiErrorMessage;
224 napi_create_object(env, &napiErrorMessage);
225 NapiUtil::SetInt32(env, napiErrorMessage, "errorCode", errorMessages[i].errorCode);
226 NapiUtil::SetString(env, napiErrorMessage, "errorMessage", errorMessages[i].errorMessage);
227 napi_set_element(env, napiErrorMessages, index, napiErrorMessage);
228 index++;
229 }
230 }
231 napi_set_named_property(env, obj, name.c_str(), napiErrorMessages);
232 }
233
BuildTaskBody(napi_env env,napi_value & obj,const TaskBody & taskBody)234 void BuildTaskBody(napi_env env, napi_value &obj, const TaskBody &taskBody)
235 {
236 napi_value napiTaskBody;
237 napi_create_object(env, &napiTaskBody);
238 BuildVersionDigestInfo(env, napiTaskBody, taskBody.versionDigestInfo);
239 NapiUtil::SetInt32(env, napiTaskBody, "status", taskBody.status);
240 NapiUtil::SetInt32(env, napiTaskBody, "subStatus", taskBody.subStatus);
241 NapiUtil::SetInt32(env, napiTaskBody, "progress", taskBody.progress);
242 NapiUtil::SetInt32(env, napiTaskBody, "installMode", taskBody.installMode);
243 BuildErrorMessages(env, napiTaskBody, "errorMessages", taskBody.errorMessages, COUNT_OF(taskBody.errorMessages));
244 BuildVersionComponents(env, napiTaskBody, taskBody.versionComponents, COUNT_OF(taskBody.versionComponents));
245 napi_set_named_property(env, obj, "taskBody", napiTaskBody);
246 }
247
BuildTaskInfo(napi_env env,napi_value & obj,const UpdateResult & result)248 int32_t ClientHelper::BuildTaskInfo(napi_env env, napi_value &obj, const UpdateResult &result)
249 {
250 PARAM_CHECK(result.result.taskInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
251 "ClientHelper::BuildTaskInfo null");
252 CLIENT_LOGI("ClientHelper::BuildTaskInfo");
253 napi_status status = napi_create_object(env, &obj);
254 PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
255 "Failed to create napi_create_object %d", static_cast<int32_t>(status));
256 NapiUtil::SetBool(env, obj, "existTask", result.result.taskInfo->existTask);
257 if (result.result.taskInfo->existTask) {
258 BuildTaskBody(env, obj, result.result.taskInfo->taskBody);
259 }
260 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
261 }
262
BuildNewVersionInfo(napi_env env,napi_value & obj,const UpdateResult & result)263 int32_t ClientHelper::BuildNewVersionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
264 {
265 PARAM_CHECK(result.result.newVersionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
266 "ClientHelper::BuildNewVersionInfo null");
267 PARAM_CHECK(result.type == SessionType::SESSION_GET_NEW_VERSION,
268 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
269 "invalid type %d",
270 result.type);
271 napi_status status = napi_create_object(env, &obj);
272 PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
273 "Failed to create napi_create_object %d", static_cast<int32_t>(status));
274
275 BuildVersionDigestInfo(env, obj, result.result.newVersionInfo->versionDigestInfo);
276 BuildVersionComponents(env, obj, result.result.newVersionInfo->versionComponents,
277 COUNT_OF(result.result.newVersionInfo->versionComponents));
278 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
279 }
280
BuildVersionDescriptionInfo(napi_env env,napi_value & obj,const UpdateResult & result)281 int32_t ClientHelper::BuildVersionDescriptionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
282 {
283 PARAM_CHECK(result.result.versionDescriptionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
284 "ClientHelper::BuildVersionDescriptionInfo null");
285 CLIENT_LOGI("BuildVersionDescriptionInfo");
286 PARAM_CHECK(result.type == SessionType::SESSION_GET_NEW_VERSION_DESCRIPTION ||
287 result.type == SessionType::SESSION_GET_CUR_VERSION_DESCRIPTION,
288 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %{public}d", result.type);
289
290 VersionDescriptionInfo *info = result.result.versionDescriptionInfo;
291 PARAM_CHECK(info != nullptr, return CAST_INT(ClientStatus::CLIENT_FAIL), "info is null");
292
293 BuildComponentDescriptions(env, obj, info->componentDescriptions, COUNT_OF(info->componentDescriptions));
294 PARAM_CHECK(obj != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS), "BuildComponentDescriptions null");
295 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
296 }
297
BuildCheckResultEx(napi_env env,napi_value & obj,const UpdateResult & result)298 int32_t ClientHelper::BuildCheckResultEx(napi_env env, napi_value &obj, const UpdateResult &result)
299 {
300 PARAM_CHECK(result.result.checkResultEx != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
301 "ClientHelper::BuildCheckResultEx null");
302 PARAM_CHECK(result.type == SessionType::SESSION_CHECK_VERSION,
303 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %d", result.type);
304 napi_status status = napi_create_object(env, &obj);
305 PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
306 "Failed to create napi_create_object %d", static_cast<int32_t>(status));
307 CheckResultEx *checkResultEx = result.result.checkResultEx;
308 NapiUtil::SetBool(env, obj, "isExistNewVersion", checkResultEx->isExistNewVersion);
309
310 if (checkResultEx->isExistNewVersion) {
311 napi_value newVersionInfo;
312 napi_create_object(env, &newVersionInfo);
313 BuildVersionDigestInfo(env, newVersionInfo, checkResultEx->newVersionInfo.versionDigestInfo);
314 BuildVersionComponents(env, newVersionInfo, checkResultEx->newVersionInfo.versionComponents,
315 COUNT_OF(checkResultEx->newVersionInfo.versionComponents));
316 napi_set_named_property(env, obj, "newVersionInfo", newVersionInfo);
317 }
318 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
319 }
320
BuildUpgradePolicy(napi_env env,napi_value & obj,const UpdateResult & result)321 int32_t ClientHelper::BuildUpgradePolicy(napi_env env, napi_value &obj, const UpdateResult &result)
322 {
323 PARAM_CHECK(result.result.upgradePolicy != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
324 "ClientHelper::BuildUpgradePolicy null");
325 PARAM_CHECK(result.type == SessionType::SESSION_GET_POLICY,
326 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %d", result.type);
327 napi_status status = napi_create_object(env, &obj);
328 PARAM_CHECK(status == napi_ok, return status, "Failed to create napi_create_object %d", status);
329 UpgradePolicy &upgradePolicy = *result.result.upgradePolicy;
330
331 // Add the result.
332 NapiUtil::SetBool(env, obj, "downloadStrategy", upgradePolicy.downloadStrategy);
333 NapiUtil::SetBool(env, obj, "autoUpgradeStrategy", upgradePolicy.autoUpgradeStrategy);
334
335 napi_value autoUpgradePeriods;
336 size_t count = COUNT_OF(upgradePolicy.autoUpgradePeriods);
337 status = napi_create_array_with_length(env, count, &autoUpgradePeriods);
338 PARAM_CHECK(status == napi_ok, return status, "Failed to create array for interval %d", status);
339 for (size_t i = 0; i < count; i++) {
340 napi_value result;
341 status = napi_create_object(env, &result);
342 PARAM_CHECK(status == napi_ok, return status, "Failed to create napi_create_object %d", status);
343 NapiUtil::SetInt32(env, result, "start", upgradePolicy.autoUpgradePeriods[i].start);
344 NapiUtil::SetInt32(env, result, "end", upgradePolicy.autoUpgradePeriods[i].end);
345 napi_set_element(env, autoUpgradePeriods, i, result);
346 }
347 (void)napi_set_named_property(env, obj, "autoUpgradePeriods", autoUpgradePeriods);
348 return napi_ok;
349 }
350
BuildUndefinedStatus(napi_env env,napi_value & obj,const UpdateResult & result)351 int32_t ClientHelper::BuildUndefinedStatus(napi_env env, napi_value &obj, const UpdateResult &result)
352 {
353 return napi_get_undefined(env, &obj);
354 }
355
CheckNapiObjectType(napi_env env,const napi_value arg)356 ClientStatus CheckNapiObjectType(napi_env env, const napi_value arg)
357 {
358 napi_valuetype type = napi_undefined;
359 napi_status status = napi_typeof(env, arg, &type);
360 PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_INVALID_TYPE,
361 "Invalid argc %d", static_cast<int32_t>(status));
362 PARAM_CHECK(type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
363 "Invalid argc %d", static_cast<int32_t>(type))
364 return ClientStatus::CLIENT_SUCCESS;
365 }
366
ParseBusinessType(napi_env env,const napi_value arg,UpgradeInfo & upgradeInfo)367 void ParseBusinessType(napi_env env, const napi_value arg, UpgradeInfo &upgradeInfo)
368 {
369 bool result = false;
370 napi_status status = napi_has_named_property(env, arg, "businessType", &result);
371 if (result && (status == napi_ok)) {
372 napi_value businessTypeValue;
373 status = napi_get_named_property(env, arg, "businessType", &businessTypeValue);
374 NapiUtil::GetString(env, businessTypeValue, "vendor", upgradeInfo.businessType.vendor);
375 }
376 upgradeInfo.businessType.subType = BusinessSubType::FIRMWARE;
377 }
378
GetUpgradeInfoFromArg(napi_env env,const napi_value arg,UpgradeInfo & upgradeInfo)379 ClientStatus ClientHelper::GetUpgradeInfoFromArg(napi_env env, const napi_value arg, UpgradeInfo &upgradeInfo)
380 {
381 PARAM_CHECK(CheckNapiObjectType(env, arg) == ClientStatus::CLIENT_SUCCESS,
382 return ClientStatus::CLIENT_INVALID_TYPE, "GetUpgradeInfoFromArg type invalid");
383 NapiUtil::GetString(env, arg, "upgradeApp", upgradeInfo.upgradeApp);
384 ParseBusinessType(env, arg, upgradeInfo);
385 NapiUtil::GetString(env, arg, "upgradeDevId", upgradeInfo.upgradeDevId);
386 NapiUtil::GetString(env, arg, "controlDevId", upgradeInfo.controlDevId);
387 return ClientStatus::CLIENT_SUCCESS;
388 }
389
GetUpgradePolicyFromArg(napi_env env,const napi_value arg,UpgradePolicy & upgradePolicy)390 ClientStatus ClientHelper::GetUpgradePolicyFromArg(napi_env env, const napi_value arg, UpgradePolicy &upgradePolicy)
391 {
392 PARAM_CHECK(CheckNapiObjectType(env, arg) == ClientStatus::CLIENT_SUCCESS,
393 return ClientStatus::CLIENT_INVALID_TYPE, "GetUpgradePolicyFromArg type invalid");
394
395 // upgradePolicy
396 NapiUtil::GetBool(env, arg, "downloadStrategy", upgradePolicy.downloadStrategy);
397 NapiUtil::GetBool(env, arg, "autoUpgradeStrategy", upgradePolicy.autoUpgradeStrategy);
398
399 // Get the array.
400 bool result = false;
401 napi_status status = napi_has_named_property(env, arg, "autoUpgradePeriods", &result);
402 if (result && (status == napi_ok)) {
403 napi_value value;
404 status = napi_get_named_property(env, arg, "autoUpgradePeriods", &value);
405 PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL, "Failed to get attr autoUpgradePeriods");
406 status = napi_is_array(env, value, &result);
407 PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL, "napi_is_array failed");
408 uint32_t count = 0;
409 status = napi_get_array_length(env, value, &count);
410 PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL,
411 "napi_get_array_length failed");
412 uint32_t i = 0;
413 do {
414 if (i >= COUNT_OF(upgradePolicy.autoUpgradePeriods)) {
415 break;
416 }
417 napi_value element;
418 napi_get_element(env, value, i, &element);
419 napi_get_value_uint32(env, element, &upgradePolicy.autoUpgradePeriods[i].start);
420 napi_get_value_uint32(env, element, &upgradePolicy.autoUpgradePeriods[i].end);
421 CLIENT_LOGI("upgradePolicy autoUpgradeInterval");
422 i++;
423 } while (i < count);
424 }
425 CLIENT_LOGI("upgradePolicy autoDownload:%d autoDownloadNet:%d",
426 static_cast<int32_t>(upgradePolicy.downloadStrategy),
427 static_cast<int32_t>(upgradePolicy.autoUpgradeStrategy));
428 return ClientStatus::CLIENT_SUCCESS;
429 }
430
GetDescriptionFormat(napi_env env,const napi_value arg,DescriptionFormat & format)431 ClientStatus ClientHelper::GetDescriptionFormat(napi_env env, const napi_value arg, DescriptionFormat &format)
432 {
433 int tmpFormat = 0;
434 NapiUtil::GetInt32(env, arg, "format", tmpFormat);
435 static const std::list formatList = {DescriptionFormat::STANDARD, DescriptionFormat::SIMPLIFIED};
436 PARAM_CHECK(IsValidEnum(formatList, tmpFormat), return ClientStatus::CLIENT_INVALID_TYPE,
437 "GetDescriptionFormat error, invalid format:%{public}d", tmpFormat);
438 format = static_cast<DescriptionFormat>(tmpFormat);
439 return ClientStatus::CLIENT_SUCCESS;
440 }
441
GetNetType(napi_env env,const napi_value arg,NetType & netType)442 ClientStatus ClientHelper::GetNetType(napi_env env, const napi_value arg, NetType &netType)
443 {
444 int allowNetwork = 0;
445 NapiUtil::GetInt32(env, arg, "allowNetwork", allowNetwork);
446 static const std::list netTypeList = {NetType::CELLULAR, NetType::METERED_WIFI, NetType::NOT_METERED_WIFI,
447 NetType::WIFI, NetType::CELLULAR_AND_WIFI};
448 PARAM_CHECK(IsValidEnum(netTypeList, allowNetwork), return ClientStatus::CLIENT_INVALID_TYPE,
449 "GetNetType error, invalid NetType:%{public}d", allowNetwork);
450 netType = static_cast<NetType>(allowNetwork);
451 return ClientStatus::CLIENT_SUCCESS;
452 }
453
GetOrder(napi_env env,const napi_value arg,Order & order)454 ClientStatus ClientHelper::GetOrder(napi_env env, const napi_value arg, Order &order)
455 {
456 int tmpOrder = 0;
457 NapiUtil::GetInt32(env, arg, "order", tmpOrder);
458 static const std::list orderList = {Order::DOWNLOAD, Order::INSTALL, Order::APPLY, Order::DOWNLOAD_AND_INSTALL,
459 Order::INSTALL_AND_APPLY};
460 PARAM_CHECK(IsValidEnum(orderList, tmpOrder), return ClientStatus::CLIENT_INVALID_TYPE,
461 "GetOrder error, invalid order:%{public}d", tmpOrder);
462 order = static_cast<Order>(tmpOrder);
463 return ClientStatus::CLIENT_SUCCESS;
464 }
465
GetOptionsFromArg(napi_env env,const napi_value arg,DescriptionOptions & descriptionOptions)466 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, DescriptionOptions &descriptionOptions)
467 {
468 ClientStatus ret = GetDescriptionFormat(env, arg, descriptionOptions.format);
469 PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
470 "GetDescriptionOptionsFromArg GetDescriptionFormat error");
471 NapiUtil::GetString(env, arg, "language", descriptionOptions.language);
472 return ClientStatus::CLIENT_SUCCESS;
473 }
474
GetOptionsFromArg(napi_env env,const napi_value arg,DownloadOptions & downloadOptions)475 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, DownloadOptions &downloadOptions)
476 {
477 ClientStatus ret = GetNetType(env, arg, downloadOptions.allowNetwork);
478 PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
479 "GetDownloadOptionsFromArg GetNetType error");
480
481 ret = GetOrder(env, arg, downloadOptions.order);
482 PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
483 "GetDownloadOptionsFromArg GetOrder error");
484 return ClientStatus::CLIENT_SUCCESS;
485 }
486
GetOptionsFromArg(napi_env env,const napi_value arg,PauseDownloadOptions & pauseDownloadOptions)487 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg,
488 PauseDownloadOptions &pauseDownloadOptions)
489 {
490 NapiUtil::GetBool(env, arg, "isAllowAutoResume", pauseDownloadOptions.isAllowAutoResume);
491 return ClientStatus::CLIENT_SUCCESS;
492 }
493
GetOptionsFromArg(napi_env env,const napi_value arg,ResumeDownloadOptions & resumeDownloadOptions)494 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg,
495 ResumeDownloadOptions &resumeDownloadOptions)
496 {
497 return GetNetType(env, arg, resumeDownloadOptions.allowNetwork);
498 }
499
GetVersionDigestInfoFromArg(napi_env env,const napi_value arg,VersionDigestInfo & versionDigestInfo)500 ClientStatus ClientHelper::GetVersionDigestInfoFromArg(napi_env env, const napi_value arg,
501 VersionDigestInfo &versionDigestInfo)
502 {
503 NapiUtil::GetString(env, arg, "versionDigest", versionDigestInfo.versionDigest);
504 CLIENT_LOGI("GetVersionDigestInfoFromArg versionDigest:%{public}s", versionDigestInfo.versionDigest.c_str());
505 return ClientStatus::CLIENT_SUCCESS;
506 }
507
GetOptionsFromArg(napi_env env,const napi_value arg,UpgradeOptions & upgradeOptions)508 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, UpgradeOptions &upgradeOptions)
509 {
510 return GetOrder(env, arg, upgradeOptions.order);
511 }
512
GetOptionsFromArg(napi_env env,const napi_value arg,ClearOptions & clearOptions)513 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, ClearOptions &clearOptions)
514 {
515 int32_t status = 0;
516 NapiUtil::GetInt32(env, arg, "status", status);
517 static const std::list statusList = {
518 UpgradeStatus::UPDATE_STATE_INIT, UpgradeStatus::UPDATE_STATE_CHECK_VERSION_ON,
519 UpgradeStatus::UPDATE_STATE_CHECK_VERSION_FAIL, UpgradeStatus::UPDATE_STATE_CHECK_VERSION_SUCCESS,
520 UpgradeStatus::UPDATE_STATE_DOWNLOAD_ON, UpgradeStatus::UPDATE_STATE_DOWNLOAD_PAUSE,
521 UpgradeStatus::UPDATE_STATE_DOWNLOAD_CANCEL, UpgradeStatus::UPDATE_STATE_DOWNLOAD_FAIL,
522 UpgradeStatus::UPDATE_STATE_DOWNLOAD_SUCCESS, UpgradeStatus::UPDATE_STATE_VERIFY_ON,
523 UpgradeStatus::UPDATE_STATE_VERIFY_FAIL, UpgradeStatus::UPDATE_STATE_VERIFY_SUCCESS,
524 UpgradeStatus::UPDATE_STATE_PACKAGE_TRANS_ON, UpgradeStatus::UPDATE_STATE_PACKAGE_TRANS_FAIL,
525 UpgradeStatus::UPDATE_STATE_PACKAGE_TRANS_SUCCESS, UpgradeStatus::UPDATE_STATE_INSTALL_ON,
526 UpgradeStatus::UPDATE_STATE_INSTALL_FAIL, UpgradeStatus::UPDATE_STATE_INSTALL_SUCCESS,
527 UpgradeStatus::UPDATE_STATE_UPDATE_ON, UpgradeStatus::UPDATE_STATE_UPDATE_FAIL,
528 UpgradeStatus::UPDATE_STATE_UPDATE_SUCCESS };
529 PARAM_CHECK(IsValidEnum(statusList, status), return ClientStatus::CLIENT_INVALID_TYPE,
530 "GetClearOptionsFromArg error, invalid status:%{public}d", status);
531 clearOptions.status = static_cast<UpgradeStatus>(status);
532 CLIENT_LOGI("GetClearOptionsFromArg status:%{public}d", clearOptions.status);
533 return ClientStatus::CLIENT_SUCCESS;
534 }
535
ParseUpgradeFile(napi_env env,const napi_value arg,UpgradeFile & upgradeFile)536 ClientStatus ParseUpgradeFile(napi_env env, const napi_value arg, UpgradeFile &upgradeFile)
537 {
538 napi_valuetype type = napi_undefined;
539 napi_status status = napi_typeof(env, arg, &type);
540 PARAM_CHECK(status == napi_ok && type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
541 "ParseUpgradeFile error, error type");
542
543 int32_t fileType = 0;
544 NapiUtil::GetInt32(env, arg, "fileType", fileType);
545 static const std::list enumList = { ComponentType::OTA };
546 PARAM_CHECK(IsValidEnum(enumList, fileType), return ClientStatus::CLIENT_INVALID_PARAM,
547 "ParseUpgradeFile error, invalid fileType:%{public}d", fileType);
548 upgradeFile.fileType = static_cast<ComponentType>(fileType);
549
550 NapiUtil::GetString(env, arg, "filePath", upgradeFile.filePath);
551 ClientHelper::TrimString(upgradeFile.filePath);
552 if (!ClientHelper::IsValidUpgradeFile(upgradeFile.filePath)) {
553 CLIENT_LOGE("ParseUpgradeFile, invalid filePath:%s", upgradeFile.filePath.c_str());
554 return ClientStatus::CLIENT_INVALID_PARAM;
555 }
556 CLIENT_LOGI("ParseUpgradeFile fileType:%{public}d, filePath:%s", fileType, upgradeFile.filePath.c_str());
557 return ClientStatus::CLIENT_SUCCESS;
558 }
559
GetUpgradeFileFromArg(napi_env env,const napi_value arg,UpgradeFile & upgradeFile)560 ClientStatus ClientHelper::GetUpgradeFileFromArg(napi_env env, const napi_value arg, UpgradeFile &upgradeFile)
561 {
562 return ParseUpgradeFile(env, arg, upgradeFile);
563 }
564
GetUpgradeFilesFromArg(napi_env env,const napi_value arg,std::vector<UpgradeFile> & upgradeFiles)565 ClientStatus ClientHelper::GetUpgradeFilesFromArg(napi_env env, const napi_value arg,
566 std::vector<UpgradeFile> &upgradeFiles)
567 {
568 bool result = false;
569 napi_status status = napi_is_array(env, arg, &result);
570 PARAM_CHECK(status == napi_ok && result, return ClientStatus::CLIENT_FAIL,
571 "GetUpgradeFilesFromArg error, napi_is_array failed");
572
573 uint32_t count = 0;
574 status = napi_get_array_length(env, arg, &count);
575 PARAM_CHECK((status == napi_ok) && (count > 0), return ClientStatus::CLIENT_FAIL,
576 "GetUpgradeFilesFromArg error, napi_get_array_length failed");
577 for (uint32_t idx = 0; idx < count; idx++) {
578 napi_value element;
579 napi_get_element(env, arg, idx, &element);
580 UpgradeFile upgradeFile;
581 ClientStatus ret = ParseUpgradeFile(env, element, upgradeFile);
582 if (ret != ClientStatus::CLIENT_SUCCESS) {
583 return ret;
584 }
585 upgradeFiles.emplace_back(upgradeFile);
586 }
587 CLIENT_LOGI("GetUpgradeFilesFromArg success, size:%{public}zu", upgradeFiles.size());
588 return ClientStatus::CLIENT_SUCCESS;
589 }
590
GetEventClassifyInfoFromArg(napi_env env,const napi_value arg,EventClassifyInfo & eventClassifyInfo)591 ClientStatus ClientHelper::GetEventClassifyInfoFromArg(napi_env env, const napi_value arg,
592 EventClassifyInfo &eventClassifyInfo)
593 {
594 napi_valuetype type = napi_undefined;
595 napi_status status = napi_typeof(env, arg, &type);
596 PARAM_CHECK(status == napi_ok && type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
597 "GetEventClassifyInfoFromArg error, error type");
598
599 int32_t eventClassify = 0;
600 NapiUtil::GetInt32(env, arg, "eventClassify", eventClassify);
601 static const std::list enumList = { EventClassify::TASK };
602 PARAM_CHECK(IsValidEnum(enumList, eventClassify), return ClientStatus::CLIENT_INVALID_TYPE,
603 "GetEventClassifyInfoFromArg error, invalid eventClassify:0x%{public}x", eventClassify);
604 eventClassifyInfo.eventClassify = static_cast<EventClassify>(eventClassify);
605
606 NapiUtil::GetString(env, arg, "extraInfo", eventClassifyInfo.extraInfo);
607 CLIENT_LOGI("GetEventClassifyInfoFromArg eventClassify:0x%{public}x, extraInfo:%s",
608 eventClassify, eventClassifyInfo.extraInfo.c_str());
609 return ClientStatus::CLIENT_SUCCESS;
610 }
611
BuildBusinessError(napi_env env,napi_value & obj,const BusinessError & businessError)612 int32_t ClientHelper::BuildBusinessError(napi_env env, napi_value &obj, const BusinessError &businessError)
613 {
614 if (!UpdateHelper::IsErrorExist(businessError)) {
615 // success, no need to set businessError
616 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
617 }
618 napi_status status = napi_create_object(env, &obj);
619 PARAM_CHECK(status == napi_ok,
620 return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
621 "Failed to create napi_create_object %d",
622 static_cast<int32_t>(status));
623
624 NapiUtil::SetString(env, obj, "message", businessError.message);
625 NapiUtil::SetInt32(env, obj, "errorNum", static_cast<int32_t>(businessError.errorNum));
626 BuildErrorMessages(env, obj, "data", businessError.data, COUNT_OF(businessError.data));
627 return CAST_INT(ClientStatus::CLIENT_SUCCESS);
628 }
629
BuildThrowError(napi_env env,const BusinessError & businessError)630 napi_value ClientHelper::BuildThrowError(napi_env env, const BusinessError &businessError)
631 {
632 napi_value message = nullptr;
633 napi_create_string_utf8(env, businessError.message.c_str(), NAPI_AUTO_LENGTH, &message);
634 napi_value error = nullptr;
635 napi_status status = napi_create_error(env, nullptr, message, &error);
636 PARAM_CHECK(status == napi_ok, return nullptr, "Failed to create napi_create_object %d",
637 static_cast<int32_t>(status));
638 NapiUtil::SetInt32(env, error, "code", static_cast<int32_t>(businessError.errorNum));
639 NapiUtil::SetString(env, error, "message", businessError.message);
640 BuildErrorMessages(env, error, "data", businessError.data, COUNT_OF(businessError.data));
641 return error;
642 }
643
ConvertVectorToStr(std::vector<std::string> & strVector)644 static std::string ConvertVectorToStr(std::vector<std::string> &strVector)
645 {
646 std::string strValue;
647 for (auto &str : strVector) {
648 if (!strValue.empty()) {
649 strValue.append(", ");
650 }
651 strValue.append(str);
652 }
653 return strValue;
654 }
655
NapiThrowParamError(napi_env env,std::vector<std::string> & paramNames,std::vector<std::string> & paramTypes)656 void ClientHelper::NapiThrowParamError(
657 napi_env env, std::vector<std::string> ¶mNames, std::vector<std::string> ¶mTypes)
658 {
659 BusinessError businessError;
660 CallResult errCode = CallResult::PARAM_ERR;
661 std::string errMsg = "BusinessError " + std::to_string(static_cast<int32_t>(errCode))
662 .append(": Parameter error. The type of { ").append(ConvertVectorToStr(paramNames)).append(" }")
663 .append("must be { ").append(ConvertVectorToStr(paramTypes)).append(" }.");
664 businessError.Build(errCode, errMsg);
665 napi_value msg = BuildThrowError(env, businessError);
666 napi_status status = napi_throw(env, msg);
667 PARAM_CHECK(status == napi_ok, return, "Failed to napi_throw %d", static_cast<int32_t>(status));
668 }
669
BuildTaskBody(napi_env env,napi_value & obj,EventId eventId,const TaskBody & taskBody)670 ClientStatus BuildTaskBody(napi_env env, napi_value &obj, EventId eventId, const TaskBody &taskBody)
671 {
672 auto iter = g_taskBodyTemplateMap.find(eventId);
673 PARAM_CHECK(iter != g_taskBodyTemplateMap.end(), return ClientStatus::CLIENT_INVALID_PARAM,
674 "BuildTaskBody error, eventId %{public}d", CAST_INT(eventId));
675 uint32_t taskBodyTemplate = iter->second;
676 napi_value napiTaskBody = nullptr;
677 napi_create_object(env, &napiTaskBody);
678 if (taskBodyTemplate & VERSION_DIGEST_INFO) {
679 BuildVersionDigestInfo(env, napiTaskBody, taskBody.versionDigestInfo);
680 }
681 if (taskBodyTemplate & UPGRADE_STATUS) {
682 NapiUtil::SetInt32(env, napiTaskBody, "status", taskBody.status);
683 }
684 if (taskBodyTemplate & SUB_STATUS) {
685 NapiUtil::SetInt32(env, napiTaskBody, "subStatus", taskBody.subStatus);
686 }
687 if (taskBodyTemplate & PROGRESS) {
688 NapiUtil::SetInt32(env, napiTaskBody, "progress", taskBody.progress);
689 }
690 if (taskBodyTemplate & INSTALL_MODE) {
691 NapiUtil::SetInt32(env, napiTaskBody, "installMode", taskBody.installMode);
692 }
693 if (taskBodyTemplate & ERROR_MESSAGE) {
694 BuildErrorMessages(env, napiTaskBody, "errorMessages", taskBody.errorMessages,
695 COUNT_OF(taskBody.errorMessages));
696 }
697 if (taskBodyTemplate & VERSION_COMPONENT) {
698 BuildVersionComponents(env, napiTaskBody, taskBody.versionComponents, COUNT_OF(taskBody.versionComponents));
699 }
700 napi_set_named_property(env, obj, "taskBody", napiTaskBody);
701 return ClientStatus::CLIENT_SUCCESS;
702 }
703
BuildEventInfo(napi_env env,napi_value & obj,const EventInfo & eventInfo)704 ClientStatus ClientHelper::BuildEventInfo(napi_env env, napi_value &obj, const EventInfo &eventInfo)
705 {
706 napi_status status = napi_create_object(env, &obj);
707 PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL,
708 "BuildEventInfo error, failed to create napi_create_object %{public}d", CAST_INT(status));
709
710 NapiUtil::SetInt32(env, obj, "eventId", CAST_INT(eventInfo.eventId));
711 ClientStatus ret = BuildTaskBody(env, obj, eventInfo.eventId, eventInfo.taskBody);
712 PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_FAIL,
713 "BuildEventInfo error, build task info fail");
714 return ClientStatus::CLIENT_SUCCESS;
715 }
716 } // namespace UpdateEngine
717 } // namespace OHOS
718