Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / reset_screen_handler.cc
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.
4
5 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/files/file_path.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_registry_simple.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/login/help_app_launcher.h"
22 #include "chrome/browser/chromeos/reset/metrics.h"
23 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
24 #include "chrome/common/pref_names.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/dbus/power_manager_client.h"
28 #include "chromeos/dbus/session_manager_client.h"
29 #include "chromeos/dbus/update_engine_client.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "grit/browser_resources.h"
32 #include "grit/chromium_strings.h"
33 #include "grit/generated_resources.h"
34 #include "ui/base/l10n/l10n_util.h"
35
36 namespace {
37
38 const char kJsScreenPath[] = "login.ResetScreen";
39
40 // Reset screen id.
41 const char kResetScreen[] = "reset";
42
43 const int kErrorUIStateRollback = 7;
44
45 static const char kRollbackFlagFile[] = "/tmp/.enable_rollback_ui";
46
47 void CheckRollbackFlagFileExists(bool *file_exists) {
48   DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
49   *file_exists = base::PathExists(base::FilePath(kRollbackFlagFile));
50 }
51
52 }  // namespace
53
54 namespace chromeos {
55
56 ResetScreenHandler::ResetScreenHandler()
57     : BaseScreenHandler(kJsScreenPath),
58       delegate_(NULL),
59       show_on_init_(false),
60       restart_required_(true),
61       reboot_was_requested_(false),
62       rollback_available_(false),
63       preparing_for_rollback_(false),
64       weak_ptr_factory_(this) {
65 }
66
67 ResetScreenHandler::~ResetScreenHandler() {
68   if (delegate_)
69     delegate_->OnActorDestroyed(this);
70   DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
71 }
72
73 void ResetScreenHandler::PrepareToShow() {
74 }
75
76 void ResetScreenHandler::ShowWithParams() {
77   int dialog_type;
78   if (reboot_was_requested_) {
79     dialog_type = rollback_available_ ?
80         reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK :
81         reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY;
82   } else {
83     dialog_type = rollback_available_ ?
84       reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE :
85       reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE;
86   }
87   UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown",
88                             dialog_type,
89                             reset::DIALOG_VIEW_TYPE_SIZE);
90
91   base::DictionaryValue reset_screen_params;
92   reset_screen_params.SetBoolean("showRestartMsg", restart_required_);
93   reset_screen_params.SetBoolean(
94       "showRollbackOption", rollback_available_ && !reboot_was_requested_);
95   reset_screen_params.SetBoolean(
96       "simpleConfirm", reboot_was_requested_ && !rollback_available_);
97   reset_screen_params.SetBoolean(
98       "rollbackConfirm", reboot_was_requested_ && rollback_available_);
99
100   PrefService* prefs = g_browser_process->local_state();
101   prefs->SetBoolean(prefs::kFactoryResetRequested, false);
102   prefs->SetBoolean(prefs::kRollbackRequested, false);
103   prefs->CommitPendingWrite();
104   ShowScreen(kResetScreen, &reset_screen_params);
105 }
106
107 void ResetScreenHandler::Show() {
108   if (!page_is_ready()) {
109     show_on_init_ = true;
110     return;
111   }
112
113   ChooseAndApplyShowScenario();
114 }
115
116 void ResetScreenHandler::ChooseAndApplyShowScenario() {
117   PrefService* prefs = g_browser_process->local_state();
118   restart_required_ = !CommandLine::ForCurrentProcess()->HasSwitch(
119       switches::kFirstExecAfterBoot);
120   reboot_was_requested_ = false;
121   rollback_available_ = false;
122   preparing_for_rollback_ = false;
123   if (!restart_required_)  // First exec after boot.
124     reboot_was_requested_ = prefs->GetBoolean(prefs::kFactoryResetRequested);
125
126   // Check Rollback flag-file.
127   scoped_ptr<bool> file_exists(new bool(false));
128   base::Closure checkfile_closure = base::Bind(
129       &CheckRollbackFlagFileExists,
130       base::Unretained(file_exists.get()));
131   base::Closure on_check_done = base::Bind(
132       &ResetScreenHandler::OnRollbackFlagFileCheckDone,
133       weak_ptr_factory_.GetWeakPtr(),
134       base::Passed(file_exists.Pass()));
135   if (!content::BrowserThread::PostBlockingPoolTaskAndReply(
136           FROM_HERE,
137           checkfile_closure,
138           on_check_done)) {
139     LOG(WARNING) << "Failed to check flag file for Rollback reset option";
140     on_check_done.Run();
141   }
142 }
143
144 void ResetScreenHandler::OnRollbackFlagFileCheckDone(
145     scoped_ptr<bool> file_exists) {
146   if (!(*file_exists) && !CommandLine::ForCurrentProcess()->HasSwitch(
147           switches::kEnableRollbackOption)) {
148     rollback_available_ = false;
149     ShowWithParams();
150   } else if (!restart_required_ && reboot_was_requested_) {
151     // First exec after boot.
152     PrefService* prefs = g_browser_process->local_state();
153     rollback_available_ = prefs->GetBoolean(prefs::kRollbackRequested);
154     ShowWithParams();
155   } else {
156     chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
157         CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck,
158         weak_ptr_factory_.GetWeakPtr()));
159   }
160 }
161
162 void ResetScreenHandler::Hide() {
163   DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
164 }
165
166 void ResetScreenHandler::SetDelegate(Delegate* delegate) {
167   delegate_ = delegate;
168   if (page_is_ready())
169     Initialize();
170 }
171
172 void ResetScreenHandler::DeclareLocalizedValues(
173     LocalizedValuesBuilder* builder) {
174   builder->Add("resetScreenTitle", IDS_RESET_SCREEN_TITLE);
175   builder->Add("resetScreenAccessibleTitle", IDS_RESET_SCREEN_TITLE);
176   builder->Add("resetScreenIconTitle",IDS_RESET_SCREEN_ICON_TITLE);
177   builder->Add("cancelButton", IDS_CANCEL);
178
179   builder->Add("resetWarningDataDetails",
180                IDS_RESET_SCREEN_WARNING_DETAILS_DATA);
181   builder->Add("resetRestartMessage", IDS_RESET_SCREEN_RESTART_MSG);
182   builder->AddF("resetRollbackOption",
183                 IDS_RESET_SCREEN_ROLLBACK_OPTION,
184                 IDS_SHORT_PRODUCT_NAME);
185   builder->AddF("resetRevertPromise",
186                 IDS_RESET_SCREEN_PREPARING_REVERT_PROMISE,
187                 IDS_SHORT_PRODUCT_NAME);
188   builder->AddF("resetRevertSpinnerMessage",
189                 IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE,
190                 IDS_SHORT_PRODUCT_NAME);
191
192   // Different variants of the same UI elements for all dialog cases.
193   builder->Add("resetButtonReset", IDS_RESET_SCREEN_RESET);
194   builder->Add("resetButtonRelaunch", IDS_RELAUNCH_BUTTON);
195   builder->Add("resetButtonPowerwash", IDS_RESET_SCREEN_POWERWASH);
196
197   builder->AddF(
198       "resetAndRollbackWarningTextConfirmational",
199       IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_AND_ROLLBACK_MSG,
200       IDS_SHORT_PRODUCT_NAME);
201   builder->AddF("resetWarningTextConfirmational",
202                 IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_MSG,
203                 IDS_SHORT_PRODUCT_NAME);
204   builder->AddF("resetWarningTextInitial",
205                 IDS_RESET_SCREEN_WARNING_MSG,
206                 IDS_SHORT_PRODUCT_NAME);
207
208   builder->AddF(
209       "resetAndRollbackWarningDetailsConfirmational",
210       IDS_RESET_SCREEN_CONFIRMATION_WARNING_ROLLBACK_DETAILS,
211       IDS_SHORT_PRODUCT_NAME);
212   builder->AddF("resetWarningDetailsConfirmational",
213                 IDS_RESET_SCREEN_CONFIRMATION_WARNING_DETAILS,
214                 IDS_SHORT_PRODUCT_NAME);
215   builder->AddF("resetWarningDetailsInitial",
216                 IDS_RESET_SCREEN_WARNING_DETAILS,
217                 IDS_SHORT_PRODUCT_NAME);
218 }
219
220 // Invoked from call to CanRollbackCheck upon completion of the DBus call.
221 void ResetScreenHandler::OnRollbackCheck(bool can_rollback) {
222   VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback;
223   rollback_available_ = can_rollback;
224   ShowWithParams();
225 }
226
227 // static
228 void ResetScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
229   registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
230   registry->RegisterBooleanPref(prefs::kRollbackRequested, false);
231 }
232
233 void ResetScreenHandler::Initialize() {
234   if (!page_is_ready() || !delegate_)
235     return;
236
237   if (show_on_init_) {
238     Show();
239     show_on_init_ = false;
240   }
241 }
242
243 void ResetScreenHandler::RegisterMessages() {
244   AddCallback("cancelOnReset", &ResetScreenHandler::HandleOnCancel);
245   AddCallback("restartOnReset", &ResetScreenHandler::HandleOnRestart);
246   AddCallback("powerwashOnReset", &ResetScreenHandler::HandleOnPowerwash);
247   AddCallback("resetOnLearnMore", &ResetScreenHandler::HandleOnLearnMore);
248 }
249
250 void ResetScreenHandler::HandleOnCancel() {
251   if (preparing_for_rollback_)
252     return;
253   if (delegate_)
254     delegate_->OnExit();
255   DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
256 }
257
258 void ResetScreenHandler::HandleOnRestart(bool should_rollback) {
259   PrefService* prefs = g_browser_process->local_state();
260   prefs->SetBoolean(prefs::kFactoryResetRequested, true);
261   prefs->SetBoolean(prefs::kRollbackRequested, should_rollback);
262   prefs->CommitPendingWrite();
263
264   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
265 }
266
267 void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) {
268   if (rollback_available_ && (rollback_checked || reboot_was_requested_)) {
269       preparing_for_rollback_ = true;
270       CallJS("updateViewOnRollbackCall");
271       DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
272       chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
273   } else {
274     if (rollback_checked && !rollback_available_) {
275       NOTREACHED() <<
276           "Rollback was checked but not available. Starting powerwash.";
277     }
278     chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
279         StartDeviceWipe();
280   }
281 }
282
283 void ResetScreenHandler::HandleOnLearnMore() {
284   if (!help_app_.get())
285     help_app_ = new HelpAppLauncher(GetNativeWindow());
286   help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
287 }
288
289 void ResetScreenHandler::UpdateStatusChanged(
290     const UpdateEngineClient::Status& status) {
291   VLOG(1) << "Update status change to " << status.status;
292   if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR ||
293       status.status ==
294           UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) {
295     preparing_for_rollback_ = false;
296     // Show error screen.
297     base::DictionaryValue params;
298     params.SetInteger("uiState", kErrorUIStateRollback);
299     ShowScreen(OobeUI::kScreenErrorMessage, &params);
300   } else if (status.status ==
301       UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
302     DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
303   }
304 }
305
306 }  // namespace chromeos