Upstream version 7.36.149.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 <algorithm>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/sys_info.h"
20 #include "base/values.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
23 #include "chrome/browser/chromeos/base/locale_util.h"
24 #include "chrome/browser/chromeos/idle_detector.h"
25 #include "chrome/browser/chromeos/input_method/input_method_util.h"
26 #include "chrome/browser/chromeos/login/input_events_blocker.h"
27 #include "chrome/browser/chromeos/login/login_display_host.h"
28 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
29 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
30 #include "chrome/browser/chromeos/system/input_device_settings.h"
31 #include "chrome/browser/chromeos/system/timezone_util.h"
32 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
33 #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h"
34 #include "chrome/common/pref_names.h"
35 #include "chromeos/chromeos_switches.h"
36 #include "chromeos/ime/extension_ime_util.h"
37 #include "chromeos/network/network_handler.h"
38 #include "chromeos/network/network_state_handler.h"
39 #include "chromeos/network/shill_property_util.h"
40 #include "grit/chromium_strings.h"
41 #include "grit/generated_resources.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/gfx/rect.h"
44 #include "ui/views/layout/fill_layout.h"
45 #include "ui/views/widget/widget.h"
46
47 namespace {
48
49 const char kJsScreenPath[] = "login.NetworkScreen";
50
51 // JS API callbacks names.
52 const char kJsApiNetworkOnExit[] = "networkOnExit";
53 const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged";
54 const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged";
55 const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged";
56
57 const char kUSLayout[] = "xkb:us::eng";
58
59 const int kDerelectDetectionTimeoutSeconds = 8 * 60 * 60;  // 8 hours.
60 const int kDerelectIdleTimeoutSeconds = 5 * 60;  // 5 minutes.
61 const int kOobeTimerUpdateIntervalSeconds = 5 * 60;  // 5 minutes.
62
63 // Returns true if element was inserted.
64 bool InsertString(const std::string& str, std::set<std::string>& to) {
65   const std::pair<std::set<std::string>::iterator, bool> result =
66       to.insert(str);
67   return result.second;
68 }
69
70 void AddOptgroupOtherLayouts(base::ListValue* input_methods_list) {
71   base::DictionaryValue* optgroup = new base::DictionaryValue;
72   optgroup->SetString(
73       "optionGroupName",
74       l10n_util::GetStringUTF16(IDS_OOBE_OTHER_KEYBOARD_LAYOUTS));
75   input_methods_list->Append(optgroup);
76 }
77
78 // For "UI Language" drop-down menu at OOBE screen we need to decide which
79 // entry to mark "selected". If user has just selected "requested_locale",
80 // but "loaded_locale" was actually loaded, we mark original user choice
81 // "selected" only if loaded_locale is a backup for "requested_locale".
82 std::string CalculateSelectedLanguage(const std::string& requested_locale,
83                                       const std::string& loaded_locale) {
84
85   std::string resolved_locale;
86   if (!l10n_util::CheckAndResolveLocale(requested_locale, &resolved_locale))
87     return loaded_locale;
88
89   if (resolved_locale == loaded_locale)
90     return requested_locale;
91
92   return loaded_locale;
93 }
94
95 }  // namespace
96
97 namespace chromeos {
98
99 // NetworkScreenHandler, public: -----------------------------------------------
100
101 NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor)
102     : BaseScreenHandler(kJsScreenPath),
103       screen_(NULL),
104       core_oobe_actor_(core_oobe_actor),
105       is_continue_enabled_(false),
106       show_on_init_(false),
107       should_reinitialize_language_keyboard_list_(false),
108       weak_ptr_factory_(this) {
109   DCHECK(core_oobe_actor_);
110   SetupTimeouts();
111
112   input_method::InputMethodManager* manager =
113       input_method::InputMethodManager::Get();
114   manager->AddObserver(this);
115   manager->GetComponentExtensionIMEManager()->AddObserver(this);
116 }
117
118 NetworkScreenHandler::~NetworkScreenHandler() {
119   if (screen_)
120     screen_->OnActorDestroyed(this);
121
122   input_method::InputMethodManager* manager =
123       input_method::InputMethodManager::Get();
124   manager->RemoveObserver(this);
125   manager->GetComponentExtensionIMEManager()->RemoveObserver(this);
126 }
127
128 // NetworkScreenHandler, NetworkScreenActor implementation: --------------------
129
130 void NetworkScreenHandler::SetDelegate(NetworkScreenActor::Delegate* screen) {
131   screen_ = screen;
132 }
133
134 void NetworkScreenHandler::PrepareToShow() {
135 }
136
137 void NetworkScreenHandler::Show() {
138   if (!page_is_ready()) {
139     show_on_init_ = true;
140     return;
141   }
142
143   // Here we should handle default locales, for which we do not have UI
144   // resources. This would load fallback, but properly show "selected" locale
145   // in the UI.
146   if (selected_language_code_.empty()) {
147     const StartupCustomizationDocument* startup_manifest =
148         StartupCustomizationDocument::GetInstance();
149     HandleOnLanguageChanged(startup_manifest->initial_locale_default());
150   }
151
152   PrefService* prefs = g_browser_process->local_state();
153   if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
154     if (core_oobe_actor_)
155       core_oobe_actor_->ShowDeviceResetScreen();
156     return;
157   }
158
159   // Make sure all our network technologies are turned on. On OOBE, the user
160   // should be able to select any of the available networks on the device.
161   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
162   handler->SetTechnologyEnabled(NetworkTypePattern::NonVirtual(),
163                                 true,
164                                 chromeos::network_handler::ErrorCallback());
165   ShowScreen(OobeUI::kScreenOobeNetwork, NULL);
166
167   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableDemoMode))
168     return;
169   if (base::SysInfo::IsRunningOnChromeOS()) {
170     std::string track;
171     // We're running on an actual device; if we cannot find our release track
172     // value or if the track contains "testimage", don't start demo mode.
173     if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_TRACK", &track) ||
174         track.find("testimage") != std::string::npos)
175       return;
176   }
177
178   if (IsDerelict())
179     StartIdleDetection();
180   else
181     StartOobeTimer();
182 }
183
184 void NetworkScreenHandler::Hide() {
185 }
186
187 void NetworkScreenHandler::ShowError(const base::string16& message) {
188   CallJS("showError", message);
189 }
190
191 void NetworkScreenHandler::ClearErrors() {
192   if (page_is_ready())
193     core_oobe_actor_->ClearErrors();
194 }
195
196 void NetworkScreenHandler::ShowConnectingStatus(
197     bool connecting,
198     const base::string16& network_id) {
199 }
200
201 void NetworkScreenHandler::EnableContinue(bool enabled) {
202   is_continue_enabled_ = enabled;
203   if (page_is_ready())
204     CallJS("enableContinueButton", enabled);
205 }
206
207 // NetworkScreenHandler, BaseScreenHandler implementation: --------------------
208
209 void NetworkScreenHandler::DeclareLocalizedValues(
210     LocalizedValuesBuilder* builder) {
211   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
212     builder->Add("networkScreenGreeting", IDS_REMORA_CONFIRM_MESSAGE);
213   else
214     builder->Add("networkScreenGreeting", IDS_WELCOME_SCREEN_GREETING);
215
216   builder->Add("networkScreenTitle", IDS_WELCOME_SCREEN_TITLE);
217   builder->Add("networkScreenAccessibleTitle",
218                IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE);
219   builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
220   builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
221   builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT);
222   builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION);
223   builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON);
224   builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
225 }
226
227 void NetworkScreenHandler::GetAdditionalParameters(
228     base::DictionaryValue* dict) {
229   dict->Set("languageList", GetLanguageList());
230   dict->Set("inputMethodsList", GetInputMethods());
231   dict->Set("timezoneList", GetTimezoneList());
232 }
233
234 void NetworkScreenHandler::Initialize() {
235   EnableContinue(is_continue_enabled_);
236   if (show_on_init_) {
237     show_on_init_ = false;
238     Show();
239   }
240
241   if (should_reinitialize_language_keyboard_list_) {
242     should_reinitialize_language_keyboard_list_ = false;
243     ReloadLocalizedContent();
244   }
245
246   timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver(
247       kSystemTimezone,
248       base::Bind(&NetworkScreenHandler::OnSystemTimezoneChanged,
249                  base::Unretained(this)));
250   OnSystemTimezoneChanged();
251 }
252
253 // NetworkScreenHandler, WebUIMessageHandler implementation: -------------------
254
255 void NetworkScreenHandler::RegisterMessages() {
256   AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit);
257   AddCallback(kJsApiNetworkOnLanguageChanged,
258               &NetworkScreenHandler::HandleOnLanguageChanged);
259   AddCallback(kJsApiNetworkOnInputMethodChanged,
260               &NetworkScreenHandler::HandleOnInputMethodChanged);
261   AddCallback(kJsApiNetworkOnTimezoneChanged,
262               &NetworkScreenHandler::HandleOnTimezoneChanged);
263 }
264
265
266 // static
267 void NetworkScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
268   registry->RegisterInt64Pref(prefs::kTimeOnOobe, 0);
269 }
270
271 // NetworkScreenHandler, private: ----------------------------------------------
272
273 void NetworkScreenHandler::HandleOnExit() {
274   idle_detector_.reset();
275   ClearErrors();
276   if (screen_)
277     screen_->OnContinuePressed();
278 }
279
280 struct NetworkScreenHandlerOnLanguageChangedCallbackData {
281   explicit NetworkScreenHandlerOnLanguageChangedCallbackData(
282       base::WeakPtr<NetworkScreenHandler>& handler)
283       : handler_(handler) {}
284
285   base::WeakPtr<NetworkScreenHandler> handler_;
286
287   // Block UI while resource bundle is being reloaded.
288   chromeos::InputEventsBlocker input_events_blocker;
289 };
290
291 // static
292 void NetworkScreenHandler::OnLanguageChangedCallback(
293     scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context,
294     const std::string& requested_locale,
295     const std::string& loaded_locale,
296     const bool success) {
297   if (!context or !context->handler_)
298     return;
299
300   NetworkScreenHandler* const self = context->handler_.get();
301
302   if (success) {
303     if (requested_locale == loaded_locale) {
304       self->selected_language_code_ = requested_locale;
305     } else {
306       self->selected_language_code_ =
307           CalculateSelectedLanguage(requested_locale, loaded_locale);
308     }
309   } else {
310     self->selected_language_code_ = loaded_locale;
311   }
312
313   self->ReloadLocalizedContent();
314
315   AccessibilityManager::Get()->OnLocaleChanged();
316 }
317
318 void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) {
319   const std::string app_locale = g_browser_process->GetApplicationLocale();
320   if (app_locale == locale)
321     return;
322
323   base::WeakPtr<NetworkScreenHandler> weak_self =
324       weak_ptr_factory_.GetWeakPtr();
325   scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data(
326       new NetworkScreenHandlerOnLanguageChangedCallbackData(weak_self));
327   scoped_ptr<locale_util::SwitchLanguageCallback> callback(
328       new locale_util::SwitchLanguageCallback(
329           base::Bind(&NetworkScreenHandler::OnLanguageChangedCallback,
330                      base::Passed(callback_data.Pass()))));
331   locale_util::SwitchLanguage(locale,
332                               true /* enableLocaleKeyboardLayouts */,
333                               true /* login_layouts_only */,
334                               callback.Pass());
335 }
336
337 void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) {
338   input_method::InputMethodManager::Get()->ChangeInputMethod(id);
339 }
340
341 void NetworkScreenHandler::HandleOnTimezoneChanged(
342     const std::string& timezone_id) {
343   std::string current_timezone_id;
344   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
345   if (current_timezone_id == timezone_id)
346     return;
347
348   CrosSettings::Get()->SetString(kSystemTimezone, timezone_id);
349 }
350
351 void NetworkScreenHandler::OnSystemTimezoneChanged() {
352   std::string current_timezone_id;
353   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
354   CallJS("setTimezone", current_timezone_id);
355 }
356
357 void NetworkScreenHandler::StartIdleDetection() {
358   if (!idle_detector_.get()) {
359     idle_detector_.reset(
360         new IdleDetector(base::Closure(),
361                          base::Bind(&NetworkScreenHandler::OnIdle,
362                                     weak_ptr_factory_.GetWeakPtr())));
363   }
364   idle_detector_->Start(derelict_idle_timeout_);
365 }
366
367 void NetworkScreenHandler::StartOobeTimer() {
368   oobe_timer_.Start(FROM_HERE,
369                     oobe_timer_update_interval_,
370                     this,
371                     &NetworkScreenHandler::OnOobeTimerUpdate);
372 }
373
374 void NetworkScreenHandler::OnIdle() {
375   LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
376   host->StartDemoAppLaunch();
377 }
378
379 void NetworkScreenHandler::OnOobeTimerUpdate() {
380   time_on_oobe_ += oobe_timer_update_interval_;
381
382   PrefService* prefs = g_browser_process->local_state();
383   prefs->SetInt64(prefs::kTimeOnOobe, time_on_oobe_.InSeconds());
384
385   if (IsDerelict()) {
386     oobe_timer_.Stop();
387     StartIdleDetection();
388   }
389 }
390
391 void NetworkScreenHandler::SetupTimeouts() {
392   CommandLine* cmdline = CommandLine::ForCurrentProcess();
393   DCHECK(cmdline);
394
395   PrefService* prefs = g_browser_process->local_state();
396   time_on_oobe_ =
397       base::TimeDelta::FromSeconds(prefs->GetInt64(prefs::kTimeOnOobe));
398
399   int derelict_detection_timeout;
400   if (!cmdline->HasSwitch(switches::kDerelictDetectionTimeout) ||
401       !base::StringToInt(
402           cmdline->GetSwitchValueASCII(switches::kDerelictDetectionTimeout),
403           &derelict_detection_timeout)) {
404     derelict_detection_timeout = kDerelectDetectionTimeoutSeconds;
405   }
406   derelict_detection_timeout_ =
407       base::TimeDelta::FromSeconds(derelict_detection_timeout);
408
409   int derelict_idle_timeout;
410   if (!cmdline->HasSwitch(switches::kDerelictIdleTimeout) ||
411       !base::StringToInt(
412           cmdline->GetSwitchValueASCII(switches::kDerelictIdleTimeout),
413           &derelict_idle_timeout)) {
414     derelict_idle_timeout = kDerelectIdleTimeoutSeconds;
415   }
416   derelict_idle_timeout_ = base::TimeDelta::FromSeconds(derelict_idle_timeout);
417
418
419   int oobe_timer_update_interval;
420   if (!cmdline->HasSwitch(switches::kOobeTimerInterval) ||
421       !base::StringToInt(
422           cmdline->GetSwitchValueASCII(switches::kOobeTimerInterval),
423           &oobe_timer_update_interval)) {
424     oobe_timer_update_interval = kOobeTimerUpdateIntervalSeconds;
425   }
426   oobe_timer_update_interval_ =
427       base::TimeDelta::FromSeconds(oobe_timer_update_interval);
428
429   // In case we'd be derelict before our timer is set to trigger, reduce
430   // the interval so we check again when we're scheduled to go derelict.
431   oobe_timer_update_interval_ =
432       std::max(std::min(oobe_timer_update_interval_,
433                         derelict_detection_timeout_ - time_on_oobe_),
434                base::TimeDelta::FromSeconds(0));
435 }
436
437 bool NetworkScreenHandler::IsDerelict() {
438   return time_on_oobe_ >= derelict_detection_timeout_;
439 }
440
441 base::ListValue* NetworkScreenHandler::GetLanguageList() {
442   const std::string app_locale = g_browser_process->GetApplicationLocale();
443   input_method::InputMethodManager* manager =
444       input_method::InputMethodManager::Get();
445   ComponentExtensionIMEManager* comp_manager =
446       manager->GetComponentExtensionIMEManager();
447   input_method::InputMethodDescriptors descriptors;
448   if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) {
449     if (comp_manager->IsInitialized())
450       descriptors = comp_manager->GetXkbIMEAsInputMethodDescriptor();
451   } else {
452     descriptors = *(manager->GetSupportedInputMethods());
453   }
454   base::ListValue* languages_list =
455       options::CrosLanguageOptionsHandler::GetUILanguageList(descriptors);
456   for (size_t i = 0; i < languages_list->GetSize(); ++i) {
457     base::DictionaryValue* language_info = NULL;
458     if (!languages_list->GetDictionary(i, &language_info))
459       NOTREACHED();
460
461     std::string value;
462     language_info->GetString("code", &value);
463     std::string display_name;
464     language_info->GetString("displayName", &display_name);
465     std::string native_name;
466     language_info->GetString("nativeDisplayName", &native_name);
467
468     // If it's option group divider, add field name.
469     if (value == options::kVendorOtherLanguagesListDivider) {
470       language_info->SetString(
471           "optionGroupName",
472           l10n_util::GetStringUTF16(IDS_OOBE_OTHER_LANGUAGES));
473     }
474     if (display_name != native_name) {
475       display_name = base::StringPrintf("%s - %s",
476                                         display_name.c_str(),
477                                         native_name.c_str());
478     }
479
480     language_info->SetString("value", value);
481     language_info->SetString("title", display_name);
482     if (selected_language_code_.empty()) {
483       if (value == app_locale)
484         language_info->SetBoolean("selected", true);
485     } else {
486       if (value == selected_language_code_)
487         language_info->SetBoolean("selected", true);
488     }
489   }
490   return languages_list;
491 }
492
493 base::DictionaryValue* CreateInputMethodsEntry(
494     const input_method::InputMethodDescriptor& method,
495     const std::string current_input_method_id) {
496   input_method::InputMethodUtil* util =
497       input_method::InputMethodManager::Get()->GetInputMethodUtil();
498   const std::string& ime_id = method.id();
499   scoped_ptr<base::DictionaryValue> input_method(new base::DictionaryValue);
500   input_method->SetString("value", ime_id);
501   input_method->SetString("title", util->GetInputMethodLongName(method));
502   input_method->SetBoolean("selected", ime_id == current_input_method_id);
503   return input_method.release();
504 }
505
506 void NetworkScreenHandler::OnImeComponentExtensionInitialized() {
507   // Refreshes the language and keyboard list once the component extension
508   // IMEs are initialized.
509   if (page_is_ready())
510     ReloadLocalizedContent();
511   else
512     should_reinitialize_language_keyboard_list_ = true;
513 }
514
515 void NetworkScreenHandler::InputMethodChanged(
516     input_method::InputMethodManager* manager, bool show_message) {
517   CallJS("setInputMethod", manager->GetCurrentInputMethod().id());
518 }
519
520 void NetworkScreenHandler::ReloadLocalizedContent() {
521   base::DictionaryValue localized_strings;
522   static_cast<OobeUI*>(web_ui()->GetController())
523       ->GetLocalizedStrings(&localized_strings);
524   core_oobe_actor_->ReloadContent(localized_strings);
525
526   // Buttons are recreated, updated "Continue" button state.
527   EnableContinue(is_continue_enabled_);
528 }
529
530 // static
531 base::ListValue* NetworkScreenHandler::GetInputMethods() {
532   base::ListValue* input_methods_list = new base::ListValue;
533   input_method::InputMethodManager* manager =
534       input_method::InputMethodManager::Get();
535   input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
536   if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) {
537     ComponentExtensionIMEManager* comp_manager =
538         manager->GetComponentExtensionIMEManager();
539     if (!comp_manager->IsInitialized()) {
540       input_method::InputMethodDescriptor fallback =
541           util->GetFallbackInputMethodDescriptor();
542       input_methods_list->Append(
543           CreateInputMethodsEntry(fallback, fallback.id()));
544       return input_methods_list;
545     }
546   }
547
548   const std::vector<std::string>& hardware_login_input_methods =
549       util->GetHardwareLoginInputMethodIds();
550   manager->EnableLoginLayouts(g_browser_process->GetApplicationLocale(),
551                               hardware_login_input_methods);
552
553   scoped_ptr<input_method::InputMethodDescriptors> input_methods(
554       manager->GetActiveInputMethods());
555   const std::string& current_input_method_id =
556       manager->GetCurrentInputMethod().id();
557   std::set<std::string> input_methods_added;
558
559   for (std::vector<std::string>::const_iterator i =
560            hardware_login_input_methods.begin();
561        i != hardware_login_input_methods.end();
562        ++i) {
563     const input_method::InputMethodDescriptor* ime =
564         util->GetInputMethodDescriptorFromId(*i);
565     DCHECK(ime != NULL);
566     // Do not crash in case of misconfiguration.
567     if (ime != NULL) {
568       input_methods_added.insert(*i);
569       input_methods_list->Append(
570           CreateInputMethodsEntry(*ime, current_input_method_id));
571     }
572   }
573
574   bool optgroup_added = false;
575   for (size_t i = 0; i < input_methods->size(); ++i) {
576     // Makes sure the id is in legacy xkb id format.
577     const std::string& ime_id = (*input_methods)[i].id();
578     if (!InsertString(ime_id, input_methods_added))
579       continue;
580     if (!optgroup_added) {
581       optgroup_added = true;
582       AddOptgroupOtherLayouts(input_methods_list);
583     }
584     input_methods_list->Append(
585         CreateInputMethodsEntry((*input_methods)[i], current_input_method_id));
586   }
587   // "xkb:us::eng" should always be in the list of available layouts.
588   const std::string& us_keyboard_id =
589       extension_ime_util::GetInputMethodIDByKeyboardLayout(kUSLayout);
590   if (input_methods_added.find(us_keyboard_id) == input_methods_added.end()) {
591     const input_method::InputMethodDescriptor* us_eng_descriptor =
592         util->GetInputMethodDescriptorFromId(us_keyboard_id);
593     DCHECK(us_eng_descriptor != NULL);
594     if (!optgroup_added) {
595       optgroup_added = true;
596       AddOptgroupOtherLayouts(input_methods_list);
597     }
598     input_methods_list->Append(
599         CreateInputMethodsEntry(*us_eng_descriptor, current_input_method_id));
600   }
601   return input_methods_list;
602 }
603
604 // static
605 base::ListValue* NetworkScreenHandler::GetTimezoneList() {
606   std::string current_timezone_id;
607   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
608
609   scoped_ptr<base::ListValue> timezone_list(new base::ListValue);
610   scoped_ptr<base::ListValue> timezones = system::GetTimezoneList().Pass();
611   for (size_t i = 0; i < timezones->GetSize(); ++i) {
612     const base::ListValue* timezone = NULL;
613     CHECK(timezones->GetList(i, &timezone));
614
615     std::string timezone_id;
616     CHECK(timezone->GetString(0, &timezone_id));
617
618     std::string timezone_name;
619     CHECK(timezone->GetString(1, &timezone_name));
620
621     scoped_ptr<base::DictionaryValue> timezone_option(
622         new base::DictionaryValue);
623     timezone_option->SetString("value", timezone_id);
624     timezone_option->SetString("title", timezone_name);
625     timezone_option->SetBoolean("selected", timezone_id == current_timezone_id);
626     timezone_list->Append(timezone_option.release());
627   }
628
629   return timezone_list.release();
630 }
631
632 }  // namespace chromeos