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