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