Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / login / screens / reset_screen.cc
blobb3106ec9b3386f21cd313dd881d3c89def4dbc90
1 // Copyright (c) 2014 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/chromeos/login/screens/reset_screen.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
14 #include "chrome/browser/chromeos/login/screens/error_screen.h"
15 #include "chrome/browser/chromeos/login/screens/network_error.h"
16 #include "chrome/browser/chromeos/login/screens/reset_view.h"
17 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
18 #include "chrome/browser/chromeos/reset/metrics.h"
19 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
20 #include "chrome/common/pref_names.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"
27 namespace chromeos {
29 ResetScreen::ResetScreen(BaseScreenDelegate* base_screen_delegate,
30 ResetView* view)
31 : ResetModel(base_screen_delegate),
32 view_(view),
33 weak_ptr_factory_(this) {
34 DCHECK(view_);
35 if (view_)
36 view_->Bind(*this);
37 context_.SetInteger(kContextKeyScreenState, STATE_RESTART_REQUIRED);
38 context_.SetBoolean(kContextKeyIsRollbackAvailable, false);
39 context_.SetBoolean(kContextKeyIsRollbackChecked, false);
40 context_.SetBoolean(kContextKeyIsConfirmational, false);
41 context_.SetBoolean(kContextKeyIsOfficialBuild, false);
42 #if defined(OFFICIAL_BUILD)
43 context_.SetBoolean(kContextKeyIsOfficialBuild, true);
44 #endif
47 ResetScreen::~ResetScreen() {
48 if (view_)
49 view_->Unbind();
50 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
53 void ResetScreen::PrepareToShow() {
54 if (view_)
55 view_->PrepareToShow();
58 void ResetScreen::Show() {
59 if (view_)
60 view_->Show();
62 int dialog_type = -1; // used by UMA metrics.
64 ContextEditor context_editor = GetContextEditor();
66 bool restart_required = !base::CommandLine::ForCurrentProcess()->HasSwitch(
67 switches::kFirstExecAfterBoot);
68 if (restart_required) {
69 context_editor.SetInteger(kContextKeyScreenState, STATE_RESTART_REQUIRED);
70 dialog_type = reset::DIALOG_SHORTCUT_RESTART_REQUIRED;
71 } else {
72 context_editor.SetInteger(kContextKeyScreenState, STATE_POWERWASH_PROPOSAL);
75 // Set availability of Rollback feature.
76 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
77 switches::kDisableRollbackOption)) {
78 context_editor.SetBoolean(kContextKeyIsRollbackAvailable, false);
79 dialog_type = reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE;
80 } else {
81 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
82 CanRollbackCheck(base::Bind(&ResetScreen::OnRollbackCheck,
83 weak_ptr_factory_.GetWeakPtr()));
86 if (dialog_type >= 0) {
87 UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown",
88 dialog_type,
89 reset::DIALOG_VIEW_TYPE_SIZE);
92 PrefService* prefs = g_browser_process->local_state();
93 prefs->SetBoolean(prefs::kFactoryResetRequested, false);
94 prefs->CommitPendingWrite();
97 void ResetScreen::Hide() {
98 if (view_)
99 view_->Hide();
102 void ResetScreen::OnViewDestroyed(ResetView* view) {
103 if (view_ == view)
104 view_ = nullptr;
107 void ResetScreen::OnUserAction(const std::string& action_id) {
108 if (action_id == kUserActionCancelReset)
109 OnCancel();
110 else if (action_id == kUserActionResetRestartPressed)
111 OnRestart();
112 else if (action_id == kUserActionResetPowerwashPressed)
113 OnPowerwash();
114 else if (action_id == kUserActionResetLearnMorePressed)
115 OnLearnMore();
116 else if (action_id == kUserActionResetRollbackToggled)
117 OnToggleRollback();
118 else if (action_id == kUserActionResetShowConfirmationPressed)
119 OnShowConfirm();
120 else if (action_id == kUserActionResetResetConfirmationDismissed)
121 OnConfirmationDismissed();
122 else
123 BaseScreen::OnUserAction(action_id);
126 void ResetScreen::OnCancel() {
127 if (context_.GetInteger(
128 kContextKeyScreenState, STATE_RESTART_REQUIRED) == STATE_REVERT_PROMISE)
129 return;
130 // Hide Rollback view for the next show.
131 if (context_.GetBoolean(kContextKeyIsRollbackAvailable) &&
132 context_.GetBoolean(kContextKeyIsRollbackChecked))
133 OnToggleRollback();
134 Finish(BaseScreenDelegate::RESET_CANCELED);
135 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
138 void ResetScreen::OnPowerwash() {
139 if (context_.GetInteger(kContextKeyScreenState, 0) !=
140 STATE_POWERWASH_PROPOSAL)
141 return;
143 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, false);
144 CommitContextChanges();
146 if (context_.GetBoolean(kContextKeyIsRollbackAvailable) &&
147 context_.GetBoolean(kContextKeyIsRollbackChecked)) {
148 GetContextEditor().SetInteger(kContextKeyScreenState, STATE_REVERT_PROMISE);
149 DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
150 VLOG(1) << "Starting Rollback";
151 DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
152 } else {
153 if (context_.GetBoolean(kContextKeyIsRollbackChecked) &&
154 !context_.GetBoolean(kContextKeyIsRollbackAvailable)) {
155 NOTREACHED() <<
156 "Rollback was checked but not available. Starting powerwash.";
158 VLOG(1) << "Starting Powerwash";
159 DBusThreadManager::Get()->GetSessionManagerClient()->StartDeviceWipe();
163 void ResetScreen::OnRestart() {
164 PrefService* prefs = g_browser_process->local_state();
165 prefs->SetBoolean(prefs::kFactoryResetRequested, true);
166 prefs->CommitPendingWrite();
168 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
171 void ResetScreen::OnToggleRollback() {
172 // Hide Rollback if visible.
173 if (context_.GetBoolean(kContextKeyIsRollbackAvailable) &&
174 context_.GetBoolean(kContextKeyIsRollbackChecked)) {
175 VLOG(1) << "Hiding rollback view on reset screen";
176 GetContextEditor().SetBoolean(kContextKeyIsRollbackChecked, false);
177 return;
180 // Show Rollback if available.
181 VLOG(1) << "Requested rollback availability" <<
182 context_.GetBoolean(kContextKeyIsRollbackAvailable);
183 if (context_.GetBoolean(kContextKeyIsRollbackAvailable) &&
184 !context_.GetBoolean(kContextKeyIsRollbackChecked)) {
185 UMA_HISTOGRAM_ENUMERATION(
186 "Reset.ChromeOS.PowerwashDialogShown",
187 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE,
188 reset::DIALOG_VIEW_TYPE_SIZE);
189 GetContextEditor().SetBoolean(kContextKeyIsRollbackChecked, true);
193 void ResetScreen::OnShowConfirm() {
194 int dialog_type = context_.GetBoolean(kContextKeyIsRollbackChecked) ?
195 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK :
196 reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY;
197 UMA_HISTOGRAM_ENUMERATION(
198 "Reset.ChromeOS.PowerwashDialogShown",
199 dialog_type,
200 reset::DIALOG_VIEW_TYPE_SIZE);
202 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, true);
205 void ResetScreen::OnLearnMore() {
206 #if defined(OFFICIAL_BUILD)
207 VLOG(1) << "Trying to view the help article about reset options.";
208 if (!help_app_.get()) {
209 help_app_ = new HelpAppLauncher(
210 LoginDisplayHostImpl::default_host()->GetNativeWindow());
212 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
213 #endif
216 void ResetScreen::OnConfirmationDismissed() {
217 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, false);
220 void ResetScreen::UpdateStatusChanged(
221 const UpdateEngineClient::Status& status) {
222 VLOG(1) << "Update status change to " << status.status;
223 if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR ||
224 status.status ==
225 UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) {
226 GetContextEditor().SetInteger(kContextKeyScreenState, STATE_ERROR);
227 // Show error screen.
228 GetErrorScreen()->SetUIState(NetworkError::UI_STATE_ROLLBACK_ERROR);
229 get_base_screen_delegate()->ShowErrorScreen();
230 } else if (status.status ==
231 UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
232 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
236 // Invoked from call to CanRollbackCheck upon completion of the DBus call.
237 void ResetScreen::OnRollbackCheck(bool can_rollback) {
238 VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback;
239 int dialog_type = can_rollback ?
240 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE :
241 reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE;
242 UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown",
243 dialog_type,
244 reset::DIALOG_VIEW_TYPE_SIZE);
246 GetContextEditor().SetBoolean(kContextKeyIsRollbackAvailable, can_rollback);
249 ErrorScreen* ResetScreen::GetErrorScreen() {
250 return get_base_screen_delegate()->GetErrorScreen();
253 } // namespace chromeos