Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / chromeos / core_chromeos_options_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/options/chromeos/core_chromeos_options_handler.h"
6
7 #include <string>
8
9 #include "ash/session_state_delegate.h"
10 #include "ash/shell.h"
11 #include "base/bind.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/sys_info.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chromeos/login/user_manager.h"
19 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
22 #include "chrome/browser/chromeos/settings/cros_settings.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h"
25 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
26 #include "chrome/common/pref_names.h"
27 #include "content/public/browser/user_metrics.h"
28 #include "content/public/browser/web_ui.h"
29 #include "grit/generated_resources.h"
30 #include "ui/base/l10n/l10n_util.h"
31
32 namespace chromeos {
33 namespace options {
34
35 namespace {
36
37 // List of settings that should be changeable by all users.
38 const char* kNonOwnerSettings[] = {
39     kSystemTimezone
40 };
41
42 // Returns true if |pref| should be only available to the owner.
43 bool IsSettingOwnerOnly(const std::string& pref) {
44   const char** end = kNonOwnerSettings + arraysize(kNonOwnerSettings);
45   return std::find(kNonOwnerSettings, end, pref) == end;
46 }
47
48 // Creates a user info dictionary to be stored in the |ListValue| that is
49 // passed to Javascript for the |kAccountsPrefUsers| preference.
50 base::DictionaryValue* CreateUserInfo(const std::string& username,
51                                       const std::string& display_email,
52                                       const std::string& display_name) {
53   base::DictionaryValue* user_dict = new base::DictionaryValue;
54   user_dict->SetString("username", username);
55   user_dict->SetString("name", display_email);
56   user_dict->SetString("email", display_name);
57
58   bool is_owner = UserManager::Get()->GetOwnerEmail() == username;
59   user_dict->SetBoolean("owner", is_owner);
60   return user_dict;
61 }
62
63 // This function decorates the bare list of emails with some more information
64 // needed by the UI to properly display the Accounts page.
65 base::Value* CreateUsersWhitelist(const base::Value *pref_value) {
66   const base::ListValue* list_value =
67       static_cast<const base::ListValue*>(pref_value);
68   base::ListValue* user_list = new base::ListValue();
69   UserManager* user_manager = UserManager::Get();
70
71   for (base::ListValue::const_iterator i = list_value->begin();
72        i != list_value->end(); ++i) {
73     std::string email;
74     if ((*i)->GetAsString(&email)) {
75       // Translate email to the display email.
76       std::string display_email = user_manager->GetUserDisplayEmail(email);
77       // TODO(ivankr): fetch display name for existing users.
78       user_list->Append(CreateUserInfo(email, display_email, std::string()));
79     }
80   }
81   return user_list;
82 }
83
84 const char kSelectNetworkMessage[] = "selectNetwork";
85
86 }  // namespace
87
88 CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler() {
89 }
90
91 CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() {
92 }
93
94 void CoreChromeOSOptionsHandler::RegisterMessages() {
95   CoreOptionsHandler::RegisterMessages();
96   web_ui()->RegisterMessageCallback(
97       kSelectNetworkMessage,
98       base::Bind(&CoreChromeOSOptionsHandler::SelectNetworkCallback,
99                  base::Unretained(this)));
100 }
101
102 void CoreChromeOSOptionsHandler::InitializeHandler() {
103   // This function is both called on the initial page load and on each reload.
104   // For the latter case, forget the last selected network.
105   proxy_config_service_.SetCurrentNetwork(std::string());
106   // And clear the cached configuration.
107   proxy_config_service_.UpdateFromPrefs();
108
109   CoreOptionsHandler::InitializeHandler();
110
111   PrefService* profile_prefs = NULL;
112   Profile* profile = Profile::FromWebUI(web_ui());
113   if (!ProfileHelper::IsSigninProfile(profile)) {
114     profile_prefs = profile->GetPrefs();
115     ObservePref(prefs::kOpenNetworkConfiguration);
116   }
117   ObservePref(prefs::kProxy);
118   ObservePref(prefs::kDeviceOpenNetworkConfiguration);
119   proxy_config_service_.SetPrefs(profile_prefs,
120                                  g_browser_process->local_state());
121 }
122
123 base::Value* CoreChromeOSOptionsHandler::FetchPref(
124     const std::string& pref_name) {
125   if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
126     base::Value *value = NULL;
127     proxy_cros_settings_parser::GetProxyPrefValue(
128         proxy_config_service_, pref_name, &value);
129     if (!value)
130       return base::Value::CreateNullValue();
131
132     return value;
133   }
134
135   if (!CrosSettings::IsCrosSettings(pref_name)) {
136     std::string controlling_pref =
137         pref_name == prefs::kUseSharedProxies ? prefs::kProxy : std::string();
138     return CreateValueForPref(pref_name, controlling_pref);
139   }
140
141   const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name);
142   if (!pref_value)
143     return base::Value::CreateNullValue();
144
145   // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
146   // TODO(estade): seems that this should replicate CreateValueForPref less.
147   base::DictionaryValue* dict = new base::DictionaryValue;
148   if (pref_name == kAccountsPrefUsers)
149     dict->Set("value", CreateUsersWhitelist(pref_value));
150   else
151     dict->Set("value", pref_value->DeepCopy());
152   policy::BrowserPolicyConnectorChromeOS* connector =
153       g_browser_process->platform_part()->browser_policy_connector_chromeos();
154   if (connector->IsEnterpriseManaged()) {
155     dict->SetBoolean("disabled", true);
156     dict->SetString("controlledBy", "policy");
157   } else {
158     bool controlled_by_owner = IsSettingOwnerOnly(pref_name) &&
159         !ProfileHelper::IsOwnerProfile(Profile::FromWebUI(web_ui()));
160     dict->SetBoolean("disabled", controlled_by_owner);
161     if (controlled_by_owner)
162       dict->SetString("controlledBy", "owner");
163   }
164   return dict;
165 }
166
167 void CoreChromeOSOptionsHandler::ObservePref(const std::string& pref_name) {
168   if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
169     // We observe those all the time.
170     return;
171   }
172   if (!CrosSettings::IsCrosSettings(pref_name))
173     return ::options::CoreOptionsHandler::ObservePref(pref_name);
174
175   linked_ptr<CrosSettings::ObserverSubscription> subscription(
176       CrosSettings::Get()->AddSettingsObserver(
177           pref_name.c_str(),
178           base::Bind(&CoreChromeOSOptionsHandler::NotifySettingsChanged,
179                      base::Unretained(this),
180                      pref_name)).release());
181   pref_subscription_map_.insert(make_pair(pref_name, subscription));
182 }
183
184 void CoreChromeOSOptionsHandler::SetPref(const std::string& pref_name,
185                                          const base::Value* value,
186                                          const std::string& metric) {
187   if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
188     proxy_cros_settings_parser::SetProxyPrefValue(
189         pref_name, value, &proxy_config_service_);
190     base::StringValue proxy_type(pref_name);
191     web_ui()->CallJavascriptFunction(
192         "options.internet.DetailsInternetPage.updateProxySettings",
193         proxy_type);
194     ProcessUserMetric(value, metric);
195     return;
196   }
197   if (!CrosSettings::IsCrosSettings(pref_name))
198     return ::options::CoreOptionsHandler::SetPref(pref_name, value, metric);
199   CrosSettings::Get()->Set(pref_name, *value);
200
201   ProcessUserMetric(value, metric);
202 }
203
204 void CoreChromeOSOptionsHandler::StopObservingPref(const std::string& path) {
205   if (proxy_cros_settings_parser::IsProxyPref(path))
206     return;  // We unregister those in the destructor.
207   // Unregister this instance from observing prefs of chrome os settings.
208   if (CrosSettings::IsCrosSettings(path))
209     pref_subscription_map_.erase(path);
210   else  // Call base class to handle regular preferences.
211     ::options::CoreOptionsHandler::StopObservingPref(path);
212 }
213
214 base::Value* CoreChromeOSOptionsHandler::CreateValueForPref(
215     const std::string& pref_name,
216     const std::string& controlling_pref_name) {
217   // The screen lock setting is shared if multiple users are logged in and at
218   // least one has chosen to require passwords.
219   if (pref_name == prefs::kEnableAutoScreenLock &&
220       UserManager::Get()->GetLoggedInUsers().size() > 1 &&
221       controlling_pref_name.empty()) {
222     PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs();
223     const PrefService::Preference* pref =
224         user_prefs->FindPreference(prefs::kEnableAutoScreenLock);
225
226     ash::SessionStateDelegate* delegate =
227         ash::Shell::GetInstance()->session_state_delegate();
228     if (pref && pref->IsUserModifiable() &&
229         delegate->ShouldLockScreenBeforeSuspending()) {
230       bool screen_lock = false;
231       bool success = pref->GetValue()->GetAsBoolean(&screen_lock);
232       DCHECK(success);
233       if (!screen_lock) {
234         // Screen lock is enabled for the session, but not in the user's
235         // preferences. Show the user's value in the checkbox, but indicate
236         // that the password requirement is enabled by some other user.
237         base::DictionaryValue* dict = new base::DictionaryValue;
238         dict->Set("value", pref->GetValue()->DeepCopy());
239         dict->SetString("controlledBy", "shared");
240         return dict;
241       }
242     }
243   }
244
245   return CoreOptionsHandler::CreateValueForPref(pref_name,
246                                                 controlling_pref_name);
247 }
248
249 void CoreChromeOSOptionsHandler::GetLocalizedValues(
250     base::DictionaryValue* localized_strings) {
251   DCHECK(localized_strings);
252   CoreOptionsHandler::GetLocalizedValues(localized_strings);
253
254   Profile* profile = Profile::FromWebUI(web_ui());
255   AddAccountUITweaksLocalizedValues(localized_strings, profile);
256
257   UserManager* user_manager = UserManager::Get();
258
259   // Check at load time whether this is a secondary user in a multi-profile
260   // session.
261   User* user = user_manager->GetUserByProfile(profile);
262   if (user && user->email() != user_manager->GetPrimaryUser()->email()) {
263     const std::string& primary_email = user_manager->GetPrimaryUser()->email();
264
265     // Set secondaryUser to show the shared icon by the network section header.
266     localized_strings->SetBoolean("secondaryUser", true);
267     localized_strings->SetString("secondaryUserBannerText",
268         l10n_util::GetStringFUTF16(
269             IDS_OPTIONS_SETTINGS_SECONDARY_USER_BANNER,
270             base::ASCIIToUTF16(primary_email)));
271     localized_strings->SetString("controlledSettingShared",
272         l10n_util::GetStringFUTF16(
273             IDS_OPTIONS_CONTROLLED_SETTING_SHARED,
274             base::ASCIIToUTF16(primary_email)));
275     localized_strings->SetString("controlledSettingsShared",
276         l10n_util::GetStringFUTF16(
277             IDS_OPTIONS_CONTROLLED_SETTINGS_SHARED,
278             base::ASCIIToUTF16(primary_email)));
279   } else {
280     localized_strings->SetBoolean("secondaryUser", false);
281     localized_strings->SetString("secondaryUserBannerText", base::string16());
282     localized_strings->SetString("controlledSettingShared", base::string16());
283     localized_strings->SetString("controlledSettingsShared", base::string16());
284   }
285
286   // Screen lock icon can show up as primary or secondary user.
287   localized_strings->SetString("screenLockShared",
288       l10n_util::GetStringUTF16(
289           IDS_OPTIONS_CONTROLLED_SETTING_SHARED_SCREEN_LOCK));
290
291   policy::BrowserPolicyConnectorChromeOS* connector =
292       g_browser_process->platform_part()->browser_policy_connector_chromeos();
293   if (connector->IsEnterpriseManaged()) {
294     // Managed machines have no "owner".
295     localized_strings->SetString("controlledSettingOwner", base::string16());
296   } else {
297     localized_strings->SetString("controlledSettingOwner",
298         l10n_util::GetStringFUTF16(
299             IDS_OPTIONS_CONTROLLED_SETTING_OWNER,
300             base::ASCIIToUTF16(user_manager->GetOwnerEmail())));
301   }
302 }
303
304 void CoreChromeOSOptionsHandler::SelectNetworkCallback(
305     const base::ListValue* args) {
306   std::string service_path;
307   if (args->GetSize() != 1 ||
308       !args->GetString(0, &service_path)) {
309     NOTREACHED();
310     return;
311   }
312   proxy_config_service_.SetCurrentNetwork(service_path);
313   NotifyProxyPrefsChanged();
314 }
315
316 void CoreChromeOSOptionsHandler::OnPreferenceChanged(
317     PrefService* service,
318     const std::string& pref_name) {
319   // Redetermine the current proxy settings and notify the UI if any of these
320   // preferences change.
321   if (pref_name == prefs::kOpenNetworkConfiguration ||
322       pref_name == prefs::kDeviceOpenNetworkConfiguration ||
323       pref_name == prefs::kProxy) {
324     NotifyProxyPrefsChanged();
325     return;
326   }
327   if (pref_name == prefs::kUseSharedProxies) {
328     // kProxy controls kUseSharedProxies and decides if it's managed by
329     // policy/extension.
330     NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy);
331     return;
332   }
333   ::options::CoreOptionsHandler::OnPreferenceChanged(service, pref_name);
334 }
335
336 void CoreChromeOSOptionsHandler::NotifySettingsChanged(
337     const std::string& setting_name) {
338   DCHECK(CrosSettings::Get()->IsCrosSettings(setting_name));
339   scoped_ptr<base::Value> value(FetchPref(setting_name));
340   if (!value.get())
341     NOTREACHED();
342   DispatchPrefChangeNotification(setting_name, value.Pass());
343 }
344
345 void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() {
346   proxy_config_service_.UpdateFromPrefs();
347   for (size_t i = 0; i < kProxySettingsCount; ++i) {
348     base::Value* value = NULL;
349     proxy_cros_settings_parser::GetProxyPrefValue(
350         proxy_config_service_, kProxySettings[i], &value);
351     DCHECK(value);
352     scoped_ptr<base::Value> ptr(value);
353     DispatchPrefChangeNotification(kProxySettings[i], ptr.Pass());
354   }
355 }
356
357 }  // namespace options
358 }  // namespace chromeos