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.
5 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h"
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 "chrome/grit/chromium_strings.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "chromeos/chromeos_switches.h"
22 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "chromeos/dbus/power_manager_client.h"
24 #include "chromeos/dbus/session_manager_client.h"
25 #include "chromeos/dbus/update_engine_client.h"
26 #include "content/public/browser/browser_thread.h"
30 const char kJsScreenPath[] = "login.ResetScreen";
33 const char kResetScreen[] = "reset";
35 const int kErrorUIStateRollback = 7;
41 ResetScreenHandler::ResetScreenHandler()
42 : BaseScreenHandler(kJsScreenPath),
45 restart_required_(true),
46 reboot_was_requested_(false),
47 rollback_available_(false),
48 rollback_checked_(false),
49 preparing_for_rollback_(false),
50 weak_ptr_factory_(this) {
53 ResetScreenHandler::~ResetScreenHandler() {
55 delegate_->OnActorDestroyed(this);
56 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
59 void ResetScreenHandler::PrepareToShow() {
62 void ResetScreenHandler::ShowWithParams() {
64 if (restart_required_) {
65 dialog_type = reset::DIALOG_SHORTCUT_RESTART_REQUIRED;
67 dialog_type = reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE;
69 UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown",
71 reset::DIALOG_VIEW_TYPE_SIZE);
73 PrefService* prefs = g_browser_process->local_state();
74 prefs->SetBoolean(prefs::kFactoryResetRequested, false);
75 prefs->CommitPendingWrite();
76 base::DictionaryValue reset_screen_params;
77 reset_screen_params.SetBoolean("restartRequired", restart_required_);
78 reset_screen_params.SetBoolean("rollbackAvailable", rollback_available_);
79 ShowScreen(kResetScreen, &reset_screen_params);
82 void ResetScreenHandler::Show() {
83 if (!page_is_ready()) {
88 ChooseAndApplyShowScenario();
91 void ResetScreenHandler::ChooseAndApplyShowScenario() {
92 PrefService* prefs = g_browser_process->local_state();
93 restart_required_ = !CommandLine::ForCurrentProcess()->HasSwitch(
94 switches::kFirstExecAfterBoot);
96 reboot_was_requested_ = false;
97 rollback_available_ = false;
98 preparing_for_rollback_ = false;
99 if (!restart_required_) // First exec after boot.
100 reboot_was_requested_ = prefs->GetBoolean(prefs::kFactoryResetRequested);
102 if (!CommandLine::ForCurrentProcess()->HasSwitch(
103 switches::kEnableRollbackOption)) {
104 rollback_available_ = false;
106 } else if (!restart_required_ && reboot_was_requested_) {
107 // First exec after boot.
108 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
109 CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck,
110 weak_ptr_factory_.GetWeakPtr()));
112 // Will require restart.
117 void ResetScreenHandler::Hide() {
118 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
121 void ResetScreenHandler::SetDelegate(Delegate* delegate) {
122 delegate_ = delegate;
127 void ResetScreenHandler::DeclareLocalizedValues(
128 LocalizedValuesBuilder* builder) {
129 builder->Add("resetScreenTitle", IDS_RESET_SCREEN_TITLE);
130 builder->Add("resetScreenAccessibleTitle", IDS_RESET_SCREEN_TITLE);
131 builder->Add("resetScreenIconTitle", IDS_RESET_SCREEN_ICON_TITLE);
132 builder->Add("cancelButton", IDS_CANCEL);
133 builder->Add("resetButtonReset", IDS_RESET_SCREEN_RESET);
134 builder->Add("resetButtonRestart", IDS_RELAUNCH_BUTTON);
135 builder->Add("resetButtonPowerwash", IDS_RESET_SCREEN_POWERWASH);
136 builder->Add("resetButtonPowerwashAndRollback",
137 IDS_RESET_SCREEN_POWERWASH_AND_REVERT);
139 builder->Add("resetWarningDataDetails",
140 IDS_RESET_SCREEN_WARNING_DETAILS_DATA);
141 builder->Add("resetRestartMessage", IDS_RESET_SCREEN_RESTART_MSG);
142 builder->AddF("resetRevertPromise",
143 IDS_RESET_SCREEN_PREPARING_REVERT_PROMISE,
144 IDS_SHORT_PRODUCT_NAME);
145 builder->AddF("resetRevertSpinnerMessage",
146 IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE,
147 IDS_SHORT_PRODUCT_NAME);
149 // Variants for screen title.
150 builder->AddF("resetWarningTitle",
151 IDS_RESET_SCREEN_WARNING_MSG,
152 IDS_SHORT_PRODUCT_NAME);
153 builder->AddF("resetPowerwashWarningTitle",
154 IDS_RESET_SCREEN_WARNING_POWERWASH_MSG,
155 IDS_SHORT_PRODUCT_NAME);
156 builder->AddF("resetPowerwasAndRollbackhWarningTitle",
157 IDS_RESET_SCREEN_WARNING_POWERWASH_AND_ROLLBACK_MSG,
158 IDS_SHORT_PRODUCT_NAME);
160 // Variants for screen message.
161 builder->AddF("resetPowerwashWarningDetails",
162 IDS_RESET_SCREEN_WARNING_DETAILS,
163 IDS_SHORT_PRODUCT_NAME);
164 builder->AddF("resetPowerwashRollbackWarningDetails",
165 IDS_RESET_SCREEN_WARNING_POWERWASH_AND_ROLLBACK_MSG,
166 IDS_SHORT_PRODUCT_NAME);
167 builder->AddF("resetPowerwashConfirmationDetails",
168 IDS_RESET_SCREEN_CONFIRMATION_WARNING_DETAILS,
169 IDS_SHORT_PRODUCT_NAME);
170 builder->AddF("resetPowerwashRollbackConfirmationDetails",
171 IDS_RESET_SCREEN_CONFIRMATION_WARNING_ROLLBACK_DETAILS,
172 IDS_SHORT_PRODUCT_NAME);
175 // Invoked from call to CanRollbackCheck upon completion of the DBus call.
176 void ResetScreenHandler::OnRollbackCheck(bool can_rollback) {
177 VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback;
178 rollback_available_ = can_rollback;
183 void ResetScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
184 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
187 void ResetScreenHandler::Initialize() {
188 if (!page_is_ready() || !delegate_)
193 show_on_init_ = false;
197 void ResetScreenHandler::RegisterMessages() {
198 AddCallback("cancelOnReset", &ResetScreenHandler::HandleOnCancel);
199 AddCallback("restartOnReset", &ResetScreenHandler::HandleOnRestart);
200 AddCallback("powerwashOnReset", &ResetScreenHandler::HandleOnPowerwash);
201 AddCallback("resetOnLearnMore", &ResetScreenHandler::HandleOnLearnMore);
203 "showRollbackOnResetScreen", &ResetScreenHandler::HandleOnShowRollback);
205 "hideRollbackOnResetScreen", &ResetScreenHandler::HandleOnHideRollback);
207 "showConfirmationOnReset", &ResetScreenHandler::HandleOnShowConfirm);
210 void ResetScreenHandler::HandleOnCancel() {
211 if (preparing_for_rollback_)
215 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
218 void ResetScreenHandler::HandleOnRestart() {
219 PrefService* prefs = g_browser_process->local_state();
220 prefs->SetBoolean(prefs::kFactoryResetRequested, true);
221 prefs->CommitPendingWrite();
223 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
226 void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) {
227 if (rollback_available_ && rollback_checked) {
228 preparing_for_rollback_ = true;
229 CallJS("updateViewOnRollbackCall");
230 DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
231 VLOG(1) << "Starting Rollback";
232 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
234 if (rollback_checked && !rollback_available_) {
236 "Rollback was checked but not available. Starting powerwash.";
238 VLOG(1) << "Starting Powerwash";
239 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
244 void ResetScreenHandler::HandleOnLearnMore() {
245 if (!help_app_.get())
246 help_app_ = new HelpAppLauncher(GetNativeWindow());
247 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
250 void ResetScreenHandler::HandleOnShowRollback() {
251 VLOG(1) << "Requested rollback availability" << rollback_available_;
252 if (rollback_available_) {
253 UMA_HISTOGRAM_ENUMERATION(
254 "Reset.ChromeOS.PowerwashDialogShown",
255 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE,
256 reset::DIALOG_VIEW_TYPE_SIZE);
257 CallJS("showRollbackOption");
258 rollback_checked_ = true;
262 void ResetScreenHandler::HandleOnHideRollback() {
263 if (rollback_available_ && rollback_checked_) {
264 CallJS("hideRollbackOption");
265 rollback_checked_ = false;
269 void ResetScreenHandler::HandleOnShowConfirm() {
270 int dialog_type = rollback_checked_ ?
271 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK :
272 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY;
273 UMA_HISTOGRAM_ENUMERATION(
274 "Reset.ChromeOS.PowerwashDialogShown",
276 reset::DIALOG_VIEW_TYPE_SIZE);
279 void ResetScreenHandler::UpdateStatusChanged(
280 const UpdateEngineClient::Status& status) {
281 VLOG(1) << "Update status change to " << status.status;
282 if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR ||
284 UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) {
285 preparing_for_rollback_ = false;
286 // Show error screen.
287 base::DictionaryValue params;
288 params.SetInteger("uiState", kErrorUIStateRollback);
289 ShowScreen(OobeUI::kScreenErrorMessage, ¶ms);
290 } else if (status.status ==
291 UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
292 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
296 } // namespace chromeos