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"
29 ResetScreen::ResetScreen(BaseScreenDelegate
* base_screen_delegate
,
31 : ResetModel(base_screen_delegate
),
33 weak_ptr_factory_(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);
47 ResetScreen::~ResetScreen() {
50 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
53 void ResetScreen::PrepareToShow() {
55 view_
->PrepareToShow();
58 void ResetScreen::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
;
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
;
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",
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() {
102 void ResetScreen::OnViewDestroyed(ResetView
* view
) {
107 void ResetScreen::OnUserAction(const std::string
& action_id
) {
108 if (action_id
== kUserActionCancelReset
)
110 else if (action_id
== kUserActionResetRestartPressed
)
112 else if (action_id
== kUserActionResetPowerwashPressed
)
114 else if (action_id
== kUserActionResetLearnMorePressed
)
116 else if (action_id
== kUserActionResetRollbackToggled
)
118 else if (action_id
== kUserActionResetShowConfirmationPressed
)
120 else if (action_id
== kUserActionResetResetConfirmationDismissed
)
121 OnConfirmationDismissed();
123 BaseScreen::OnUserAction(action_id
);
126 void ResetScreen::OnCancel() {
127 if (context_
.GetInteger(
128 kContextKeyScreenState
, STATE_RESTART_REQUIRED
) == STATE_REVERT_PROMISE
)
130 // Hide Rollback view for the next show.
131 if (context_
.GetBoolean(kContextKeyIsRollbackAvailable
) &&
132 context_
.GetBoolean(kContextKeyIsRollbackChecked
))
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
)
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();
153 if (context_
.GetBoolean(kContextKeyIsRollbackChecked
) &&
154 !context_
.GetBoolean(kContextKeyIsRollbackAvailable
)) {
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);
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",
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
);
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
||
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",
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