OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/screens/reset_screen.h" | 5 #include "chrome/browser/chromeos/login/screens/reset_screen.h" |
6 | 6 |
7 #include "base/logging.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" |
8 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" | 13 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" |
9 #include "chrome/browser/chromeos/login/wizard_controller.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" |
| 25 |
10 | 26 |
11 namespace chromeos { | 27 namespace chromeos { |
12 | 28 |
13 ResetScreen::ResetScreen(BaseScreenDelegate* base_screen_delegate, | 29 ResetScreen::ResetScreen(BaseScreenDelegate* base_screen_delegate, |
14 ResetScreenActor* actor) | 30 ResetView* view) |
15 : BaseScreen(base_screen_delegate), actor_(actor) { | 31 : ResetModel(base_screen_delegate), |
16 DCHECK(actor_); | 32 view_(view), |
17 if (actor_) | 33 weak_ptr_factory_(this) { |
18 actor_->SetDelegate(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 |
19 } | 45 } |
20 | 46 |
21 ResetScreen::~ResetScreen() { | 47 ResetScreen::~ResetScreen() { |
22 if (actor_) | 48 if (view_) |
23 actor_->SetDelegate(NULL); | 49 view_->Unbind(); |
| 50 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); |
24 } | 51 } |
25 | 52 |
26 void ResetScreen::PrepareToShow() { | 53 void ResetScreen::PrepareToShow() { |
27 if (actor_) | 54 if (view_) |
28 actor_->PrepareToShow(); | 55 view_->PrepareToShow(); |
29 } | 56 } |
30 | 57 |
31 void ResetScreen::Show() { | 58 void ResetScreen::Show() { |
32 if (actor_) | 59 if (view_) |
33 actor_->Show(); | 60 view_->Show(); |
| 61 |
| 62 int dialog_type = -1; // used by UMA metrics. |
| 63 |
| 64 ContextEditor context_editor = GetContextEditor(); |
| 65 |
| 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); |
| 73 } |
| 74 |
| 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())); |
| 84 } |
| 85 |
| 86 if (dialog_type >= 0) { |
| 87 UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown", |
| 88 dialog_type, |
| 89 reset::DIALOG_VIEW_TYPE_SIZE); |
| 90 } |
| 91 |
| 92 PrefService* prefs = g_browser_process->local_state(); |
| 93 prefs->SetBoolean(prefs::kFactoryResetRequested, false); |
| 94 prefs->CommitPendingWrite(); |
34 } | 95 } |
35 | 96 |
36 void ResetScreen::Hide() { | 97 void ResetScreen::Hide() { |
37 if (actor_) | 98 if (view_) |
38 actor_->Hide(); | 99 view_->Hide(); |
39 } | 100 } |
40 | 101 |
41 std::string ResetScreen::GetName() const { | 102 void ResetScreen::OnViewDestroyed(ResetView* view) { |
42 return WizardController::kResetScreenName; | 103 if (view_ == view) |
43 } | 104 view_ = nullptr; |
44 | 105 } |
45 void ResetScreen::OnExit() { | 106 |
| 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); |
| 124 } |
| 125 |
| 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(); |
46 Finish(BaseScreenDelegate::RESET_CANCELED); | 134 Finish(BaseScreenDelegate::RESET_CANCELED); |
47 } | 135 DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); |
48 | 136 } |
49 void ResetScreen::OnActorDestroyed(ResetScreenActor* actor) { | 137 |
50 if (actor_ == actor) | 138 void ResetScreen::OnPowerwash() { |
51 actor_ = NULL; | 139 if (context_.GetInteger(kContextKeyScreenState, 0) != |
| 140 STATE_POWERWASH_PROPOSAL) |
| 141 return; |
| 142 |
| 143 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, false); |
| 144 CommitContextChanges(); |
| 145 |
| 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."; |
| 157 } |
| 158 VLOG(1) << "Starting Powerwash"; |
| 159 DBusThreadManager::Get()->GetSessionManagerClient()->StartDeviceWipe(); |
| 160 } |
| 161 } |
| 162 |
| 163 void ResetScreen::OnRestart() { |
| 164 PrefService* prefs = g_browser_process->local_state(); |
| 165 prefs->SetBoolean(prefs::kFactoryResetRequested, true); |
| 166 prefs->CommitPendingWrite(); |
| 167 |
| 168 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); |
| 169 } |
| 170 |
| 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; |
| 178 } |
| 179 |
| 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); |
| 190 } |
| 191 } |
| 192 |
| 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); |
| 201 |
| 202 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, true); |
| 203 } |
| 204 |
| 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()); |
| 211 } |
| 212 help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH); |
| 213 #endif |
| 214 } |
| 215 |
| 216 void ResetScreen::OnConfirmationDismissed() { |
| 217 GetContextEditor().SetBoolean(kContextKeyIsConfirmational, false); |
| 218 } |
| 219 |
| 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(); |
| 233 } |
| 234 } |
| 235 |
| 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); |
| 245 |
| 246 GetContextEditor().SetBoolean(kContextKeyIsRollbackAvailable, can_rollback); |
| 247 } |
| 248 |
| 249 ErrorScreen* ResetScreen::GetErrorScreen() { |
| 250 return get_base_screen_delegate()->GetErrorScreen(); |
52 } | 251 } |
53 | 252 |
54 } // namespace chromeos | 253 } // namespace chromeos |
OLD | NEW |