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_result_process.h"
17
18 #include <fstream>
19 #include <iostream>
20 #include <map>
21 #include <ohos_types.h>
22 #include <sstream>
23 #include <string>
24 #include <unistd.h>
25
26 #include "string_utils.h"
27 #include "firmware_callback_utils.h"
28 #include "firmware_common.h"
29 #include "firmware_preferences_utils.h"
30 #include "firmware_task.h"
31 #include "firmware_task_operator.h"
32 #include "firmware_update_adapter.h"
33 #include "firmware_update_helper.h"
34
35 namespace OHOS {
36 namespace UpdateEngine {
37 static const std::string UPDATER_RESULT_FILE = "/data/updater/updater_result";
38 constexpr int32_t SYMBOL_LENGTH = 1;
39 constexpr uint32_t UPDATE_SUCCESSED = 1;
40 constexpr uint32_t UPDATE_FAILED = 2;
41 constexpr size_t PKG_PATH_INDEX = 0;
42 constexpr size_t RESULT_INDEX = 1;
43 constexpr size_t REASON_INDEX = 2;
44
ParseResult(const std::vector<std::string> & results,std::string & value,size_t index)45 void FirmwareResultProcess::ParseResult(const std::vector<std::string> &results, std::string &value, size_t index)
46 {
47 if (index >= results.size()) {
48 return;
49 }
50 value = results[index];
51 StringUtils::Trim(value);
52 }
53
GetUpdaterResult(const std::vector<FirmwareComponent> & components,std::map<std::string,UpdateResult> & resultMap)54 UpdateResultCode FirmwareResultProcess::GetUpdaterResult(const std::vector<FirmwareComponent> &components,
55 std::map<std::string, UpdateResult> &resultMap)
56 {
57 FIRMWARE_LOGE("GetUpdaterResult");
58 if (components.empty()) {
59 FIRMWARE_LOGE("components is empty");
60 return UpdateResultCode::FAILURE;
61 }
62 resultMap.clear();
63 std::ifstream infile;
64 infile.open(UPDATER_RESULT_FILE, std::ios_base::in);
65 if (!infile.is_open()) {
66 FIRMWARE_LOGE("open update status file fail!");
67 HandleFileError(resultMap, components);
68 } else {
69 std::string buffer;
70 while (!infile.eof()) {
71 getline(infile, buffer);
72 ParseUpdaterResultRecord(buffer, resultMap);
73 }
74 infile.close();
75 }
76 return HandleFileResults(resultMap, components);
77 }
78
CompareVersion(const FirmwareComponent & component)79 UpdateResult FirmwareResultProcess::CompareVersion(const FirmwareComponent &component)
80 {
81 bool isResultSuccess = false;
82 isResultSuccess = component.versionNumber == FirmwareUpdateAdapter::GetDisplayVersion();
83 FIRMWARE_LOGI("component.versionNumber=%{pubilc}s, GetDisplayVersion=%{pubilc}s",
84 component.versionNumber.c_str(), FirmwareUpdateAdapter::GetDisplayVersion().c_str());
85 UpdateResult updateResult;
86 updateResult.spath = component.spath;
87 if (isResultSuccess) {
88 updateResult.result = UPDATER_RESULT_SUCCESS;
89 updateResult.reason = UPDATER_RESULT_SUCCESS_REASON;
90 } else {
91 updateResult.result = UPDATER_RESULT_FAILURE;
92 updateResult.reason = UPDATER_RESULT_FAILURE_REASON;
93 }
94 return updateResult;
95 }
96
97 /*
98 /data/update/ota_package/firmware/versions/0856210b1bf14427a0706aff1bdd4aed/updater.zip|pass
99 /data/update/ota_package/firmware/versions/1faa6ba19df044449ab8a10cb05bf1a6/updater.zip|
100 fail:;02:145768,41554,454656487,1463ac:-1
101 /data/update/ota_package/firmware/versions/971c50415d604c80a170f911993c2e2a/updater.zip
102 spath为 /data/update/ota_package/firmware/versions/52e700cdd0974ee79c721dad4a54f119/updater.zip
103 result为 pass或者fail 没有则为空
104 reason为 ;02:145768,41554,454656487,1463ac:-1 没有则为空
105 */
ParseUpdaterResultRecord(const std::string & resultLine,std::map<std::string,UpdateResult> & resultMap)106 void FirmwareResultProcess::ParseUpdaterResultRecord(const std::string &resultLine,
107 std::map<std::string, UpdateResult> &resultMap)
108 {
109 FIRMWARE_LOGE("ParseUpdaterResultRecord");
110 if (resultLine.empty()) {
111 FIRMWARE_LOGE("resultLine is null");
112 return;
113 }
114 UpdateResult updateResult;
115 std::vector<std::string> results;
116 std::stringstream stringStream(resultLine);
117 std::string token;
118 while (std::getline(stringStream, token, '|')) {
119 results.push_back(token);
120 }
121
122 ParseResult(results, updateResult.spath, PKG_PATH_INDEX);
123 ParseResult(results, updateResult.result, RESULT_INDEX);
124 ParseResult(results, updateResult.reason, REASON_INDEX);
125
126 auto colonPlace = updateResult.result.find_first_of(":");
127 if (colonPlace != std::string::npos) {
128 updateResult.result = updateResult.result.substr(0, colonPlace);
129 updateResult.reason = results[RESULT_INDEX].substr(colonPlace + SYMBOL_LENGTH);
130 }
131 StringUtils::Trim(updateResult.spath);
132 StringUtils::Trim(updateResult.result);
133 StringUtils::Trim(updateResult.reason);
134 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
135 }
136
HandleFileError(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)137 void FirmwareResultProcess::HandleFileError(std::map<std::string, UpdateResult> &resultMap,
138 const std::vector<FirmwareComponent> &components)
139 {
140 resultMap.clear();
141 for (const auto &component : components) {
142 UpdateResult updateResult = CompareVersion(component);
143 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
144 }
145 }
146
HandleFileResults(std::map<std::string,UpdateResult> & resultMap,const std::vector<FirmwareComponent> & components)147 UpdateResultCode FirmwareResultProcess::HandleFileResults(std::map<std::string, UpdateResult> &resultMap,
148 const std::vector<FirmwareComponent> &components)
149 {
150 FirmwareTask task;
151 FirmwareTaskOperator().QueryTask(task);
152 if (!task.isExistTask) {
153 FIRMWARE_LOGI("HandleFileResults has no task");
154 return UpdateResultCode::FAILURE;
155 }
156 uint32_t hotaUpdateResult = 0;
157 for (const auto &component : components) {
158 std::string updateResultStatus;
159 auto result = resultMap.find(component.spath);
160 if (result == resultMap.end()) {
161 UpdateResult updateResult = CompareVersion(component);
162 resultMap.emplace(std::make_pair(updateResult.spath, updateResult));
163 FIRMWARE_LOGE("spath %{public}s, result %{public}s", component.spath.c_str(), updateResult.result.c_str());
164 updateResultStatus = updateResult.result;
165 } else {
166 updateResultStatus = result->second.result;
167 }
168 hotaUpdateResult |= updateResultStatus == UPDATER_RESULT_SUCCESS ? UPDATE_SUCCESSED : UPDATE_FAILED;
169 }
170
171 if (task.combinationType == CombinationType::HOTA) {
172 return hotaUpdateResult == UPDATE_SUCCESSED ? UpdateResultCode::SUCCESS : UpdateResultCode::FAILURE;
173 }
174
175 if (hotaUpdateResult != UPDATE_SUCCESSED) {
176 return UpdateResultCode::FAILURE;
177 }
178 return UpdateResultCode::SUCCESS;
179 }
180 } // namespace UpdateEngine
181 } // namespace OHOS
182