// // Copyright (C) 2014 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "update_engine/update_manager/boxed_value.h" #include <stdint.h> #include <set> #include <string> #include <base/strings/string_number_conversions.h> #include <base/time/time.h> #include "update_engine/common/utils.h" #include "update_engine/connection_utils.h" #include "update_engine/update_manager/rollback_prefs.h" #include "update_engine/update_manager/shill_provider.h" #include "update_engine/update_manager/updater_provider.h" #include "update_engine/update_manager/weekly_time.h" using chromeos_update_engine::ConnectionTethering; using chromeos_update_engine::ConnectionType; using chromeos_update_engine::connection_utils::StringForConnectionType; using std::set; using std::string; namespace chromeos_update_manager { // Template instantiation for common types; used in BoxedValue::ToString(). // Keep in sync with boxed_value_unitttest.cc. template <> string BoxedValue::ValuePrinter<string>(const void* value) { const string* val = reinterpret_cast<const string*>(value); return *val; } template <> string BoxedValue::ValuePrinter<int>(const void* value) { const int* val = reinterpret_cast<const int*>(value); #if BASE_VER < 576279 return base::IntToString(*val); #else return base::NumberToString(*val); #endif } template <> string BoxedValue::ValuePrinter<unsigned int>(const void* value) { const unsigned int* val = reinterpret_cast<const unsigned int*>(value); #if BASE_VER < 576279 return base::UintToString(*val); #else return base::NumberToString(*val); #endif } template <> string BoxedValue::ValuePrinter<int64_t>(const void* value) { const int64_t* val = reinterpret_cast<const int64_t*>(value); #if BASE_VER < 576279 return base::Int64ToString(*val); #else return base::NumberToString(*val); #endif } template <> string BoxedValue::ValuePrinter<uint64_t>(const void* value) { const uint64_t* val = reinterpret_cast<const uint64_t*>(value); #if BASE_VER < 576279 return base::Uint64ToString(*val); #else return base::NumberToString(*val); #endif } template <> string BoxedValue::ValuePrinter<bool>(const void* value) { const bool* val = reinterpret_cast<const bool*>(value); return *val ? "true" : "false"; } template <> string BoxedValue::ValuePrinter<double>(const void* value) { const double* val = reinterpret_cast<const double*>(value); #if BASE_VER < 576279 return base::DoubleToString(*val); #else return base::NumberToString(*val); #endif } template <> string BoxedValue::ValuePrinter<base::Time>(const void* value) { const base::Time* val = reinterpret_cast<const base::Time*>(value); return chromeos_update_engine::utils::ToString(*val); } template <> string BoxedValue::ValuePrinter<base::TimeDelta>(const void* value) { const base::TimeDelta* val = reinterpret_cast<const base::TimeDelta*>(value); return chromeos_update_engine::utils::FormatTimeDelta(*val); } template <> string BoxedValue::ValuePrinter<ConnectionType>(const void* value) { const ConnectionType* val = reinterpret_cast<const ConnectionType*>(value); return StringForConnectionType(*val); } template <> string BoxedValue::ValuePrinter<set<ConnectionType>>(const void* value) { string ret = ""; const set<ConnectionType>* val = reinterpret_cast<const set<ConnectionType>*>(value); for (auto& it : *val) { ConnectionType type = it; if (ret.size() > 0) ret += ","; ret += StringForConnectionType(type); } return ret; } template <> string BoxedValue::ValuePrinter<ConnectionTethering>(const void* value) { const ConnectionTethering* val = reinterpret_cast<const ConnectionTethering*>(value); switch (*val) { case ConnectionTethering::kNotDetected: return "Not Detected"; case ConnectionTethering::kSuspected: return "Suspected"; case ConnectionTethering::kConfirmed: return "Confirmed"; case ConnectionTethering::kUnknown: return "Unknown"; } NOTREACHED(); return "Unknown"; } template <> string BoxedValue::ValuePrinter<RollbackToTargetVersion>(const void* value) { const RollbackToTargetVersion* val = reinterpret_cast<const RollbackToTargetVersion*>(value); switch (*val) { case RollbackToTargetVersion::kUnspecified: return "Unspecified"; case RollbackToTargetVersion::kDisabled: return "Disabled"; case RollbackToTargetVersion::kRollbackAndPowerwash: return "Rollback and powerwash"; case RollbackToTargetVersion::kRollbackAndRestoreIfPossible: return "Rollback and restore if possible"; case RollbackToTargetVersion::kRollbackOnlyIfRestorePossible: return "Rollback only if restore is possible"; case RollbackToTargetVersion::kMaxValue: NOTREACHED(); return "Max value"; } NOTREACHED(); return "Unknown"; } template <> string BoxedValue::ValuePrinter<Stage>(const void* value) { const Stage* val = reinterpret_cast<const Stage*>(value); switch (*val) { case Stage::kIdle: return "Idle"; case Stage::kCheckingForUpdate: return "Checking For Update"; case Stage::kUpdateAvailable: return "Update Available"; case Stage::kDownloading: return "Downloading"; case Stage::kVerifying: return "Verifying"; case Stage::kFinalizing: return "Finalizing"; case Stage::kUpdatedNeedReboot: return "Updated, Need Reboot"; case Stage::kReportingErrorEvent: return "Reporting Error Event"; case Stage::kAttemptingRollback: return "Attempting Rollback"; } NOTREACHED(); return "Unknown"; } template <> string BoxedValue::ValuePrinter<UpdateRequestStatus>(const void* value) { const UpdateRequestStatus* val = reinterpret_cast<const UpdateRequestStatus*>(value); switch (*val) { case UpdateRequestStatus::kNone: return "None"; case UpdateRequestStatus::kInteractive: return "Interactive"; case UpdateRequestStatus::kPeriodic: return "Periodic"; } NOTREACHED(); return "Unknown"; } template <> string BoxedValue::ValuePrinter<UpdateRestrictions>(const void* value) { const UpdateRestrictions* val = reinterpret_cast<const UpdateRestrictions*>(value); if (*val == UpdateRestrictions::kNone) { return "None"; } string retval = "Flags:"; if (*val & kRestrictDownloading) { retval += " RestrictDownloading"; } return retval; } template <> string BoxedValue::ValuePrinter<WeeklyTimeInterval>(const void* value) { const WeeklyTimeInterval* val = reinterpret_cast<const WeeklyTimeInterval*>(value); return val->ToString(); } template <> string BoxedValue::ValuePrinter<WeeklyTimeIntervalVector>(const void* value) { const WeeklyTimeIntervalVector* val = reinterpret_cast<const WeeklyTimeIntervalVector*>(value); string retval = "Disallowed intervals:\n"; for (const auto& interval : *val) { retval += interval.ToString() + "\n"; } return retval; } } // namespace chromeos_update_manager