Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / network_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/network_screen_handler.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
15 #include "chrome/browser/chromeos/base/locale_util.h"
16 #include "chrome/browser/chromeos/customization_document.h"
17 #include "chrome/browser/chromeos/idle_detector.h"
18 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
19 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
20 #include "chrome/browser/chromeos/system/input_device_settings.h"
21 #include "chrome/browser/chromeos/system/timezone_util.h"
22 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
23 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
24 #include "chrome/common/pref_names.h"
25 #include "chromeos/ime/extension_ime_util.h"
26 #include "chromeos/network/network_handler.h"
27 #include "chromeos/network/network_state_handler.h"
28 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/gfx/rect.h"
32 #include "ui/views/layout/fill_layout.h"
33 #include "ui/views/widget/widget.h"
34
35 namespace {
36
37 const char kJsScreenPath[] = "login.NetworkScreen";
38
39 // JS API callbacks names.
40 const char kJsApiNetworkOnExit[] = "networkOnExit";
41 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged";
42 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged";
43 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged";
44
45 // For "UI Language" drop-down menu at OOBE screen we need to decide which
46 // entry to mark "selected". If user has just selected "requested_locale",
47 // but "loaded_locale" was actually loaded, we mark original user choice
48 // "selected" only if loaded_locale is a backup for "requested_locale".
49 std::string CalculateSelectedLanguage(const std::string& requested_locale,
50                                       const std::string& loaded_locale) {
51
52   std::string resolved_locale;
53   if (!l10n_util::CheckAndResolveLocale(requested_locale, &resolved_locale))
54     return loaded_locale;
55
56   if (resolved_locale == loaded_locale)
57     return requested_locale;
58
59   return loaded_locale;
60 }
61
62 }  // namespace
63
64 namespace chromeos {
65
66 // NetworkScreenHandler, public: -----------------------------------------------
67
68 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor)
69     : BaseScreenHandler(kJsScreenPath),
70       screen_(NULL),
71       core_oobe_actor_(core_oobe_actor),
72       is_continue_enabled_(false),
73       show_on_init_(false),
74       weak_ptr_factory_(this) {
75   DCHECK(core_oobe_actor_);
76
77   input_method::InputMethodManager* manager =
78       input_method::InputMethodManager::Get();
79   manager->AddObserver(this);
80 }
81
82 NetworkScreenHandler::~NetworkScreenHandler() {
83   if (screen_)
84     screen_->OnActorDestroyed(this);
85
86   input_method::InputMethodManager* manager =
87       input_method::InputMethodManager::Get();
88   manager->RemoveObserver(this);
89 }
90
91 // NetworkScreenHandler, NetworkScreenActor implementation: --------------------
92
93 void NetworkScreenHandler::SetDelegate(NetworkScreenActor::Delegate* screen) {
94   screen_ = screen;
95 }
96
97 void NetworkScreenHandler::PrepareToShow() {
98 }
99
100 void NetworkScreenHandler::Show() {
101   if (!page_is_ready()) {
102     show_on_init_ = true;
103     return;
104   }
105
106   // Here we should handle default locales, for which we do not have UI
107   // resources. This would load fallback, but properly show "selected" locale
108   // in the UI.
109   if (selected_language_code_.empty()) {
110     const StartupCustomizationDocument* startup_manifest =
111         StartupCustomizationDocument::GetInstance();
112     HandleOnLanguageChanged(startup_manifest->initial_locale_default());
113   }
114
115   PrefService* prefs = g_browser_process->local_state();
116   if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
117     if (core_oobe_actor_)
118       core_oobe_actor_->ShowDeviceResetScreen();
119     return;
120   }
121
122   // Make sure all our network technologies are turned on. On OOBE, the user
123   // should be able to select any of the available networks on the device.
124   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
125   handler->SetTechnologyEnabled(NetworkTypePattern::NonVirtual(),
126                                 true,
127                                 chromeos::network_handler::ErrorCallback());
128   ShowScreen(OobeUI::kScreenOobeNetwork, NULL);
129   core_oobe_actor_->InitDemoModeDetection();
130 }
131
132 void NetworkScreenHandler::Hide() {
133 }
134
135 void NetworkScreenHandler::ShowError(const base::string16& message) {
136   CallJS("showError", message);
137 }
138
139 void NetworkScreenHandler::ClearErrors() {
140   if (page_is_ready())
141     core_oobe_actor_->ClearErrors();
142 }
143
144 void NetworkScreenHandler::ShowConnectingStatus(
145     bool connecting,
146     const base::string16& network_id) {
147 }
148
149 void NetworkScreenHandler::EnableContinue(bool enabled) {
150   is_continue_enabled_ = enabled;
151   if (page_is_ready())
152     CallJS("enableContinueButton", enabled);
153 }
154
155 // NetworkScreenHandler, BaseScreenHandler implementation: --------------------
156
157 void NetworkScreenHandler::DeclareLocalizedValues(
158     LocalizedValuesBuilder* builder) {
159   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
160     builder->Add("networkScreenGreeting", IDS_REMORA_CONFIRM_MESSAGE);
161   else
162     builder->Add("networkScreenGreeting", IDS_WELCOME_SCREEN_GREETING);
163
164   builder->Add("networkScreenTitle", IDS_WELCOME_SCREEN_TITLE);
165   builder->Add("networkScreenAccessibleTitle",
166                IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE);
167   builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
168   builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
169   builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT);
170   builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION);
171   builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON);
172   builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
173 }
174
175 void NetworkScreenHandler::GetAdditionalParameters(
176     base::DictionaryValue* dict) {
177   const std::string application_locale =
178       g_browser_process->GetApplicationLocale();
179   const std::string selected_language = selected_language_code_.empty() ?
180       application_locale : selected_language_code_;
181   const std::string selected_input_method =
182       input_method::InputMethodManager::Get()->GetCurrentInputMethod().id();
183
184   dict->Set("languageList",
185             GetUILanguageList(NULL, selected_language).release());
186   dict->Set("inputMethodsList",
187             GetLoginKeyboardLayouts(application_locale,
188                                     selected_input_method).release());
189   dict->Set("timezoneList", GetTimezoneList());
190 }
191
192 void NetworkScreenHandler::Initialize() {
193   EnableContinue(is_continue_enabled_);
194   if (show_on_init_) {
195     show_on_init_ = false;
196     Show();
197   }
198
199   timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver(
200       kSystemTimezone,
201       base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged,
202                  base::Unretained(this)));
203   OnSystemTimezoneChanged();
204 }
205
206 // NetworkScreenHandler, WebUIMessageHandler implementation: -------------------
207
208 void NetworkScreenHandler::RegisterMessages() {
209   AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit);
210   AddCallback(kJsApiNetworkOnLanguageChanged,
211               &NetworkScreenHandler::HandleOnLanguageChanged);
212   AddCallback(kJsApiNetworkOnInputMethodChanged,
213               &NetworkScreenHandler::HandleOnInputMethodChanged);
214   AddCallback(kJsApiNetworkOnTimezoneChanged,
215               &NetworkScreenHandler::HandleOnTimezoneChanged);
216 }
217
218
219 // NetworkScreenHandler, private: ----------------------------------------------
220
221 void NetworkScreenHandler::HandleOnExit() {
222   core_oobe_actor_->StopDemoModeDetection();
223   ClearErrors();
224   if (screen_)
225     screen_->OnContinuePressed();
226 }
227
228 struct NetworkScreenHandlerOnLanguageChangedCallbackData {
229   explicit NetworkScreenHandlerOnLanguageChangedCallbackData(
230       base::WeakPtr<NetworkScreenHandler>& handler)
231       : handler_(handler) {}
232
233   base::WeakPtr<NetworkScreenHandler> handler_;
234
235   // Block UI while resource bundle is being reloaded.
236   chromeos::InputEventsBlocker input_events_blocker;
237 };
238
239 // static
240 void NetworkScreenHandler::OnLanguageChangedCallback(
241     scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context,
242     const std::string& requested_locale,
243     const std::string& loaded_locale,
244     const bool success) {
245   if (!context or !context->handler_)
246     return;
247
248   NetworkScreenHandler* const self = context->handler_.get();
249
250   if (success) {
251     if (requested_locale == loaded_locale) {
252       self->selected_language_code_ = requested_locale;
253     } else {
254       self->selected_language_code_ =
255           CalculateSelectedLanguage(requested_locale, loaded_locale);
256     }
257   } else {
258     self->selected_language_code_ = loaded_locale;
259   }
260
261   self->ReloadLocalizedContent();
262
263   // We still do not have device owner, so owner settings are not applied.
264   // But Guest session can be started before owner is created, so we need to
265   // save locale settings directly here.
266   g_browser_process->local_state()->SetString(prefs::kApplicationLocale,
267                                               self->selected_language_code_);
268
269   AccessibilityManager::Get()->OnLocaleChanged();
270 }
271
272 void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) {
273   const std::string app_locale = g_browser_process->GetApplicationLocale();
274   if (app_locale == locale)
275     return;
276
277   base::WeakPtr<NetworkScreenHandler> weak_self =
278       weak_ptr_factory_.GetWeakPtr();
279   scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data(
280       new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self));
281   scoped_ptr<locale_util::SwitchLanguageCallback> callback(
282       new locale_util::SwitchLanguageCallback(
283           base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback,
284                      base::Passed(callback_data.Pass()))));
285   locale_util::SwitchLanguage(locale,
286                               true /* enableLocaleKeyboardLayouts */,
287                               true /* login_layouts_only */,
288                               callback.Pass());
289 }
290
291 void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) {
292   input_method::InputMethodManager::Get()->ChangeInputMethod(id);
293 }
294
295 void NetworkScreenHandler::HandleOnTimezoneChanged(
296     const std::string& timezone_id) {
297   std::string current_timezone_id;
298   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
299   if (current_timezone_id == timezone_id)
300     return;
301
302   CrosSettings::Get()->SetString(kSystemTimezone, timezone_id);
303 }
304
305 void NetworkScreenHandler::OnSystemTimezoneChanged() {
306   std::string current_timezone_id;
307   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
308   CallJS("setTimezone", current_timezone_id);
309 }
310
311 void NetworkScreenHandler::InputMethodChanged(
312     input_method::InputMethodManager* manager, bool show_message) {
313   CallJS("setInputMethod", manager->GetCurrentInputMethod().id());
314 }
315
316 void NetworkScreenHandler::ReloadLocalizedContent() {
317   base::DictionaryValue localized_strings;
318   static_cast<OobeUI*>(web_ui()->GetController())
319       ->GetLocalizedStrings(&localized_strings);
320   core_oobe_actor_->ReloadContent(localized_strings);
321
322   // Buttons are recreated, updated "Continue" button state.
323   EnableContinue(is_continue_enabled_);
324 }
325
326 // static
327 base::ListValue* NetworkScreenHandler::GetTimezoneList() {
328   std::string current_timezone_id;
329   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
330
331   scoped_ptr<base::ListValue> timezone_list(new base::ListValue);
332   scoped_ptr<base::ListValue> timezones = system::GetTimezoneList().Pass();
333   for (size_t i = 0; i < timezones->GetSize(); ++i) {
334     const base::ListValue* timezone = NULL;
335     CHECK(timezones->GetList(i, &timezone));
336
337     std::string timezone_id;
338     CHECK(timezone->GetString(0, &timezone_id));
339
340     std::string timezone_name;
341     CHECK(timezone->GetString(1, &timezone_name));
342
343     scoped_ptr<base::DictionaryValue> timezone_option(
344         new base::DictionaryValue);
345     timezone_option->SetString("value", timezone_id);
346     timezone_option->SetString("title", timezone_name);
347     timezone_option->SetBoolean("selected", timezone_id == current_timezone_id);
348     timezone_list->Append(timezone_option.release());
349   }
350
351   return timezone_list.release();
352 }
353
354 }  // namespace chromeos