reset_screen_handler.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h" 6 7#include <string> 8 9#include "base/command_line.h" 10#include "base/metrics/histogram.h" 11#include "base/prefs/pref_registry_simple.h" 12#include "base/prefs/pref_service.h" 13#include "base/values.h" 14#include "chrome/browser/browser_process.h" 15#include "chrome/browser/chromeos/login/help_app_launcher.h" 16#include "chrome/browser/chromeos/reset/metrics.h" 17#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 18#include "chrome/common/pref_names.h" 19#include "chromeos/chromeos_switches.h" 20#include "chromeos/dbus/dbus_thread_manager.h" 21#include "chromeos/dbus/power_manager_client.h" 22#include "chromeos/dbus/session_manager_client.h" 23#include "chromeos/dbus/update_engine_client.h" 24#include "content/public/browser/browser_thread.h" 25#include "grit/browser_resources.h" 26#include "grit/chromium_strings.h" 27#include "grit/generated_resources.h" 28#include "ui/base/l10n/l10n_util.h" 29 30namespace { 31 32const char kJsScreenPath[] = "login.ResetScreen"; 33 34// Reset screen id. 35const char kResetScreen[] = "reset"; 36 37const int kErrorUIStateRollback = 7; 38 39} // namespace 40 41namespace chromeos { 42 43ResetScreenHandler::ResetScreenHandler() 44 : BaseScreenHandler(kJsScreenPath), 45 delegate_(NULL), 46 show_on_init_(false), 47 restart_required_(true), 48 reboot_was_requested_(false), 49 rollback_available_(false), 50 preparing_for_rollback_(false), 51 weak_ptr_factory_(this) { 52} 53 54ResetScreenHandler::~ResetScreenHandler() { 55 if (delegate_) 56 delegate_->OnActorDestroyed(this); 57 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); 58} 59 60void ResetScreenHandler::PrepareToShow() { 61} 62 63void ResetScreenHandler::ShowWithParams() { 64 int dialog_type; 65 if (reboot_was_requested_) { 66 dialog_type = rollback_available_ ? 67 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK : 68 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY; 69 } else { 70 dialog_type = rollback_available_ ? 71 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE : 72 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE; 73 } 74 UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown", 75 dialog_type, 76 reset::DIALOG_VIEW_TYPE_SIZE); 77 78 base::DictionaryValue reset_screen_params; 79 reset_screen_params.SetBoolean("showRestartMsg", restart_required_); 80 reset_screen_params.SetBoolean( 81 "showRollbackOption", rollback_available_ && !reboot_was_requested_); 82 reset_screen_params.SetBoolean( 83 "simpleConfirm", reboot_was_requested_ && !rollback_available_); 84 reset_screen_params.SetBoolean( 85 "rollbackConfirm", reboot_was_requested_ && rollback_available_); 86 87 PrefService* prefs = g_browser_process->local_state(); 88 prefs->SetBoolean(prefs::kFactoryResetRequested, false); 89 prefs->SetBoolean(prefs::kRollbackRequested, false); 90 prefs->CommitPendingWrite(); 91 ShowScreen(kResetScreen, &reset_screen_params); 92} 93 94void ResetScreenHandler::Show() { 95 if (!page_is_ready()) { 96 show_on_init_ = true; 97 return; 98 } 99 100 ChooseAndApplyShowScenario(); 101} 102 103void ResetScreenHandler::ChooseAndApplyShowScenario() { 104 PrefService* prefs = g_browser_process->local_state(); 105 restart_required_ = !CommandLine::ForCurrentProcess()->HasSwitch( 106 switches::kFirstExecAfterBoot); 107 reboot_was_requested_ = false; 108 rollback_available_ = false; 109 preparing_for_rollback_ = false; 110 if (!restart_required_) // First exec after boot. 111 reboot_was_requested_ = prefs->GetBoolean(prefs::kFactoryResetRequested); 112 113 if (CommandLine::ForCurrentProcess()->HasSwitch( 114 switches::kDisableRollbackOption)) { 115 rollback_available_ = false; 116 ShowWithParams(); 117 } else if (!restart_required_ && reboot_was_requested_) { 118 // First exec after boot. 119 PrefService* prefs = g_browser_process->local_state(); 120 rollback_available_ = prefs->GetBoolean(prefs::kRollbackRequested); 121 ShowWithParams(); 122 } else { 123 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()-> 124 CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck, 125 weak_ptr_factory_.GetWeakPtr())); 126 } 127} 128 129void ResetScreenHandler::Hide() { 130 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); 131} 132 133void ResetScreenHandler::SetDelegate(Delegate* delegate) { 134 delegate_ = delegate; 135 if (page_is_ready()) 136 Initialize(); 137} 138 139void ResetScreenHandler::DeclareLocalizedValues( 140 LocalizedValuesBuilder* builder) { 141 builder->Add("resetScreenTitle", IDS_RESET_SCREEN_TITLE); 142 builder->Add("resetScreenAccessibleTitle", IDS_RESET_SCREEN_TITLE); 143 builder->Add("resetScreenIconTitle",IDS_RESET_SCREEN_ICON_TITLE); 144 builder->Add("cancelButton", IDS_CANCEL); 145 146 builder->Add("resetWarningDataDetails", 147 IDS_RESET_SCREEN_WARNING_DETAILS_DATA); 148 builder->Add("resetRestartMessage", IDS_RESET_SCREEN_RESTART_MSG); 149 builder->AddF("resetRollbackOption", 150 IDS_RESET_SCREEN_ROLLBACK_OPTION, 151 IDS_SHORT_PRODUCT_NAME); 152 builder->AddF("resetRevertPromise", 153 IDS_RESET_SCREEN_PREPARING_REVERT_PROMISE, 154 IDS_SHORT_PRODUCT_NAME); 155 builder->AddF("resetRevertSpinnerMessage", 156 IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE, 157 IDS_SHORT_PRODUCT_NAME); 158 159 // Different variants of the same UI elements for all dialog cases. 160 builder->Add("resetButtonReset", IDS_RESET_SCREEN_RESET); 161 builder->Add("resetButtonRelaunch", IDS_RELAUNCH_BUTTON); 162 builder->Add("resetButtonPowerwash", IDS_RESET_SCREEN_POWERWASH); 163 164 builder->AddF( 165 "resetAndRollbackWarningTextConfirmational", 166 IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_AND_ROLLBACK_MSG, 167 IDS_SHORT_PRODUCT_NAME); 168 builder->AddF("resetWarningTextConfirmational", 169 IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_MSG, 170 IDS_SHORT_PRODUCT_NAME); 171 builder->AddF("resetWarningTextInitial", 172 IDS_RESET_SCREEN_WARNING_MSG, 173 IDS_SHORT_PRODUCT_NAME); 174 175 builder->AddF( 176 "resetAndRollbackWarningDetailsConfirmational", 177 IDS_RESET_SCREEN_CONFIRMATION_WARNING_ROLLBACK_DETAILS, 178 IDS_SHORT_PRODUCT_NAME); 179 builder->AddF("resetWarningDetailsConfirmational", 180 IDS_RESET_SCREEN_CONFIRMATION_WARNING_DETAILS, 181 IDS_SHORT_PRODUCT_NAME); 182 builder->AddF("resetWarningDetailsInitial", 183 IDS_RESET_SCREEN_WARNING_DETAILS, 184 IDS_SHORT_PRODUCT_NAME); 185} 186 187// Invoked from call to CanRollbackCheck upon completion of the DBus call. 188void ResetScreenHandler::OnRollbackCheck(bool can_rollback) { 189 VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback; 190 rollback_available_ = can_rollback; 191 ShowWithParams(); 192} 193 194// static 195void ResetScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) { 196 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false); 197 registry->RegisterBooleanPref(prefs::kRollbackRequested, false); 198} 199 200void ResetScreenHandler::Initialize() { 201 if (!page_is_ready() || !delegate_) 202 return; 203 204 if (show_on_init_) { 205 Show(); 206 show_on_init_ = false; 207 } 208} 209 210void ResetScreenHandler::RegisterMessages() { 211 AddCallback("cancelOnReset", &ResetScreenHandler::HandleOnCancel); 212 AddCallback("restartOnReset", &ResetScreenHandler::HandleOnRestart); 213 AddCallback("powerwashOnReset", &ResetScreenHandler::HandleOnPowerwash); 214 AddCallback("resetOnLearnMore", &ResetScreenHandler::HandleOnLearnMore); 215} 216 217void ResetScreenHandler::HandleOnCancel() { 218 if (preparing_for_rollback_) 219 return; 220 if (delegate_) 221 delegate_->OnExit(); 222 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); 223} 224 225void ResetScreenHandler::HandleOnRestart(bool should_rollback) { 226 PrefService* prefs = g_browser_process->local_state(); 227 prefs->SetBoolean(prefs::kFactoryResetRequested, true); 228 prefs->SetBoolean(prefs::kRollbackRequested, should_rollback); 229 prefs->CommitPendingWrite(); 230 231 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); 232} 233 234void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) { 235 if (rollback_available_ && (rollback_checked || reboot_was_requested_)) { 236 preparing_for_rollback_ = true; 237 CallJS("updateViewOnRollbackCall"); 238 DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this); 239 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback(); 240 } else { 241 if (rollback_checked && !rollback_available_) { 242 NOTREACHED() << 243 "Rollback was checked but not available. Starting powerwash."; 244 } 245 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> 246 StartDeviceWipe(); 247 } 248} 249 250void ResetScreenHandler::HandleOnLearnMore() { 251 if (!help_app_.get()) 252 help_app_ = new HelpAppLauncher(GetNativeWindow()); 253 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH); 254} 255 256void ResetScreenHandler::UpdateStatusChanged( 257 const UpdateEngineClient::Status& status) { 258 VLOG(1) << "Update status change to " << status.status; 259 if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR || 260 status.status == 261 UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) { 262 preparing_for_rollback_ = false; 263 // Show error screen. 264 base::DictionaryValue params; 265 params.SetInteger("uiState", kErrorUIStateRollback); 266 ShowScreen(OobeUI::kScreenErrorMessage, ¶ms); 267 } else if (status.status == 268 UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) { 269 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); 270 } 271} 272 273} // namespace chromeos 274