diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 9f6f4555d2263b..736ea9d1c81029 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd @@ -366,15 +366,24 @@ This file contains the strings for ash. Adobe Flash Player update available + + Device will be rolled back + Learn more about the latest $1Chromium OS update Restart to update + + Restart and reset + This update requires powerwashing your device. Learn more about the latest $1Chromium OS update. + + Your administrator is rolling back your device. All data will be deleted when the device is restarted. + Volume diff --git a/ash/public/interfaces/system_tray.mojom b/ash/public/interfaces/system_tray.mojom index c90c3e294f415e..7ef30f39dad3b2 100644 --- a/ash/public/interfaces/system_tray.mojom +++ b/ash/public/interfaces/system_tray.mojom @@ -33,11 +33,21 @@ interface SystemTray { // tracing is running. SetPerformanceTracingIconVisible(bool visible); - // Shows an icon in the system tray indicating that a software update is - // available. Once shown the icon persists until reboot. |severity| and - // |factory_reset_required| are used to set the icon, color, and tooltip. + // Shows an icon in the system tray or a notification on the unified system + // menu indicating that a software update is available. Once shown, the icon + // or the notification persists until reboot. + // |severity| specifies how critical is the update. + // |factory_reset_required| is true if during the update the device will + // be wiped. + // |rollback| specifies whether the update is actually an admin-initiated + // rollback. This implies that a the device will be wiped. + // |update_type| specifies the component which has been updated. + // + // These values are used to control the icon, color and the text of the + // tooltip or the notification. ShowUpdateIcon(UpdateSeverity severity, bool factory_reset_required, + bool rollback, UpdateType update_type); // If |visible| is true, shows an icon in the system tray which indicates that diff --git a/ash/system/model/system_tray_model.cc b/ash/system/model/system_tray_model.cc index 0ec2691176bdc0..bf9bc4a15777be 100644 --- a/ash/system/model/system_tray_model.cc +++ b/ash/system/model/system_tray_model.cc @@ -78,8 +78,9 @@ void SystemTrayModel::SetPerformanceTracingIconVisible(bool visible) { void SystemTrayModel::ShowUpdateIcon(mojom::UpdateSeverity severity, bool factory_reset_required, + bool rollback, mojom::UpdateType update_type) { - update_model()->SetUpdateAvailable(severity, factory_reset_required, + update_model()->SetUpdateAvailable(severity, factory_reset_required, rollback, update_type); } diff --git a/ash/system/model/system_tray_model.h b/ash/system/model/system_tray_model.h index ba14516cc18ed7..e0acc3bc8dae42 100644 --- a/ash/system/model/system_tray_model.h +++ b/ash/system/model/system_tray_model.h @@ -38,6 +38,7 @@ class SystemTrayModel : public mojom::SystemTray { void SetPerformanceTracingIconVisible(bool visible) override; void ShowUpdateIcon(mojom::UpdateSeverity severity, bool factory_reset_required, + bool rollback, mojom::UpdateType update_type) override; void SetUpdateOverCellularAvailableIconVisible(bool visible) override; void ShowVolumeSliderBubble() override; diff --git a/ash/system/model/update_model.cc b/ash/system/model/update_model.cc index caf6c3336ba81d..2f30e6dc6ee775 100644 --- a/ash/system/model/update_model.cc +++ b/ash/system/model/update_model.cc @@ -19,10 +19,12 @@ void UpdateModel::RemoveObserver(UpdateObserver* observer) { void UpdateModel::SetUpdateAvailable(mojom::UpdateSeverity severity, bool factory_reset_required, + bool rollback, mojom::UpdateType update_type) { update_required_ = true; severity_ = severity; factory_reset_required_ = factory_reset_required; + rollback_ = rollback; update_type_ = update_type; NotifyUpdateAvailable(); } diff --git a/ash/system/model/update_model.h b/ash/system/model/update_model.h index b7255446e77e37..b8557e508911d7 100644 --- a/ash/system/model/update_model.h +++ b/ash/system/model/update_model.h @@ -28,11 +28,12 @@ class UpdateModel { void RemoveObserver(UpdateObserver* observer); // Store the state that a software update is available. The state persists - // until reboot. Based on |severity| and |factory_reset_required|, the - // observer views can indicate the severity of the update to users by changing - // the icon, color, and tooltip. + // until reboot. Based on |severity|, |factory_reset_required| and |rollback|, + // the observer views can indicate the severity of the update to users by + // changing the icon, color, and tooltip. void SetUpdateAvailable(mojom::UpdateSeverity severity, bool factory_reset_required, + bool rollback, mojom::UpdateType update_type); // If |available| is true, a software update is available but user's agreement @@ -45,6 +46,7 @@ class UpdateModel { bool update_required() const { return update_required_; } bool factory_reset_required() const { return factory_reset_required_; } + bool rollback() const { return rollback_; } mojom::UpdateType update_type() const { return update_type_; } bool update_over_cellular_available() const { return update_over_cellular_available_; @@ -56,6 +58,7 @@ class UpdateModel { bool update_required_ = false; mojom::UpdateSeverity severity_ = mojom::UpdateSeverity::NONE; bool factory_reset_required_ = false; + bool rollback_ = false; mojom::UpdateType update_type_ = mojom::UpdateType::SYSTEM; bool update_over_cellular_available_ = false; diff --git a/ash/system/update/tray_update_unittest.cc b/ash/system/update/tray_update_unittest.cc index 742bc135bb05f0..99ed20c9cfe6bd 100644 --- a/ash/system/update/tray_update_unittest.cc +++ b/ash/system/update/tray_update_unittest.cc @@ -34,7 +34,7 @@ TEST_F(TrayUpdateTest, VisibilityAfterUpdate) { // Simulate an update. Shell::Get()->system_tray_model()->ShowUpdateIcon( - mojom::UpdateSeverity::LOW, false, mojom::UpdateType::SYSTEM); + mojom::UpdateSeverity::LOW, false, false, mojom::UpdateType::SYSTEM); // Tray item is now visible. EXPECT_TRUE(tray_update->tray_view()->visible()); @@ -58,7 +58,7 @@ TEST_F(TrayUpdateTest, VisibilityAfterFlashUpdate) { // Simulate an update. Shell::Get()->system_tray_model()->ShowUpdateIcon( - mojom::UpdateSeverity::LOW, false, mojom::UpdateType::FLASH); + mojom::UpdateSeverity::LOW, false, false, mojom::UpdateType::FLASH); // Tray item is now visible. EXPECT_TRUE(tray_update->tray_view()->visible()); diff --git a/ash/system/update/update_notification_controller.cc b/ash/system/update/update_notification_controller.cc index 00d5e4ea41cf96..c0c4ac4e069662 100644 --- a/ash/system/update/update_notification_controller.cc +++ b/ash/system/update/update_notification_controller.cc @@ -45,6 +45,10 @@ void UpdateNotificationController::OnUpdateAvailable() { return; } + message_center::SystemNotificationWarningLevel warning_level = + model_->rollback() + ? message_center::SystemNotificationWarningLevel::WARNING + : message_center::SystemNotificationWarningLevel::NORMAL; std::unique_ptr notification = Notification::CreateSystemNotification( message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, @@ -57,15 +61,18 @@ void UpdateNotificationController::OnUpdateAvailable() { base::BindRepeating( &UpdateNotificationController::HandleNotificationClick, weak_ptr_factory_.GetWeakPtr())), - kSystemMenuUpdateIcon, - message_center::SystemNotificationWarningLevel::NORMAL); + kSystemMenuUpdateIcon, warning_level); notification->set_pinned(true); if (model_->update_required()) { std::vector notification_actions; - message_center::ButtonInfo button_info = message_center::ButtonInfo( - l10n_util::GetStringUTF16(IDS_UPDATE_NOTIFICATION_RESTART_BUTTON)); - notification_actions.push_back(button_info); + if (model_->rollback()) { + notification_actions.push_back(message_center::ButtonInfo( + l10n_util::GetStringUTF16(IDS_ROLLBACK_NOTIFICATION_RESTART_BUTTON))); + } else { + notification_actions.push_back(message_center::ButtonInfo( + l10n_util::GetStringUTF16(IDS_UPDATE_NOTIFICATION_RESTART_BUTTON))); + } notification->set_buttons(notification_actions); } @@ -79,6 +86,9 @@ bool UpdateNotificationController::ShouldShowUpdate() const { base::string16 UpdateNotificationController::GetNotificationMessage() const { base::string16 system_app_name = l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_SYSTEM_APP_NAME); + if (model_->rollback()) { + return l10n_util::GetStringUTF16(IDS_UPDATE_NOTIFICATION_MESSAGE_ROLLBACK); + } if (model_->factory_reset_required()) { return l10n_util::GetStringFUTF16(IDS_UPDATE_NOTIFICATION_MESSAGE_POWERWASH, system_app_name); @@ -94,8 +104,9 @@ base::string16 UpdateNotificationController::GetNotificationTitle() const { IDS_UPDATE_NOTIFICATION_TITLE_FLASH_PLAYER); } #endif - - return l10n_util::GetStringUTF16(IDS_UPDATE_NOTIFICATION_TITLE); + return model_->rollback() + ? l10n_util::GetStringUTF16(IDS_ROLLBACK_NOTIFICATION_TITLE) + : l10n_util::GetStringUTF16(IDS_UPDATE_NOTIFICATION_TITLE); } void UpdateNotificationController::HandleNotificationClick( diff --git a/ash/system/update/update_notification_controller_unittest.cc b/ash/system/update/update_notification_controller_unittest.cc index 25d6cde6e6c15a..2ae8427a8ee6cb 100644 --- a/ash/system/update/update_notification_controller_unittest.cc +++ b/ash/system/update/update_notification_controller_unittest.cc @@ -85,7 +85,7 @@ TEST_F(UpdateNotificationControllerTest, VisibilityAfterUpdate) { // Simulate an update. Shell::Get()->system_tray_model()->ShowUpdateIcon( - mojom::UpdateSeverity::LOW, false, mojom::UpdateType::SYSTEM); + mojom::UpdateSeverity::LOW, false, false, mojom::UpdateType::SYSTEM); // The notification is now visible. ASSERT_TRUE(HasNotification()); @@ -103,7 +103,7 @@ TEST_F(UpdateNotificationControllerTest, VisibilityAfterFlashUpdate) { // Simulate an update. Shell::Get()->system_tray_model()->ShowUpdateIcon( - mojom::UpdateSeverity::LOW, false, mojom::UpdateType::FLASH); + mojom::UpdateSeverity::LOW, false, false, mojom::UpdateType::FLASH); // The notification is now visible. ASSERT_TRUE(HasNotification()); @@ -150,7 +150,7 @@ TEST_F(UpdateNotificationControllerTest, // Simulate an update that requires factory reset. Shell::Get()->system_tray_model()->ShowUpdateIcon( - mojom::UpdateSeverity::LOW, true, mojom::UpdateType::SYSTEM); + mojom::UpdateSeverity::LOW, true, false, mojom::UpdateType::SYSTEM); // The notification is now visible. ASSERT_TRUE(HasNotification()); @@ -162,4 +162,23 @@ TEST_F(UpdateNotificationControllerTest, EXPECT_EQ("Restart to update", GetNotificationButton(0)); } +TEST_F(UpdateNotificationControllerTest, VisibilityAfterRollback) { + // The system starts with no update pending, so the notification isn't + // visible. + EXPECT_FALSE(HasNotification()); + + // Simulate a rollback. + Shell::Get()->system_tray_model()->ShowUpdateIcon( + mojom::UpdateSeverity::LOW, false, true, mojom::UpdateType::SYSTEM); + + // The notification is now visible. + ASSERT_TRUE(HasNotification()); + EXPECT_EQ("Device will be rolled back", GetNotificationTitle()); + EXPECT_EQ( + "Your administrator is rolling back your device. All data will" + " be deleted when the device is restarted.", + GetNotificationMessage()); + EXPECT_EQ("Restart and reset", GetNotificationButton(0)); +} + } // namespace ash diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 7d0ad7767161c2..2bc240e543fb82 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp @@ -59,8 +59,8 @@ Restart - - Relaunch and Powerwash + + Restart and reset Powerwash for added security @@ -83,6 +83,12 @@ Channel changed. Restart your device to apply changes. + + Your administrator is rolling back this device ($190%) + + + Your administrator rolled back this device. Please save important files, then restart. All data on the device will be deleted. + Your $1Chromebook is up to date diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.cc b/chrome/browser/chromeos/upgrade_detector_chromeos.cc index fc1a76f162aca8..efd87ae784684e 100644 --- a/chrome/browser/chromeos/upgrade_detector_chromeos.cc +++ b/chrome/browser/chromeos/upgrade_detector_chromeos.cc @@ -146,7 +146,7 @@ void UpgradeDetectorChromeos::UpdateStatusChanged( set_upgrade_detected_time(tick_clock()->NowTicks()); if (status.is_rollback) { - set_is_factory_reset_required(true); + set_is_rollback(true); NotifyOnUpgrade(); } else { // Determine whether powerwash is required based on the channel. diff --git a/chrome/browser/resources/settings/about_page/about_page.js b/chrome/browser/resources/settings/about_page/about_page.js index 1ddbddc6f6084f..9fcdad3314a4e5 100644 --- a/chrome/browser/resources/settings/about_page/about_page.js +++ b/chrome/browser/resources/settings/about_page/about_page.js @@ -16,7 +16,12 @@ Polymer({ /** @private {?UpdateStatusChangedEvent} */ currentUpdateStatusEvent_: { type: Object, - value: {message: '', progress: 0, status: UpdateStatus.DISABLED}, + value: { + message: '', + progress: 0, + rollback: false, + status: UpdateStatus.DISABLED + }, }, // @@ -298,8 +303,8 @@ Polymer({ this.showRelaunch_ = this.checkStatus_(UpdateStatus.NEARLY_UPDATED); // // - this.showRelaunch_ = this.checkStatus_(UpdateStatus.NEARLY_UPDATED) && - !this.isTargetChannelMoreStable_(); + this.showRelaunch_ = + this.checkStatus_(UpdateStatus.NEARLY_UPDATED) && !this.isRollback_(); // }, @@ -324,6 +329,8 @@ Polymer({ // if (this.currentChannel_ != this.targetChannel_) return this.i18nAdvanced('aboutUpgradeSuccessChannelSwitch'); + if (this.currentUpdateStatusEvent_.rollback) + return this.i18nAdvanced('aboutRollbackSuccess'); // return this.i18nAdvanced('aboutUpgradeRelaunch'); case UpdateStatus.UPDATED: @@ -342,6 +349,11 @@ Polymer({ ] }); } + if (this.currentUpdateStatusEvent_.rollback) { + return this.i18nAdvanced('aboutRollbackInProgress', { + substitutions: [progressPercent], + }); + } // if (this.currentUpdateStatusEvent_.progress > 0) { // NOTE(dbeam): some platforms (i.e. Mac) always send 0% while @@ -442,9 +454,13 @@ Polymer({ * @return {boolean} * @private */ - isTargetChannelMoreStable_: function() { + isRollback_: function() { assert(this.currentChannel_.length > 0); assert(this.targetChannel_.length > 0); + if (this.currentUpdateStatusEvent_.rollback) { + return true; + } + // Channel switch to a more stable channel is also a rollback return settings.isTargetChannelMoreStable( this.currentChannel_, this.targetChannel_); }, @@ -464,8 +480,7 @@ Polymer({ * @private */ computeShowRelaunchAndPowerwash_: function() { - return this.checkStatus_(UpdateStatus.NEARLY_UPDATED) && - this.isTargetChannelMoreStable_(); + return this.checkStatus_(UpdateStatus.NEARLY_UPDATED) && this.isRollback_(); }, /** @private */ diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc index a89af16d816988..9327ba76717d92 100644 --- a/chrome/browser/ui/ash/system_tray_client.cc +++ b/chrome/browser/ui/ash/system_tray_client.cc @@ -453,7 +453,7 @@ void SystemTrayClient::HandleUpdateAvailable() { : ash::mojom::UpdateType::FLASH; system_tray_->ShowUpdateIcon(severity, detector->is_factory_reset_required(), - update_type); + detector->is_rollback(), update_type); } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/ui/webui/help/version_updater.h b/chrome/browser/ui/webui/help/version_updater.h index 2bfc0d51f94ee5..ad34cb0c53f614 100644 --- a/chrome/browser/ui/webui/help/version_updater.h +++ b/chrome/browser/ui/webui/help/version_updater.h @@ -52,15 +52,22 @@ class VersionUpdater { EolStatusCallback; #endif - // Used to update the client of status changes. int parameter is the progress - // and should only be non-zero for the UPDATING state. - // std::string parameter is the version of the available update and should be - // empty string when update is not available. - // int64_t parameter is the size in bytes of the available update and should - // be 0 when update is not available. - // base::string16 parameter is a message explaining a failure. - typedef base::Callback< - void(Status, int, const std::string&, int64_t, const base::string16&)> + // Used to update the client of status changes. + // |status| is the current state of the update. + // |progress| should only be non-zero for the UPDATING state. + // |rollback| indicates whether the update is actually a rollback, which + // requires wiping the device upon reboot. + // |version| is the version of the available update and should be empty string + // when update is not available. + // |update_size| is the size of the available update in bytes and should be 0 + // when update is not available. + // |message| is a message explaining a failure. + typedef base::Callback StatusCallback; // Used to show or hide the promote UI elements. Mac-only. diff --git a/chrome/browser/ui/webui/help/version_updater_basic.cc b/chrome/browser/ui/webui/help/version_updater_basic.cc index 8cb85a35079989..796d0a5a9f4a26 100644 --- a/chrome/browser/ui/webui/help/version_updater_basic.cc +++ b/chrome/browser/ui/webui/help/version_updater_basic.cc @@ -11,9 +11,10 @@ void VersionUpdaterBasic::CheckForUpdate( const StatusCallback& status_callback, const PromoteCallback&) { if (UpgradeDetector::GetInstance()->notify_upgrade()) - status_callback.Run(NEARLY_UPDATED, 0, std::string(), 0, base::string16()); + status_callback.Run(NEARLY_UPDATED, 0, false, std::string(), 0, + base::string16()); else - status_callback.Run(DISABLED, 0, std::string(), 0, base::string16()); + status_callback.Run(DISABLED, 0, false, std::string(), 0, base::string16()); } VersionUpdater* VersionUpdater::Create(content::WebContents* web_contents) { diff --git a/chrome/browser/ui/webui/help/version_updater_chromeos.cc b/chrome/browser/ui/webui/help/version_updater_chromeos.cc index 815a49eb16d2e5..66060e64fa7a92 100644 --- a/chrome/browser/ui/webui/help/version_updater_chromeos.cc +++ b/chrome/browser/ui/webui/help/version_updater_chromeos.cc @@ -106,7 +106,7 @@ base::string16 GetConnectionTypeAsUTF16(const chromeos::NetworkState* network) { bool EnsureCanUpdate(bool interactive, const VersionUpdater::StatusCallback& callback) { if (IsAutoUpdateDisabled()) { - callback.Run(VersionUpdater::DISABLED_BY_ADMIN, 0, std::string(), 0, + callback.Run(VersionUpdater::DISABLED_BY_ADMIN, 0, false, std::string(), 0, l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY)); return false; } @@ -120,13 +120,13 @@ bool EnsureCanUpdate(bool interactive, // to a network for which updates are disallowed. NetworkStatus status = GetNetworkStatus(interactive, network); if (status == NETWORK_STATUS_OFFLINE) { - callback.Run(VersionUpdater::FAILED_OFFLINE, 0, std::string(), 0, + callback.Run(VersionUpdater::FAILED_OFFLINE, 0, false, std::string(), 0, l10n_util::GetStringUTF16(IDS_UPGRADE_OFFLINE)); return false; } else if (status == NETWORK_STATUS_DISALLOWED) { base::string16 message = l10n_util::GetStringFUTF16( IDS_UPGRADE_DISALLOWED, GetConnectionTypeAsUTF16(network)); - callback.Run(VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED, 0, + callback.Run(VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED, 0, false, std::string(), 0, message); return false; } @@ -221,7 +221,7 @@ void VersionUpdaterCros::OnSetUpdateOverCellularOneTimePermission( // TODO(weidongg/691108): invoke callback to signal about page to show // appropriate error message. LOG(ERROR) << "Error setting update over cellular one time permission."; - callback_.Run(VersionUpdater::FAILED, 0, std::string(), 0, + callback_.Run(VersionUpdater::FAILED, 0, false, std::string(), 0, base::string16()); } } @@ -325,7 +325,8 @@ void VersionUpdaterCros::UpdateStatusChanged( break; } - callback_.Run(my_status, progress, version, size, message); + callback_.Run(my_status, progress, status.is_rollback, version, size, + message); last_operation_ = status.status; if (check_for_update_when_idle_ && @@ -339,5 +340,5 @@ void VersionUpdaterCros::OnUpdateCheck( // If version updating is not implemented, this binary is the most up-to-date // possible with respect to automatic updating. if (result == UpdateEngineClient::UPDATE_RESULT_NOTIMPLEMENTED) - callback_.Run(UPDATED, 0, std::string(), 0, base::string16()); + callback_.Run(UPDATED, 0, false, std::string(), 0, base::string16()); } diff --git a/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc b/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc index 2e47406c229865..587ec32394c1f1 100644 --- a/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc +++ b/chrome/browser/ui/webui/help/version_updater_chromeos_unittest.cc @@ -33,6 +33,7 @@ namespace { void CheckNotification(VersionUpdater::Status /* status */, int /* progress */, + bool /* rollback */, const std::string& /* version */, int64_t /* size */, const base::string16& /* message */) {} diff --git a/chrome/browser/ui/webui/help/version_updater_mac.mm b/chrome/browser/ui/webui/help/version_updater_mac.mm index 243d56245425d8..e339760732f7d3 100644 --- a/chrome/browser/ui/webui/help/version_updater_mac.mm +++ b/chrome/browser/ui/webui/help/version_updater_mac.mm @@ -108,7 +108,8 @@ - (void)handleStatusNotification:(NSNotification*)notification { } else { // There is no glue, or the application is on a read-only filesystem. // Updates and promotions are impossible. - status_callback_.Run(DISABLED, 0, std::string(), 0, base::string16()); + status_callback_.Run(DISABLED, 0, false, std::string(), 0, + base::string16()); } } @@ -235,7 +236,7 @@ - (void)handleStatusNotification:(NSNotification*)notification { } if (!status_callback_.is_null()) - status_callback_.Run(status, 0, std::string(), 0, message); + status_callback_.Run(status, 0, false, std::string(), 0, message); PromotionState promotion_state; if (!promote_callback_.is_null()) { diff --git a/chrome/browser/ui/webui/help/version_updater_win.cc b/chrome/browser/ui/webui/help/version_updater_win.cc index 861526eea8a14e..a09e57511764f0 100644 --- a/chrome/browser/ui/webui/help/version_updater_win.cc +++ b/chrome/browser/ui/webui/help/version_updater_win.cc @@ -29,7 +29,7 @@ void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback, // There is no supported integration with Google Update for Chromium. callback_ = callback; - callback_.Run(CHECKING, 0, std::string(), 0, base::string16()); + callback_.Run(CHECKING, 0, false, std::string(), 0, base::string16()); DoBeginUpdateCheck(false /* !install_update_if_possible */); } @@ -50,18 +50,18 @@ void VersionUpdaterWin::OnUpdateCheckComplete( // Notify the caller that the update is now beginning and initiate it. DoBeginUpdateCheck(true /* install_update_if_possible */); - callback_.Run(UPDATING, 0, std::string(), 0, base::string16()); + callback_.Run(UPDATING, 0, false, std::string(), 0, base::string16()); } void VersionUpdaterWin::OnUpgradeProgress(int progress, const base::string16& new_version) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - callback_.Run(UPDATING, progress, std::string(), 0, base::string16()); + callback_.Run(UPDATING, progress, false, std::string(), 0, base::string16()); } void VersionUpdaterWin::OnUpgradeComplete(const base::string16& new_version) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - callback_.Run(NEARLY_UPDATED, 0, std::string(), 0, base::string16()); + callback_.Run(NEARLY_UPDATED, 0, false, std::string(), 0, base::string16()); } void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code, @@ -92,7 +92,7 @@ void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code, } break; } - callback_.Run(status, 0, std::string(), 0, message); + callback_.Run(status, 0, false, std::string(), 0, message); } void VersionUpdaterWin::DoBeginUpdateCheck(bool install_update_if_possible) { @@ -104,7 +104,7 @@ void VersionUpdaterWin::DoBeginUpdateCheck(bool install_update_if_possible) { } void VersionUpdaterWin::OnPendingRestartCheck(bool is_update_pending_restart) { - callback_.Run(is_update_pending_restart ? NEARLY_UPDATED : UPDATED, 0, + callback_.Run(is_update_pending_restart ? NEARLY_UPDATED : UPDATED, 0, false, std::string(), 0, base::string16()); } diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index e72196562df1bc..6683c9e776744e 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc @@ -647,6 +647,7 @@ void AboutHandler::RequestUpdate() { void AboutHandler::SetUpdateStatus(VersionUpdater::Status status, int progress, + bool rollback, const std::string& version, int64_t size, const base::string16& message) { @@ -657,6 +658,7 @@ void AboutHandler::SetUpdateStatus(VersionUpdater::Status status, event->SetString("status", UpdateStatusToString(status)); event->SetString("message", message); event->SetInteger("progress", progress); + event->SetBoolean("rollback", rollback); event->SetString("version", version); // DictionaryValue does not support int64_t, so convert to string. event->SetString("size", base::Int64ToString(size)); diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h index 4363cda035708a..4c8ae08a2928dd 100644 --- a/chrome/browser/ui/webui/settings/about_handler.h +++ b/chrome/browser/ui/webui/settings/about_handler.h @@ -127,6 +127,7 @@ class AboutHandler : public settings::SettingsPageUIHandler, // Callback method which forwards status updates to the page. void SetUpdateStatus(VersionUpdater::Status status, int progress, + bool rollback, const std::string& version, int64_t size, const base::string16& fail_message); diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 59189009c128db..745ab481524fda 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc @@ -335,6 +335,8 @@ void AddAboutStrings(content::WebUIDataSource* html_source) { {"aboutPlatformLabel", IDS_SETTINGS_ABOUT_PAGE_PLATFORM}, {"aboutRelaunchAndPowerwash", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH_AND_POWERWASH}, + {"aboutRollbackInProgress", IDS_SETTINGS_UPGRADE_ROLLBACK_IN_PROGRESS}, + {"aboutRollbackSuccess", IDS_SETTINGS_UPGRADE_ROLLBACK_SUCCESS}, {"aboutUpgradeUpdatingChannelSwitch", IDS_SETTINGS_UPGRADE_UPDATING_CHANNEL_SWITCH}, {"aboutUpgradeSuccessChannelSwitch", diff --git a/chrome/browser/upgrade_detector.h b/chrome/browser/upgrade_detector.h index 140d3999701066..084b331828485a 100644 --- a/chrome/browser/upgrade_detector.h +++ b/chrome/browser/upgrade_detector.h @@ -93,6 +93,10 @@ class UpgradeDetector { bool is_factory_reset_required() const { return is_factory_reset_required_; } +#if defined(OS_CHROMEOS) + bool is_rollback() const { return is_rollback_; } +#endif // defined(OS_CHROMEOS) + // Retrieves the right icon based on the degree of severity (see // UpgradeNotificationAnnoyanceLevel, each level has an an accompanying icon // to go with it) to display within the app menu. @@ -202,6 +206,10 @@ class UpgradeDetector { is_factory_reset_required_ = is_factory_reset_required; } +#if defined(OS_CHROMEOS) + void set_is_rollback(bool is_rollback) { is_rollback_ = is_rollback; } +#endif // defined(OS_CHROMEOS) + private: FRIEND_TEST_ALL_PREFIXES(AppMenuModelTest, Basics); FRIEND_TEST_ALL_PREFIXES(SystemTrayClientTest, UpdateTrayIcon); @@ -245,6 +253,13 @@ class UpgradeDetector { // Whether a factory reset is needed to complete an update. bool is_factory_reset_required_; +#if defined(OS_CHROMEOS) + // Whether the update is actually an admin-initiated rollback of the device + // to an earlier version of Chrome OS, which results in the device being + // wiped when it's rebooted. + bool is_rollback_ = false; +#endif // defined(OS_CHROMEOS) + // A timer to check to see if we've been idle for long enough to show the // critical warning. Should only be set if |upgrade_available_| is // UPGRADE_AVAILABLE_CRITICAL.