1 /*
2  * Copyright (c) 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 "firmware_check_analyze_utils.h"
17 
18 #include <cinttypes>
19 #include <iostream>
20 #include <memory>
21 #include <map>
22 #include <string>
23 
24 #include "constant.h"
25 #include "dupdate_json_utils.h"
26 #include "file_utils.h"
27 #include "firmware_combine_version_utils.h"
28 #include "firmware_constant.h"
29 #include "firmware_log.h"
30 #include "firmware_preferences_utils.h"
31 #include "string_utils.h"
32 
33 namespace OHOS {
34 namespace UpdateEngine {
DoAnalyze(const std::string & rawJson,std::vector<FirmwareComponent> & components,Duration & duration,CheckAndAuthInfo & checkAndAuthInfo)35 void FirmwareCheckAnalyzeUtils::DoAnalyze(const std::string &rawJson, std::vector<FirmwareComponent> &components,
36     Duration &duration, CheckAndAuthInfo &checkAndAuthInfo)
37 {
38     BlCheckResponse response;
39     int32_t ret = CAST_INT(JsonParseError::ERR_OK);
40     nlohmann::json root;
41     if (!JsonUtils::ParseAndGetJsonObject(rawJson, root)) {
42         FIRMWARE_LOGE("fail to parse out a json object");
43         return;
44     }
45 
46     int32_t status = CAST_INT(CheckResultStatus::STATUS_SYSTEM_ERROR);
47     JsonUtils::GetValueAndSetTo(root, "searchStatus", status);
48 
49     checkAndAuthInfo.responseStatus = std::to_string(status);
50     if (!IsLegalStatus(status)) {
51         FIRMWARE_LOGI("not found new version!");
52         return;
53     }
54     if (status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE)) {
55         ret += AnalyzeBlVersionCheckResults(root, response);
56         ret += AnalyzeComponents(root);
57     }
58 
59     // 解析的都是必须字段,全部解析正常,才能给component赋值
60     if (ret == CAST_INT(JsonParseError::ERR_OK)) {
61         components = components_;
62     }
63 }
64 
AnalyzeBlVersionCheckResults(nlohmann::json & root,BlCheckResponse & response)65 int32_t FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults(nlohmann::json &root, BlCheckResponse &response)
66 {
67     if (root.find("checkResults") == root.end()) {
68         FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeBlVersionCheckResults no key checkResults");
69         return CAST_INT(JsonParseError::MISSING_PROP);
70     }
71     FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "", static_cast<uint64_t>(root["checkResults"].size()));
72     int32_t ret = CAST_INT(JsonParseError::ERR_OK);
73     for (auto &result : root["checkResults"]) {
74         int32_t status = CAST_INT(CheckResultStatus::STATUS_SYSTEM_ERROR);
75         JsonUtils::GetValueAndSetTo(root, "searchStatus", status);
76         if (status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE)) {
77             BlVersionCheckResult checkResult;
78             ret += JsonUtils::GetValueAndSetTo(result, "descriptPackageId", checkResult.descriptPackageId);
79             checkResult.blVersionType = 1;
80             checkResult.status = std::to_string(status);
81             UpdatePackage package;
82             package.versionId = "1";
83             int32_t versionPackageType = CAST_INT(PackageType::DYNAMIC);
84             ret += JsonUtils::GetValueAndSetTo(result, "packageType", versionPackageType);
85             package.versionPackageType = static_cast<PackageType>(versionPackageType);
86             package.packageIndex = 0;
87             checkResult.updatePackages.push_back(package);
88             TargetBlComponent component;
89             component.versionPackageType = package.versionPackageType;
90             ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.displayVersionNumber);
91             ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.versionNumber);
92             checkResult.targetBlComponents.push_back(component);
93             checkResult.blVersionInfo = result["blVersionInfo"].dump();
94             response.blVersionCheckResults.push_back(checkResult);
95             Version version;
96             version.versionId = "1";
97             ret += JsonUtils::GetValueAndSetTo(result, "versionCode", version.versionNumber);
98             ret += JsonUtils::GetValueAndSetTo(result, "url", version.url);
99             response.versionList.push_back(version);
100         }
101     }
102     return ret;
103 }
104 
AnalyzeComponents(nlohmann::json & root)105 int32_t FirmwareCheckAnalyzeUtils::AnalyzeComponents(nlohmann::json &root)
106 {
107     if (root.find("checkResults") == root.end()) {
108         FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key checkResults");
109         return CAST_INT(JsonParseError::MISSING_PROP);
110     }
111     FIRMWARE_LOGI("checkResults size is %{public}" PRIu64 "", static_cast<uint64_t>(root["checkResults"].size()));
112     int32_t ret = CAST_INT(JsonParseError::ERR_OK);
113     std::string componentId;
114     for (auto &result : root["checkResults"]) {
115         FirmwareComponent component;
116         int32_t componetSize = 0;
117         ret += JsonUtils::GetValueAndSetTo(result, "descriptPackageId", component.descriptPackageId);
118         ret += JsonUtils::GetValueAndSetTo(result, "url", component.url);
119         ret += JsonUtils::GetValueAndSetTo(result, "size", componetSize);
120         component.size = static_cast<int64_t>(componetSize);
121         component.fileName = StringUtils::GetLastSplitString(component.url, "/");
122         ret += JsonUtils::GetValueAndSetTo(result, "verifyInfo", component.verifyInfo);
123         ret += JsonUtils::GetValueAndSetTo(result, "versionCode", component.versionNumber);
124         ret += JsonUtils::GetValueAndSetTo(result, "versionName", component.targetBlVersionNumber);
125         component.targetBlDisplayVersionNumber = component.targetBlVersionNumber;
126         component.blVersionType = 1;
127         component.componentId = component.descriptPackageId;
128         component.versionPackageType = PackageType::NORMAL;
129         componentId = component.descriptPackageId;
130         components_.push_back(component);
131     }
132 
133     if (root.find("descriptInfo") == root.end()) {
134         FIRMWARE_LOGE("FirmwareCheckAnalyzeUtils::AnalyzeComponents no key descriptInfo");
135         return CAST_INT(JsonParseError::MISSING_PROP);
136     }
137     for (auto &descriptInfo : root["descriptInfo"]) {
138         int32_t descriptInfoType;
139         std::string descContent;
140         std::string subString = "quota";
141         std::string replString = "\"";
142         ret += JsonUtils::GetValueAndSetTo(descriptInfo, "descriptionType", descriptInfoType);
143         ret += JsonUtils::GetValueAndSetTo(descriptInfo, "content", descContent);
144         StringUtils::ReplaceStringAll(descContent, subString, replString);
145         std::string changelogFilePath = Firmware::CHANGELOG_PATH + "/" + componentId + ".xml";
146         FIRMWARE_LOGI("changelog file %{public}s", changelogFilePath.c_str());
147         std::string data = std::to_string(descriptInfoType) + "|" + descContent;
148         if (!FileUtils::SaveDataToFile(changelogFilePath, data)) {
149             FIRMWARE_LOGE("write data to description file error, %{public}s", changelogFilePath.c_str());
150         }
151     }
152 
153     return ret;
154 }
155 
IsLegalStatus(int32_t status)156 bool FirmwareCheckAnalyzeUtils::IsLegalStatus(int32_t status)
157 {
158     return status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_AVAILABLE) ||
159            status == CAST_INT(CheckResultStatus::STATUS_NEW_VERSION_NOT_AVAILABLE);
160 }
161 } // namespace UpdateEngine
162 } // namespace OHOS