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 #include <base/version.h> 27 28 #include "update_engine/common/connection_utils.h" 29 #include "update_engine/common/utils.h" 30 #include "update_engine/update_manager/rollback_prefs.h" 31 #include "update_engine/update_manager/shill_provider.h" 32 #include "update_engine/update_manager/updater_provider.h" 33 #include "update_engine/update_manager/weekly_time.h" 34 35 using chromeos_update_engine::ConnectionTethering; 36 using chromeos_update_engine::ConnectionType; 37 using chromeos_update_engine::connection_utils::StringForConnectionType; 38 using std::set; 39 using std::string; 40 41 namespace chromeos_update_manager { 42 43 // Template instantiation for common types; used in BoxedValue::ToString(). 44 // Keep in sync with boxed_value_unitttest.cc. 45 46 template <> ValuePrinter(const void * value)47string BoxedValue::ValuePrinter<string>(const void* value) { 48 const string* val = reinterpret_cast<const string*>(value); 49 return *val; 50 } 51 52 template <> ValuePrinter(const void * value)53string BoxedValue::ValuePrinter<int>(const void* value) { 54 const int* val = reinterpret_cast<const int*>(value); 55 return base::NumberToString(*val); 56 } 57 58 template <> ValuePrinter(const void * value)59string BoxedValue::ValuePrinter<unsigned int>(const void* value) { 60 const unsigned int* val = reinterpret_cast<const unsigned int*>(value); 61 return base::NumberToString(*val); 62 } 63 64 template <> ValuePrinter(const void * value)65string BoxedValue::ValuePrinter<int64_t>(const void* value) { 66 const int64_t* val = reinterpret_cast<const int64_t*>(value); 67 return base::NumberToString(*val); 68 } 69 70 template <> ValuePrinter(const void * value)71string BoxedValue::ValuePrinter<uint64_t>(const void* value) { 72 const uint64_t* val = reinterpret_cast<const uint64_t*>(value); 73 return base::NumberToString(*val); 74 } 75 76 template <> ValuePrinter(const void * value)77string BoxedValue::ValuePrinter<bool>(const void* value) { 78 const bool* val = reinterpret_cast<const bool*>(value); 79 return *val ? "true" : "false"; 80 } 81 82 template <> ValuePrinter(const void * value)83string BoxedValue::ValuePrinter<double>(const void* value) { 84 const double* val = reinterpret_cast<const double*>(value); 85 return base::NumberToString(*val); 86 } 87 88 template <> ValuePrinter(const void * value)89string BoxedValue::ValuePrinter<base::Time>(const void* value) { 90 const base::Time* val = reinterpret_cast<const base::Time*>(value); 91 return chromeos_update_engine::utils::ToString(*val); 92 } 93 94 template <> ValuePrinter(const void * value)95string BoxedValue::ValuePrinter<base::TimeDelta>(const void* value) { 96 const base::TimeDelta* val = reinterpret_cast<const base::TimeDelta*>(value); 97 return chromeos_update_engine::utils::FormatTimeDelta(*val); 98 } 99 100 template <> ValuePrinter(const void * value)101string BoxedValue::ValuePrinter<ConnectionType>(const void* value) { 102 const ConnectionType* val = reinterpret_cast<const ConnectionType*>(value); 103 return StringForConnectionType(*val); 104 } 105 106 template <> ValuePrinter(const void * value)107string BoxedValue::ValuePrinter<set<ConnectionType>>(const void* value) { 108 string ret = ""; 109 const set<ConnectionType>* val = 110 reinterpret_cast<const set<ConnectionType>*>(value); 111 for (auto& it : *val) { 112 ConnectionType type = it; 113 if (ret.size() > 0) 114 ret += ","; 115 ret += StringForConnectionType(type); 116 } 117 return ret; 118 } 119 120 template <> ValuePrinter(const void * value)121string BoxedValue::ValuePrinter<ConnectionTethering>(const void* value) { 122 const ConnectionTethering* val = 123 reinterpret_cast<const ConnectionTethering*>(value); 124 switch (*val) { 125 case ConnectionTethering::kNotDetected: 126 return "Not Detected"; 127 case ConnectionTethering::kSuspected: 128 return "Suspected"; 129 case ConnectionTethering::kConfirmed: 130 return "Confirmed"; 131 case ConnectionTethering::kUnknown: 132 return "Unknown"; 133 } 134 NOTREACHED(); 135 return "Unknown"; 136 } 137 138 template <> ValuePrinter(const void * value)139string BoxedValue::ValuePrinter<RollbackToTargetVersion>(const void* value) { 140 const RollbackToTargetVersion* val = 141 reinterpret_cast<const RollbackToTargetVersion*>(value); 142 switch (*val) { 143 case RollbackToTargetVersion::kUnspecified: 144 return "Unspecified"; 145 case RollbackToTargetVersion::kDisabled: 146 return "Disabled"; 147 case RollbackToTargetVersion::kRollbackAndPowerwash: 148 return "Rollback and powerwash"; 149 case RollbackToTargetVersion::kRollbackAndRestoreIfPossible: 150 return "Rollback and restore if possible"; 151 case RollbackToTargetVersion::kMaxValue: 152 NOTREACHED(); 153 return "Max value"; 154 } 155 NOTREACHED(); 156 return "Unknown"; 157 } 158 159 template <> ValuePrinter(const void * value)160string BoxedValue::ValuePrinter<Stage>(const void* value) { 161 const Stage* val = reinterpret_cast<const Stage*>(value); 162 switch (*val) { 163 case Stage::kIdle: 164 return "Idle"; 165 case Stage::kCheckingForUpdate: 166 return "Checking For Update"; 167 case Stage::kUpdateAvailable: 168 return "Update Available"; 169 case Stage::kDownloading: 170 return "Downloading"; 171 case Stage::kVerifying: 172 return "Verifying"; 173 case Stage::kFinalizing: 174 return "Finalizing"; 175 case Stage::kUpdatedNeedReboot: 176 return "Updated, Need Reboot"; 177 case Stage::kReportingErrorEvent: 178 return "Reporting Error Event"; 179 case Stage::kAttemptingRollback: 180 return "Attempting Rollback"; 181 case Stage::kCleanupPreviousUpdate: 182 return "Cleanup Previous Update"; 183 } 184 NOTREACHED(); 185 return "Unknown"; 186 } 187 188 template <> ValuePrinter(const void * value)189string BoxedValue::ValuePrinter<UpdateRequestStatus>(const void* value) { 190 const UpdateRequestStatus* val = 191 reinterpret_cast<const UpdateRequestStatus*>(value); 192 switch (*val) { 193 case UpdateRequestStatus::kNone: 194 return "None"; 195 case UpdateRequestStatus::kInteractive: 196 return "Interactive"; 197 case UpdateRequestStatus::kPeriodic: 198 return "Periodic"; 199 } 200 NOTREACHED(); 201 return "Unknown"; 202 } 203 204 template <> ValuePrinter(const void * value)205string BoxedValue::ValuePrinter<UpdateRestrictions>(const void* value) { 206 const UpdateRestrictions* val = 207 reinterpret_cast<const UpdateRestrictions*>(value); 208 209 if (*val == UpdateRestrictions::kNone) { 210 return "None"; 211 } 212 string retval = "Flags:"; 213 if (*val & kRestrictDownloading) { 214 retval += " RestrictDownloading"; 215 } 216 return retval; 217 } 218 219 template <> ValuePrinter(const void * value)220string BoxedValue::ValuePrinter<WeeklyTimeInterval>(const void* value) { 221 const WeeklyTimeInterval* val = 222 reinterpret_cast<const WeeklyTimeInterval*>(value); 223 return val->ToString(); 224 } 225 226 template <> ValuePrinter(const void * value)227string BoxedValue::ValuePrinter<WeeklyTimeIntervalVector>(const void* value) { 228 const WeeklyTimeIntervalVector* val = 229 reinterpret_cast<const WeeklyTimeIntervalVector*>(value); 230 231 string retval = "Disallowed intervals:\n"; 232 for (const auto& interval : *val) { 233 retval += interval.ToString() + "\n"; 234 } 235 return retval; 236 } 237 238 template <> ValuePrinter(const void * value)239string BoxedValue::ValuePrinter<ChannelDowngradeBehavior>(const void* value) { 240 const ChannelDowngradeBehavior* val = 241 reinterpret_cast<const ChannelDowngradeBehavior*>(value); 242 switch (*val) { 243 case ChannelDowngradeBehavior::kUnspecified: 244 return "Unspecified"; 245 case ChannelDowngradeBehavior::kWaitForVersionToCatchUp: 246 return "Wait for the target channel to catch up"; 247 case ChannelDowngradeBehavior::kRollback: 248 return "Roll back and powerwash on channel downgrade"; 249 case ChannelDowngradeBehavior::kAllowUserToConfigure: 250 return "User decides on channel downgrade behavior"; 251 } 252 NOTREACHED(); 253 return "Unknown"; 254 } 255 256 template <> ValuePrinter(const void * value)257string BoxedValue::ValuePrinter<base::Version>(const void* value) { 258 const base::Version* val = reinterpret_cast<const base::Version*>(value); 259 if (val->IsValid()) 260 return val->GetString(); 261 return "Unknown"; 262 } 263 264 } // namespace chromeos_update_manager 265