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 #if defined(OFFICIAL_BUILD)
80 reset_screen_params.SetBoolean("isOfficialBuild", true);
82 ShowScreen(kResetScreen, &reset_screen_params);
85 void ResetScreenHandler::Show() {
86 if (!page_is_ready()) {
91 ChooseAndApplyShowScenario();
94 void ResetScreenHandler::ChooseAndApplyShowScenario() {
95 PrefService* prefs = g_browser_process->local_state();
96 restart_required_ = !CommandLine::ForCurrentProcess()->HasSwitch(
97 switches::kFirstExecAfterBoot);
99 reboot_was_requested_ = false;
100 preparing_for_rollback_ = false;
101 if (!restart_required_) // First exec after boot.
102 reboot_was_requested_ = prefs->GetBoolean(prefs::kFactoryResetRequested);
104 if (CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kDisableRollbackOption)) {
106 rollback_available_ = false;
108 } else if (restart_required_) {
109 // Will require restart.
112 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
113 CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck,
114 weak_ptr_factory_.GetWeakPtr()));
118 void ResetScreenHandler::Hide() {
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);
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);
154 // Variants for screen message.
155 builder->AddF("resetPowerwashWarningDetails",
156 IDS_RESET_SCREEN_WARNING_POWERWASH_MSG,
157 IDS_SHORT_PRODUCT_NAME);
158 builder->AddF("resetPowerwashRollbackWarningDetails",
159 IDS_RESET_SCREEN_WARNING_POWERWASH_AND_ROLLBACK_MSG,
160 IDS_SHORT_PRODUCT_NAME);
162 builder->Add("confirmPowerwashTitle", IDS_RESET_SCREEN_POPUP_POWERWASH_TITLE);
163 builder->Add("confirmRollbackTitle", IDS_RESET_SCREEN_POPUP_ROLLBACK_TITLE);
164 builder->Add("confirmPowerwashMessage",
165 IDS_RESET_SCREEN_POPUP_POWERWASH_TEXT);
166 builder->Add("confirmRollbackMessage", IDS_RESET_SCREEN_POPUP_ROLLBACK_TEXT);
167 builder->Add("confirmResetButton", IDS_RESET_SCREEN_POPUP_CONFIRM_BUTTON);
170 // Invoked from call to CanRollbackCheck upon completion of the DBus call.
171 void ResetScreenHandler::OnRollbackCheck(bool can_rollback) {
172 VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback;
173 rollback_available_ = can_rollback;
178 void ResetScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
179 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
182 void ResetScreenHandler::Initialize() {
183 if (!page_is_ready() || !delegate_)
188 show_on_init_ = false;
192 void ResetScreenHandler::RegisterMessages() {
193 AddCallback("cancelOnReset", &ResetScreenHandler::HandleOnCancel);
194 AddCallback("restartOnReset", &ResetScreenHandler::HandleOnRestart);
195 AddCallback("powerwashOnReset", &ResetScreenHandler::HandleOnPowerwash);
196 AddCallback("resetOnLearnMore", &ResetScreenHandler::HandleOnLearnMore);
197 AddCallback("toggleRollbackOnResetScreen",
198 &ResetScreenHandler::HandleOnToggleRollback);
200 "showConfirmationOnReset", &ResetScreenHandler::HandleOnShowConfirm);
203 void ResetScreenHandler::HandleOnCancel() {
204 if (preparing_for_rollback_)
206 // Hide Rollback view for the next show.
207 if (rollback_available_ && rollback_checked_)
208 HandleOnToggleRollback();
211 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
214 void ResetScreenHandler::HandleOnRestart() {
215 PrefService* prefs = g_browser_process->local_state();
216 prefs->SetBoolean(prefs::kFactoryResetRequested, true);
217 prefs->CommitPendingWrite();
219 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
222 void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) {
223 if (rollback_available_ && rollback_checked) {
224 preparing_for_rollback_ = true;
225 CallJS("updateViewOnRollbackCall");
226 DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
227 VLOG(1) << "Starting Rollback";
228 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
230 if (rollback_checked && !rollback_available_) {
232 "Rollback was checked but not available. Starting powerwash.";
234 VLOG(1) << "Starting Powerwash";
235 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
240 void ResetScreenHandler::HandleOnLearnMore() {
241 VLOG(1) << "Trying to view the help article about reset options.";
242 if (!help_app_.get())
243 help_app_ = new HelpAppLauncher(GetNativeWindow());
244 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
247 void ResetScreenHandler::HandleOnToggleRollback() {
248 // Hide Rollback if visible.
249 if (rollback_available_ && rollback_checked_) {
250 VLOG(1) << "Hiding rollback view on reset screen";
251 CallJS("hideRollbackOption");
252 rollback_checked_ = false;
256 // Show Rollback if available.
257 VLOG(1) << "Requested rollback availability" << rollback_available_;
258 if (rollback_available_ && !rollback_checked_) {
259 UMA_HISTOGRAM_ENUMERATION(
260 "Reset.ChromeOS.PowerwashDialogShown",
261 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE,
262 reset::DIALOG_VIEW_TYPE_SIZE);
263 CallJS("showRollbackOption");
264 rollback_checked_ = true;
268 void ResetScreenHandler::HandleOnShowConfirm() {
269 int dialog_type = rollback_checked_ ?
270 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK :
271 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY;
272 UMA_HISTOGRAM_ENUMERATION(
273 "Reset.ChromeOS.PowerwashDialogShown",
275 reset::DIALOG_VIEW_TYPE_SIZE);
278 void ResetScreenHandler::UpdateStatusChanged(
279 const UpdateEngineClient::Status& status) {
280 VLOG(1) << "Update status change to " << status.status;
281 if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR ||
283 UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) {
284 preparing_for_rollback_ = false;
285 // Show error screen.
286 base::DictionaryValue params;
287 params.SetInteger("uiState", kErrorUIStateRollback);
288 ShowScreen(OobeUI::kScreenErrorMessage, ¶ms);
289 } else if (status.status ==
290 UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
291 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
295 } // namespace chromeos