//
// 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