| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/upgrade_detector/installed_version_updater_chromeos.h" |
| |
| #include "base/functional/bind.h" |
| #include "base/logging.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "chrome/browser/upgrade_detector/build_state.h" |
| #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h" |
| |
| namespace { |
| |
| // The reason of the rollback used in the UpgradeDetector.RollbackReason |
| // histogram. |
| enum class RollbackReason { |
| kToMoreStableChannel = 0, |
| kEnterpriseRollback = 1, |
| kMaxValue = kEnterpriseRollback, |
| }; |
| |
| } // namespace |
| |
| InstalledVersionUpdater::InstalledVersionUpdater(BuildState* build_state) |
| : build_state_(build_state) { |
| ash::UpdateEngineClient::Get()->AddObserver(this); |
| } |
| |
| InstalledVersionUpdater::~InstalledVersionUpdater() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| ash::UpdateEngineClient::Get()->RemoveObserver(this); |
| } |
| |
| void InstalledVersionUpdater::UpdateStatusChanged( |
| const update_engine::StatusResult& status) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| |
| // If status changes to `IDLE`, there is no currently available update. |
| if (status.current_operation() == update_engine::Operation::IDLE) { |
| build_state_->SetUpdate(BuildState::UpdateType::kNone, base::Version(), |
| std::nullopt); |
| return; |
| } |
| |
| if (status.current_operation() != |
| update_engine::Operation::UPDATED_NEED_REBOOT) { |
| return; |
| } |
| |
| BuildState::UpdateType update_type = BuildState::UpdateType::kNormalUpdate; |
| |
| if (status.will_powerwash_after_reboot()) { |
| // Powerwash will be required, this can be triggered by an enterprise |
| // rollback or by the user switching to a more stable channel. Determine |
| // what kind of notification to show based on the enterprise rollback flag. |
| |
| if (status.is_enterprise_rollback()) { |
| update_type = BuildState::UpdateType::kEnterpriseRollback; |
| |
| base::UmaHistogramEnumeration("UpgradeDetector.RollbackReason", |
| RollbackReason::kEnterpriseRollback); |
| |
| LOG(WARNING) << "Device is rolling back, will require powerwash. Reason:" |
| << " Enterprise rollback."; |
| |
| } else { |
| // Powerwash must have been triggered by channel change. |
| update_type = BuildState::UpdateType::kChannelSwitchRollback; |
| |
| base::UmaHistogramEnumeration("UpgradeDetector.RollbackReason", |
| RollbackReason::kToMoreStableChannel); |
| |
| LOG(WARNING) << "Device is rolling back, will require powerwash. Reason:" |
| << " Channel switch."; |
| } |
| } |
| build_state_->SetUpdate(update_type, base::Version(status.new_version()), |
| std::nullopt); |
| } |