1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/update_manager/boxed_value.h"
18 
19 #include <stdint.h>
20 
21 #include <set>
22 #include <string>
23 
24 #include <base/strings/string_number_conversions.h>
25 #include <base/time/time.h>
26 
27 #include "update_engine/common/utils.h"
28 #include "update_engine/connection_utils.h"
29 #include "update_engine/update_manager/rollback_prefs.h"
30 #include "update_engine/update_manager/shill_provider.h"
31 #include "update_engine/update_manager/updater_provider.h"
32 #include "update_engine/update_manager/weekly_time.h"
33 
34 using chromeos_update_engine::ConnectionTethering;
35 using chromeos_update_engine::ConnectionType;
36 using chromeos_update_engine::connection_utils::StringForConnectionType;
37 using std::set;
38 using std::string;
39 
40 namespace chromeos_update_manager {
41 
42 // Template instantiation for common types; used in BoxedValue::ToString().
43 // Keep in sync with boxed_value_unitttest.cc.
44 
45 template <>
46 string BoxedValue::ValuePrinter<string>(const void* value) {
47   const string* val = reinterpret_cast<const string*>(value);
48   return *val;
49 }
50 
51 template <>
52 string BoxedValue::ValuePrinter<int>(const void* value) {
53   const int* val = reinterpret_cast<const int*>(value);
54 #if BASE_VER < 576279
55   return base::IntToString(*val);
56 #else
57   return base::NumberToString(*val);
58 #endif
59 }
60 
61 template <>
62 string BoxedValue::ValuePrinter<unsigned int>(const void* value) {
63   const unsigned int* val = reinterpret_cast<const unsigned int*>(value);
64 #if BASE_VER < 576279
65   return base::UintToString(*val);
66 #else
67   return base::NumberToString(*val);
68 #endif
69 }
70 
71 template <>
72 string BoxedValue::ValuePrinter<int64_t>(const void* value) {
73   const int64_t* val = reinterpret_cast<const int64_t*>(value);
74 #if BASE_VER < 576279
75   return base::Int64ToString(*val);
76 #else
77   return base::NumberToString(*val);
78 #endif
79 }
80 
81 template <>
82 string BoxedValue::ValuePrinter<uint64_t>(const void* value) {
83   const uint64_t* val = reinterpret_cast<const uint64_t*>(value);
84 #if BASE_VER < 576279
85   return base::Uint64ToString(*val);
86 #else
87   return base::NumberToString(*val);
88 #endif
89 }
90 
91 template <>
92 string BoxedValue::ValuePrinter<bool>(const void* value) {
93   const bool* val = reinterpret_cast<const bool*>(value);
94   return *val ? "true" : "false";
95 }
96 
97 template <>
98 string BoxedValue::ValuePrinter<double>(const void* value) {
99   const double* val = reinterpret_cast<const double*>(value);
100 #if BASE_VER < 576279
101   return base::DoubleToString(*val);
102 #else
103   return base::NumberToString(*val);
104 #endif
105 }
106 
107 template <>
108 string BoxedValue::ValuePrinter<base::Time>(const void* value) {
109   const base::Time* val = reinterpret_cast<const base::Time*>(value);
110   return chromeos_update_engine::utils::ToString(*val);
111 }
112 
113 template <>
114 string BoxedValue::ValuePrinter<base::TimeDelta>(const void* value) {
115   const base::TimeDelta* val = reinterpret_cast<const base::TimeDelta*>(value);
116   return chromeos_update_engine::utils::FormatTimeDelta(*val);
117 }
118 
119 template <>
120 string BoxedValue::ValuePrinter<ConnectionType>(const void* value) {
121   const ConnectionType* val = reinterpret_cast<const ConnectionType*>(value);
122   return StringForConnectionType(*val);
123 }
124 
125 template <>
126 string BoxedValue::ValuePrinter<set<ConnectionType>>(const void* value) {
127   string ret = "";
128   const set<ConnectionType>* val =
129       reinterpret_cast<const set<ConnectionType>*>(value);
130   for (auto& it : *val) {
131     ConnectionType type = it;
132     if (ret.size() > 0)
133       ret += ",";
134     ret += StringForConnectionType(type);
135   }
136   return ret;
137 }
138 
139 template <>
140 string BoxedValue::ValuePrinter<ConnectionTethering>(const void* value) {
141   const ConnectionTethering* val =
142       reinterpret_cast<const ConnectionTethering*>(value);
143   switch (*val) {
144     case ConnectionTethering::kNotDetected:
145       return "Not Detected";
146     case ConnectionTethering::kSuspected:
147       return "Suspected";
148     case ConnectionTethering::kConfirmed:
149       return "Confirmed";
150     case ConnectionTethering::kUnknown:
151       return "Unknown";
152   }
153   NOTREACHED();
154   return "Unknown";
155 }
156 
157 template <>
158 string BoxedValue::ValuePrinter<RollbackToTargetVersion>(const void* value) {
159   const RollbackToTargetVersion* val =
160       reinterpret_cast<const RollbackToTargetVersion*>(value);
161   switch (*val) {
162     case RollbackToTargetVersion::kUnspecified:
163       return "Unspecified";
164     case RollbackToTargetVersion::kDisabled:
165       return "Disabled";
166     case RollbackToTargetVersion::kRollbackAndPowerwash:
167       return "Rollback and powerwash";
168     case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
169       return "Rollback and restore if possible";
170     case RollbackToTargetVersion::kRollbackOnlyIfRestorePossible:
171       return "Rollback only if restore is possible";
172     case RollbackToTargetVersion::kMaxValue:
173       NOTREACHED();
174       return "Max value";
175   }
176   NOTREACHED();
177   return "Unknown";
178 }
179 
180 template <>
181 string BoxedValue::ValuePrinter<Stage>(const void* value) {
182   const Stage* val = reinterpret_cast<const Stage*>(value);
183   switch (*val) {
184     case Stage::kIdle:
185       return "Idle";
186     case Stage::kCheckingForUpdate:
187       return "Checking For Update";
188     case Stage::kUpdateAvailable:
189       return "Update Available";
190     case Stage::kDownloading:
191       return "Downloading";
192     case Stage::kVerifying:
193       return "Verifying";
194     case Stage::kFinalizing:
195       return "Finalizing";
196     case Stage::kUpdatedNeedReboot:
197       return "Updated, Need Reboot";
198     case Stage::kReportingErrorEvent:
199       return "Reporting Error Event";
200     case Stage::kAttemptingRollback:
201       return "Attempting Rollback";
202   }
203   NOTREACHED();
204   return "Unknown";
205 }
206 
207 template <>
208 string BoxedValue::ValuePrinter<UpdateRequestStatus>(const void* value) {
209   const UpdateRequestStatus* val =
210       reinterpret_cast<const UpdateRequestStatus*>(value);
211   switch (*val) {
212     case UpdateRequestStatus::kNone:
213       return "None";
214     case UpdateRequestStatus::kInteractive:
215       return "Interactive";
216     case UpdateRequestStatus::kPeriodic:
217       return "Periodic";
218   }
219   NOTREACHED();
220   return "Unknown";
221 }
222 
223 template <>
224 string BoxedValue::ValuePrinter<UpdateRestrictions>(const void* value) {
225   const UpdateRestrictions* val =
226       reinterpret_cast<const UpdateRestrictions*>(value);
227 
228   if (*val == UpdateRestrictions::kNone) {
229     return "None";
230   }
231   string retval = "Flags:";
232   if (*val & kRestrictDownloading) {
233     retval += " RestrictDownloading";
234   }
235   return retval;
236 }
237 
238 template <>
239 string BoxedValue::ValuePrinter<WeeklyTimeInterval>(const void* value) {
240   const WeeklyTimeInterval* val =
241       reinterpret_cast<const WeeklyTimeInterval*>(value);
242   return val->ToString();
243 }
244 
245 template <>
246 string BoxedValue::ValuePrinter<WeeklyTimeIntervalVector>(const void* value) {
247   const WeeklyTimeIntervalVector* val =
248       reinterpret_cast<const WeeklyTimeIntervalVector*>(value);
249 
250   string retval = "Disallowed intervals:\n";
251   for (const auto& interval : *val) {
252     retval += interval.ToString() + "\n";
253   }
254   return retval;
255 }
256 
257 }  // namespace chromeos_update_manager
258