xref: /aosp_15_r20/system/update_engine/metrics_utils.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2015 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker 
17*5a923131SAndroid Build Coastguard Worker #include "update_engine/metrics_utils.h"
18*5a923131SAndroid Build Coastguard Worker 
19*5a923131SAndroid Build Coastguard Worker #include <string>
20*5a923131SAndroid Build Coastguard Worker 
21*5a923131SAndroid Build Coastguard Worker #include <base/time/time.h>
22*5a923131SAndroid Build Coastguard Worker 
23*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/clock_interface.h"
24*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/constants.h"
25*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/utils.h"
26*5a923131SAndroid Build Coastguard Worker 
27*5a923131SAndroid Build Coastguard Worker using base::Time;
28*5a923131SAndroid Build Coastguard Worker using base::TimeDelta;
29*5a923131SAndroid Build Coastguard Worker 
30*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
31*5a923131SAndroid Build Coastguard Worker namespace metrics_utils {
32*5a923131SAndroid Build Coastguard Worker 
GetAttemptResult(ErrorCode code)33*5a923131SAndroid Build Coastguard Worker metrics::AttemptResult GetAttemptResult(ErrorCode code) {
34*5a923131SAndroid Build Coastguard Worker   ErrorCode base_code = static_cast<ErrorCode>(
35*5a923131SAndroid Build Coastguard Worker       static_cast<int>(code) & ~static_cast<int>(ErrorCode::kSpecialFlags));
36*5a923131SAndroid Build Coastguard Worker 
37*5a923131SAndroid Build Coastguard Worker   switch (base_code) {
38*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSuccess:
39*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kUpdateSucceeded;
40*5a923131SAndroid Build Coastguard Worker 
41*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdatedButNotActive:
42*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kUpdateSucceededNotActive;
43*5a923131SAndroid Build Coastguard Worker 
44*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadTransferError:
45*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kInternalLibCurlError:
46*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnresolvedHostError:
47*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnresolvedHostRecovered:
48*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kPayloadDownloadError;
49*5a923131SAndroid Build Coastguard Worker 
50*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataSize:
51*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataMagicString:
52*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureError:
53*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureVerificationError:
54*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadMismatchedType:
55*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnsupportedMajorPayloadVersion:
56*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnsupportedMinorPayloadVersion:
57*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadNewPartitionInfoError:
58*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadSignatureMissingInManifest:
59*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadManifestParseError:
60*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashMissingError:
61*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kMetadataMalformed;
62*5a923131SAndroid Build Coastguard Worker 
63*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashMismatch:
64*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashVerificationError:
65*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kOperationMalformed;
66*5a923131SAndroid Build Coastguard Worker 
67*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationExecutionError:
68*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kInstallDeviceOpenError:
69*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kKernelDeviceOpenError:
70*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadWriteError:
71*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFilesystemCopierError:
72*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFilesystemVerifierError:
73*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kVerityCalculationError:
74*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNotEnoughSpace:
75*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDeviceCorrupted:
76*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOverlayfsenabledError:
77*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kOperationExecutionError;
78*5a923131SAndroid Build Coastguard Worker 
79*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureMismatch:
80*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kMetadataVerificationFailed;
81*5a923131SAndroid Build Coastguard Worker 
82*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadSizeMismatchError:
83*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadHashMismatchError:
84*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadPayloadVerificationError:
85*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSignedDeltaPayloadExpectedError:
86*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadPayloadPubKeyVerificationError:
87*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadTimestampError:
88*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kPayloadVerificationFailed;
89*5a923131SAndroid Build Coastguard Worker 
90*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNewRootfsVerificationError:
91*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNewKernelVerificationError:
92*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kRollbackNotPossible:
93*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kVerificationFailed;
94*5a923131SAndroid Build Coastguard Worker 
95*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallRunnerError:
96*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallBootedFromFirmwareB:
97*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallFirmwareRONotUpdatable:
98*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostInstallMountError:
99*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kPostInstallFailed;
100*5a923131SAndroid Build Coastguard Worker 
101*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUserCanceled:
102*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kUpdateCanceled;
103*5a923131SAndroid Build Coastguard Worker 
104*5a923131SAndroid Build Coastguard Worker     // We should never get these errors in the update-attempt stage so
105*5a923131SAndroid Build Coastguard Worker     // return internal error if this happens.
106*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kError:
107*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestXMLParseError:
108*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestError:
109*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaResponseHandlerError:
110*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadStateInitializationError:
111*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestEmptyResponseError:
112*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataSignature:
113*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaResponseInvalid:
114*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
115*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaErrorInHTTPResponse:
116*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureMissingError:
117*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateDeferredForBackoff:
118*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallPowerwashError:
119*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateCanceledByChannelChange:
120*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestXMLHasEntityDecl:
121*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateIgnoredOverCellular:
122*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNoUpdate:
123*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFirstActiveOmahaPingSentPersistenceError:
124*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPackageExcludedFromUpdate:
125*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kInternalError;
126*5a923131SAndroid Build Coastguard Worker 
127*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateDeferredPerPolicy:
128*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNonCriticalUpdateInOOBE:
129*5a923131SAndroid Build Coastguard Worker       return metrics::AttemptResult::kUpdateSkipped;
130*5a923131SAndroid Build Coastguard Worker 
131*5a923131SAndroid Build Coastguard Worker     // Special flags. These can't happen (we mask them out above) but
132*5a923131SAndroid Build Coastguard Worker     // the compiler doesn't know that. Just break out so we can warn and
133*5a923131SAndroid Build Coastguard Worker     // return |kInternalError|.
134*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUmaReportedMax:
135*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestHTTPResponseBase:
136*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDevModeFlag:
137*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kResumedFlag:
138*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kTestImageFlag:
139*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kTestOmahaUrlFlag:
140*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSpecialFlags:
141*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateProcessing:
142*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateAlreadyInstalled:
143*5a923131SAndroid Build Coastguard Worker       break;
144*5a923131SAndroid Build Coastguard Worker   }
145*5a923131SAndroid Build Coastguard Worker 
146*5a923131SAndroid Build Coastguard Worker   LOG(ERROR) << "Unexpected error code " << base_code;
147*5a923131SAndroid Build Coastguard Worker   return metrics::AttemptResult::kInternalError;
148*5a923131SAndroid Build Coastguard Worker }
149*5a923131SAndroid Build Coastguard Worker 
GetDownloadErrorCode(ErrorCode code)150*5a923131SAndroid Build Coastguard Worker metrics::DownloadErrorCode GetDownloadErrorCode(ErrorCode code) {
151*5a923131SAndroid Build Coastguard Worker   ErrorCode base_code = static_cast<ErrorCode>(
152*5a923131SAndroid Build Coastguard Worker       static_cast<int>(code) & ~static_cast<int>(ErrorCode::kSpecialFlags));
153*5a923131SAndroid Build Coastguard Worker 
154*5a923131SAndroid Build Coastguard Worker   if (base_code >= ErrorCode::kOmahaRequestHTTPResponseBase) {
155*5a923131SAndroid Build Coastguard Worker     int http_status =
156*5a923131SAndroid Build Coastguard Worker         static_cast<int>(base_code) -
157*5a923131SAndroid Build Coastguard Worker         static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase);
158*5a923131SAndroid Build Coastguard Worker     if (http_status >= 200 && http_status <= 599) {
159*5a923131SAndroid Build Coastguard Worker       return static_cast<metrics::DownloadErrorCode>(
160*5a923131SAndroid Build Coastguard Worker           static_cast<int>(metrics::DownloadErrorCode::kHttpStatus200) +
161*5a923131SAndroid Build Coastguard Worker           http_status - 200);
162*5a923131SAndroid Build Coastguard Worker     } else if (http_status == 0) {
163*5a923131SAndroid Build Coastguard Worker       // The code is using HTTP Status 0 for "Unable to get http
164*5a923131SAndroid Build Coastguard Worker       // response code."
165*5a923131SAndroid Build Coastguard Worker       return metrics::DownloadErrorCode::kDownloadError;
166*5a923131SAndroid Build Coastguard Worker     }
167*5a923131SAndroid Build Coastguard Worker     LOG(WARNING) << "Unexpected HTTP status code " << http_status;
168*5a923131SAndroid Build Coastguard Worker     return metrics::DownloadErrorCode::kHttpStatusOther;
169*5a923131SAndroid Build Coastguard Worker   }
170*5a923131SAndroid Build Coastguard Worker 
171*5a923131SAndroid Build Coastguard Worker   switch (base_code) {
172*5a923131SAndroid Build Coastguard Worker     // Unfortunately, ErrorCode::kDownloadTransferError is returned for a wide
173*5a923131SAndroid Build Coastguard Worker     // variety of errors (proxy errors, host not reachable, timeouts etc.).
174*5a923131SAndroid Build Coastguard Worker     //
175*5a923131SAndroid Build Coastguard Worker     // For now just map that to kDownloading. See http://crbug.com/355745
176*5a923131SAndroid Build Coastguard Worker     // for how we plan to add more detail in the future.
177*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadTransferError:
178*5a923131SAndroid Build Coastguard Worker       return metrics::DownloadErrorCode::kDownloadError;
179*5a923131SAndroid Build Coastguard Worker 
180*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kInternalLibCurlError:
181*5a923131SAndroid Build Coastguard Worker       return metrics::DownloadErrorCode::kInternalLibCurlError;
182*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnresolvedHostError:
183*5a923131SAndroid Build Coastguard Worker       return metrics::DownloadErrorCode::kUnresolvedHostError;
184*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnresolvedHostRecovered:
185*5a923131SAndroid Build Coastguard Worker       return metrics::DownloadErrorCode::kUnresolvedHostRecovered;
186*5a923131SAndroid Build Coastguard Worker 
187*5a923131SAndroid Build Coastguard Worker     // All of these error codes are not related to downloading so break
188*5a923131SAndroid Build Coastguard Worker     // out so we can warn and return InputMalformed.
189*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSuccess:
190*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kError:
191*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestError:
192*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaResponseHandlerError:
193*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFilesystemCopierError:
194*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallRunnerError:
195*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostInstallMountError:
196*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOverlayfsenabledError:
197*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadMismatchedType:
198*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kInstallDeviceOpenError:
199*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kKernelDeviceOpenError:
200*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadHashMismatchError:
201*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadSizeMismatchError:
202*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadPayloadVerificationError:
203*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadNewPartitionInfoError:
204*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadWriteError:
205*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNewRootfsVerificationError:
206*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNewKernelVerificationError:
207*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSignedDeltaPayloadExpectedError:
208*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadPayloadPubKeyVerificationError:
209*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallBootedFromFirmwareB:
210*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadStateInitializationError:
211*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataMagicString:
212*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadSignatureMissingInManifest:
213*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadManifestParseError:
214*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureError:
215*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureVerificationError:
216*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureMismatch:
217*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashVerificationError:
218*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationExecutionError:
219*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashMismatch:
220*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestEmptyResponseError:
221*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestXMLParseError:
222*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataSize:
223*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadInvalidMetadataSignature:
224*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaResponseInvalid:
225*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
226*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateDeferredPerPolicy:
227*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNonCriticalUpdateInOOBE:
228*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaErrorInHTTPResponse:
229*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadOperationHashMissingError:
230*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDownloadMetadataSignatureMissingError:
231*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateDeferredForBackoff:
232*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallPowerwashError:
233*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateCanceledByChannelChange:
234*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPostinstallFirmwareRONotUpdatable:
235*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnsupportedMajorPayloadVersion:
236*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUnsupportedMinorPayloadVersion:
237*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestXMLHasEntityDecl:
238*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFilesystemVerifierError:
239*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUserCanceled:
240*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaUpdateIgnoredOverCellular:
241*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPayloadTimestampError:
242*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdatedButNotActive:
243*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNoUpdate:
244*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kRollbackNotPossible:
245*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kFirstActiveOmahaPingSentPersistenceError:
246*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kVerityCalculationError:
247*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kNotEnoughSpace:
248*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDeviceCorrupted:
249*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kPackageExcludedFromUpdate:
250*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateProcessing:
251*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUpdateAlreadyInstalled:
252*5a923131SAndroid Build Coastguard Worker       break;
253*5a923131SAndroid Build Coastguard Worker 
254*5a923131SAndroid Build Coastguard Worker     // Special flags. These can't happen (we mask them out above) but
255*5a923131SAndroid Build Coastguard Worker     // the compiler doesn't know that. Just break out so we can warn and
256*5a923131SAndroid Build Coastguard Worker     // return |kInputMalformed|.
257*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kUmaReportedMax:
258*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kOmahaRequestHTTPResponseBase:
259*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kDevModeFlag:
260*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kResumedFlag:
261*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kTestImageFlag:
262*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kTestOmahaUrlFlag:
263*5a923131SAndroid Build Coastguard Worker     case ErrorCode::kSpecialFlags:
264*5a923131SAndroid Build Coastguard Worker       LOG(ERROR) << "Unexpected error code " << base_code;
265*5a923131SAndroid Build Coastguard Worker       break;
266*5a923131SAndroid Build Coastguard Worker   }
267*5a923131SAndroid Build Coastguard Worker 
268*5a923131SAndroid Build Coastguard Worker   return metrics::DownloadErrorCode::kInputMalformed;
269*5a923131SAndroid Build Coastguard Worker }
270*5a923131SAndroid Build Coastguard Worker 
GetConnectionType(ConnectionType type,ConnectionTethering tethering)271*5a923131SAndroid Build Coastguard Worker metrics::ConnectionType GetConnectionType(ConnectionType type,
272*5a923131SAndroid Build Coastguard Worker                                           ConnectionTethering tethering) {
273*5a923131SAndroid Build Coastguard Worker   switch (type) {
274*5a923131SAndroid Build Coastguard Worker     case ConnectionType::kUnknown:
275*5a923131SAndroid Build Coastguard Worker       return metrics::ConnectionType::kUnknown;
276*5a923131SAndroid Build Coastguard Worker 
277*5a923131SAndroid Build Coastguard Worker     case ConnectionType::kDisconnected:
278*5a923131SAndroid Build Coastguard Worker       return metrics::ConnectionType::kDisconnected;
279*5a923131SAndroid Build Coastguard Worker 
280*5a923131SAndroid Build Coastguard Worker     case ConnectionType::kEthernet:
281*5a923131SAndroid Build Coastguard Worker       if (tethering == ConnectionTethering::kConfirmed)
282*5a923131SAndroid Build Coastguard Worker         return metrics::ConnectionType::kTetheredEthernet;
283*5a923131SAndroid Build Coastguard Worker       else
284*5a923131SAndroid Build Coastguard Worker         return metrics::ConnectionType::kEthernet;
285*5a923131SAndroid Build Coastguard Worker 
286*5a923131SAndroid Build Coastguard Worker     case ConnectionType::kWifi:
287*5a923131SAndroid Build Coastguard Worker       if (tethering == ConnectionTethering::kConfirmed)
288*5a923131SAndroid Build Coastguard Worker         return metrics::ConnectionType::kTetheredWifi;
289*5a923131SAndroid Build Coastguard Worker       else
290*5a923131SAndroid Build Coastguard Worker         return metrics::ConnectionType::kWifi;
291*5a923131SAndroid Build Coastguard Worker 
292*5a923131SAndroid Build Coastguard Worker     case ConnectionType::kCellular:
293*5a923131SAndroid Build Coastguard Worker       return metrics::ConnectionType::kCellular;
294*5a923131SAndroid Build Coastguard Worker   }
295*5a923131SAndroid Build Coastguard Worker 
296*5a923131SAndroid Build Coastguard Worker   LOG(ERROR) << "Unexpected network connection type: type="
297*5a923131SAndroid Build Coastguard Worker              << static_cast<int>(type)
298*5a923131SAndroid Build Coastguard Worker              << ", tethering=" << static_cast<int>(tethering);
299*5a923131SAndroid Build Coastguard Worker 
300*5a923131SAndroid Build Coastguard Worker   return metrics::ConnectionType::kUnknown;
301*5a923131SAndroid Build Coastguard Worker }
302*5a923131SAndroid Build Coastguard Worker 
GetPersistedValue(std::string_view key,PrefsInterface * prefs)303*5a923131SAndroid Build Coastguard Worker int64_t GetPersistedValue(std::string_view key, PrefsInterface* prefs) {
304*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
305*5a923131SAndroid Build Coastguard Worker   if (!prefs->Exists(key))
306*5a923131SAndroid Build Coastguard Worker     return 0;
307*5a923131SAndroid Build Coastguard Worker 
308*5a923131SAndroid Build Coastguard Worker   int64_t stored_value;
309*5a923131SAndroid Build Coastguard Worker   if (!prefs->GetInt64(key, &stored_value))
310*5a923131SAndroid Build Coastguard Worker     return 0;
311*5a923131SAndroid Build Coastguard Worker 
312*5a923131SAndroid Build Coastguard Worker   if (stored_value < 0) {
313*5a923131SAndroid Build Coastguard Worker     LOG(ERROR) << key << ": Invalid value (" << stored_value
314*5a923131SAndroid Build Coastguard Worker                << ") in persisted state. Defaulting to 0";
315*5a923131SAndroid Build Coastguard Worker     return 0;
316*5a923131SAndroid Build Coastguard Worker   }
317*5a923131SAndroid Build Coastguard Worker 
318*5a923131SAndroid Build Coastguard Worker   return stored_value;
319*5a923131SAndroid Build Coastguard Worker }
320*5a923131SAndroid Build Coastguard Worker 
SetNumReboots(int64_t num_reboots,PrefsInterface * prefs)321*5a923131SAndroid Build Coastguard Worker void SetNumReboots(int64_t num_reboots, PrefsInterface* prefs) {
322*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
323*5a923131SAndroid Build Coastguard Worker   prefs->SetInt64(kPrefsNumReboots, num_reboots);
324*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Number of Reboots during current update attempt = "
325*5a923131SAndroid Build Coastguard Worker             << num_reboots;
326*5a923131SAndroid Build Coastguard Worker }
327*5a923131SAndroid Build Coastguard Worker 
SetPayloadAttemptNumber(int64_t payload_attempt_number,PrefsInterface * prefs)328*5a923131SAndroid Build Coastguard Worker void SetPayloadAttemptNumber(int64_t payload_attempt_number,
329*5a923131SAndroid Build Coastguard Worker                              PrefsInterface* prefs) {
330*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
331*5a923131SAndroid Build Coastguard Worker   prefs->SetInt64(kPrefsPayloadAttemptNumber, payload_attempt_number);
332*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Payload Attempt Number = " << payload_attempt_number;
333*5a923131SAndroid Build Coastguard Worker }
334*5a923131SAndroid Build Coastguard Worker 
SetSystemUpdatedMarker(ClockInterface * clock,PrefsInterface * prefs)335*5a923131SAndroid Build Coastguard Worker void SetSystemUpdatedMarker(ClockInterface* clock, PrefsInterface* prefs) {
336*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
337*5a923131SAndroid Build Coastguard Worker   CHECK(clock);
338*5a923131SAndroid Build Coastguard Worker   Time update_finish_time = clock->GetMonotonicTime();
339*5a923131SAndroid Build Coastguard Worker   prefs->SetInt64(kPrefsSystemUpdatedMarker,
340*5a923131SAndroid Build Coastguard Worker                   update_finish_time.ToInternalValue());
341*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Updated Marker = " << utils::ToString(update_finish_time);
342*5a923131SAndroid Build Coastguard Worker }
343*5a923131SAndroid Build Coastguard Worker 
SetUpdateTimestampStart(const Time & update_start_time,PrefsInterface * prefs)344*5a923131SAndroid Build Coastguard Worker void SetUpdateTimestampStart(const Time& update_start_time,
345*5a923131SAndroid Build Coastguard Worker                              PrefsInterface* prefs) {
346*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
347*5a923131SAndroid Build Coastguard Worker   prefs->SetInt64(kPrefsUpdateTimestampStart,
348*5a923131SAndroid Build Coastguard Worker                   update_start_time.ToInternalValue());
349*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Update Monotonic Timestamp Start = "
350*5a923131SAndroid Build Coastguard Worker             << utils::ToString(update_start_time);
351*5a923131SAndroid Build Coastguard Worker }
352*5a923131SAndroid Build Coastguard Worker 
SetUpdateBootTimestampStart(const base::Time & update_start_boot_time,PrefsInterface * prefs)353*5a923131SAndroid Build Coastguard Worker void SetUpdateBootTimestampStart(const base::Time& update_start_boot_time,
354*5a923131SAndroid Build Coastguard Worker                                  PrefsInterface* prefs) {
355*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
356*5a923131SAndroid Build Coastguard Worker   prefs->SetInt64(kPrefsUpdateBootTimestampStart,
357*5a923131SAndroid Build Coastguard Worker                   update_start_boot_time.ToInternalValue());
358*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Update Boot Timestamp Start = "
359*5a923131SAndroid Build Coastguard Worker             << utils::ToString(update_start_boot_time);
360*5a923131SAndroid Build Coastguard Worker }
361*5a923131SAndroid Build Coastguard Worker 
LoadAndReportTimeToReboot(MetricsReporterInterface * metrics_reporter,PrefsInterface * prefs,ClockInterface * clock)362*5a923131SAndroid Build Coastguard Worker bool LoadAndReportTimeToReboot(MetricsReporterInterface* metrics_reporter,
363*5a923131SAndroid Build Coastguard Worker                                PrefsInterface* prefs,
364*5a923131SAndroid Build Coastguard Worker                                ClockInterface* clock) {
365*5a923131SAndroid Build Coastguard Worker   CHECK(prefs);
366*5a923131SAndroid Build Coastguard Worker   CHECK(clock);
367*5a923131SAndroid Build Coastguard Worker   int64_t stored_value = GetPersistedValue(kPrefsSystemUpdatedMarker, prefs);
368*5a923131SAndroid Build Coastguard Worker   if (stored_value == 0)
369*5a923131SAndroid Build Coastguard Worker     return false;
370*5a923131SAndroid Build Coastguard Worker 
371*5a923131SAndroid Build Coastguard Worker   Time system_updated_at = Time::FromInternalValue(stored_value);
372*5a923131SAndroid Build Coastguard Worker   const auto current_time = clock->GetMonotonicTime();
373*5a923131SAndroid Build Coastguard Worker   TimeDelta time_to_reboot = current_time - system_updated_at;
374*5a923131SAndroid Build Coastguard Worker   if (time_to_reboot.ToInternalValue() < 0) {
375*5a923131SAndroid Build Coastguard Worker     LOG(WARNING) << "time_to_reboot is negative - system_updated_at: "
376*5a923131SAndroid Build Coastguard Worker                  << utils::ToString(system_updated_at)
377*5a923131SAndroid Build Coastguard Worker                  << " current time: " << utils::ToString(current_time);
378*5a923131SAndroid Build Coastguard Worker     return false;
379*5a923131SAndroid Build Coastguard Worker   }
380*5a923131SAndroid Build Coastguard Worker   metrics_reporter->ReportTimeToReboot(time_to_reboot.InMinutes());
381*5a923131SAndroid Build Coastguard Worker   return true;
382*5a923131SAndroid Build Coastguard Worker }
383*5a923131SAndroid Build Coastguard Worker 
384*5a923131SAndroid Build Coastguard Worker }  // namespace metrics_utils
385*5a923131SAndroid Build Coastguard Worker }  // namespace chromeos_update_engine
386