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.
5 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
10 #include "base/prefs/pref_change_registrar.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chromeos/login/user_manager.h"
16 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
17 #include "chrome/browser/chromeos/profiles/profile_helper.h"
18 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h"
22 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
23 #include "chrome/common/pref_names.h"
24 #include "content/public/browser/user_metrics.h"
25 #include "content/public/browser/web_ui.h"
26 #include "grit/generated_resources.h"
27 #include "ui/base/l10n/l10n_util.h"
34 // List of settings that should be changeable by all users.
35 const char* kNonOwnerSettings[] = {
39 // Returns true if |pref| should be only available to the owner.
40 bool IsSettingOwnerOnly(const std::string& pref) {
41 const char** end = kNonOwnerSettings + arraysize(kNonOwnerSettings);
42 return std::find(kNonOwnerSettings, end, pref) == end;
45 // Returns true if |username| is the logged-in owner.
46 bool IsLoggedInOwner(const std::string& username) {
47 UserManager* user_manager = UserManager::Get();
48 return user_manager->IsCurrentUserOwner() &&
49 user_manager->GetLoggedInUser()->email() == username;
52 // Creates a user info dictionary to be stored in the |ListValue| that is
53 // passed to Javascript for the |kAccountsPrefUsers| preference.
54 base::DictionaryValue* CreateUserInfo(const std::string& username,
55 const std::string& display_email,
56 const std::string& display_name) {
57 base::DictionaryValue* user_dict = new base::DictionaryValue;
58 user_dict->SetString("username", username);
59 user_dict->SetString("name", display_email);
60 user_dict->SetString("email", display_name);
61 user_dict->SetBoolean("owner", IsLoggedInOwner(username));
65 // This function decorates the bare list of emails with some more information
66 // needed by the UI to properly display the Accounts page.
67 base::Value* CreateUsersWhitelist(const base::Value *pref_value) {
68 const base::ListValue* list_value =
69 static_cast<const base::ListValue*>(pref_value);
70 base::ListValue* user_list = new base::ListValue();
71 UserManager* user_manager = UserManager::Get();
73 for (base::ListValue::const_iterator i = list_value->begin();
74 i != list_value->end(); ++i) {
76 if ((*i)->GetAsString(&email)) {
77 // Translate email to the display email.
78 std::string display_email = user_manager->GetUserDisplayEmail(email);
79 // TODO(ivankr): fetch display name for existing users.
80 user_list->Append(CreateUserInfo(email, display_email, std::string()));
86 const char kSelectNetworkMessage[] = "selectNetwork";
90 CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler() {
93 CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() {
96 void CoreChromeOSOptionsHandler::RegisterMessages() {
97 CoreOptionsHandler::RegisterMessages();
98 web_ui()->RegisterMessageCallback(
99 kSelectNetworkMessage,
100 base::Bind(&CoreChromeOSOptionsHandler::SelectNetworkCallback,
101 base::Unretained(this)));
104 void CoreChromeOSOptionsHandler::InitializeHandler() {
105 // This function is both called on the initial page load and on each reload.
106 // For the latter case, forget the last selected network.
107 proxy_config_service_.SetCurrentNetwork(std::string());
108 // And clear the cached configuration.
109 proxy_config_service_.UpdateFromPrefs();
111 CoreOptionsHandler::InitializeHandler();
113 PrefService* profile_prefs = NULL;
114 Profile* profile = Profile::FromWebUI(web_ui());
115 if (!ProfileHelper::IsSigninProfile(profile)) {
116 profile_prefs = profile->GetPrefs();
117 ObservePref(prefs::kOpenNetworkConfiguration);
119 ObservePref(prefs::kProxy);
120 ObservePref(prefs::kDeviceOpenNetworkConfiguration);
121 proxy_config_service_.SetPrefs(profile_prefs,
122 g_browser_process->local_state());
125 base::Value* CoreChromeOSOptionsHandler::FetchPref(
126 const std::string& pref_name) {
127 if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
128 base::Value *value = NULL;
129 proxy_cros_settings_parser::GetProxyPrefValue(
130 proxy_config_service_, pref_name, &value);
132 return base::Value::CreateNullValue();
136 if (!CrosSettings::IsCrosSettings(pref_name)) {
137 std::string controlling_pref =
138 pref_name == prefs::kUseSharedProxies ? prefs::kProxy : std::string();
139 return CreateValueForPref(pref_name, controlling_pref);
142 const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name);
144 return base::Value::CreateNullValue();
146 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
147 // TODO(estade): seems that this should replicate CreateValueForPref less.
148 base::DictionaryValue* dict = new base::DictionaryValue;
149 if (pref_name == kAccountsPrefUsers)
150 dict->Set("value", CreateUsersWhitelist(pref_value));
152 dict->Set("value", pref_value->DeepCopy());
153 policy::BrowserPolicyConnectorChromeOS* connector =
154 g_browser_process->platform_part()->browser_policy_connector_chromeos();
155 if (connector->IsEnterpriseManaged())
156 dict->SetString("controlledBy", "policy");
157 bool disabled_by_owner = IsSettingOwnerOnly(pref_name) &&
158 !UserManager::Get()->IsCurrentUserOwner();
159 dict->SetBoolean("disabled", disabled_by_owner);
160 if (disabled_by_owner)
161 dict->SetString("controlledBy", "owner");
165 void CoreChromeOSOptionsHandler::ObservePref(const std::string& pref_name) {
166 if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
167 // We observe those all the time.
170 if (!CrosSettings::IsCrosSettings(pref_name))
171 return ::options::CoreOptionsHandler::ObservePref(pref_name);
173 linked_ptr<CrosSettings::ObserverSubscription> subscription(
174 CrosSettings::Get()->AddSettingsObserver(
176 base::Bind(&CoreChromeOSOptionsHandler::NotifySettingsChanged,
177 base::Unretained(this),
178 pref_name)).release());
179 pref_subscription_map_.insert(make_pair(pref_name, subscription));
182 void CoreChromeOSOptionsHandler::SetPref(const std::string& pref_name,
183 const base::Value* value,
184 const std::string& metric) {
185 if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
186 proxy_cros_settings_parser::SetProxyPrefValue(
187 pref_name, value, &proxy_config_service_);
188 base::StringValue proxy_type(pref_name);
189 web_ui()->CallJavascriptFunction(
190 "options.internet.DetailsInternetPage.updateProxySettings",
192 ProcessUserMetric(value, metric);
195 if (!CrosSettings::IsCrosSettings(pref_name))
196 return ::options::CoreOptionsHandler::SetPref(pref_name, value, metric);
197 CrosSettings::Get()->Set(pref_name, *value);
199 ProcessUserMetric(value, metric);
202 void CoreChromeOSOptionsHandler::StopObservingPref(const std::string& path) {
203 if (proxy_cros_settings_parser::IsProxyPref(path))
204 return; // We unregister those in the destructor.
205 // Unregister this instance from observing prefs of chrome os settings.
206 if (CrosSettings::IsCrosSettings(path))
207 pref_subscription_map_.erase(path);
208 else // Call base class to handle regular preferences.
209 ::options::CoreOptionsHandler::StopObservingPref(path);
212 void CoreChromeOSOptionsHandler::GetLocalizedValues(
213 base::DictionaryValue* localized_strings) {
214 DCHECK(localized_strings);
215 CoreOptionsHandler::GetLocalizedValues(localized_strings);
217 AddAccountUITweaksLocalizedValues(localized_strings);
218 localized_strings->SetString("controlledSettingOwner",
219 l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_OWNER));
222 void CoreChromeOSOptionsHandler::SelectNetworkCallback(
223 const base::ListValue* args) {
224 std::string service_path;
225 if (args->GetSize() != 1 ||
226 !args->GetString(0, &service_path)) {
230 proxy_config_service_.SetCurrentNetwork(service_path);
231 NotifyProxyPrefsChanged();
234 void CoreChromeOSOptionsHandler::OnPreferenceChanged(
235 PrefService* service,
236 const std::string& pref_name) {
237 // Redetermine the current proxy settings and notify the UI if any of these
238 // preferences change.
239 if (pref_name == prefs::kOpenNetworkConfiguration ||
240 pref_name == prefs::kDeviceOpenNetworkConfiguration ||
241 pref_name == prefs::kProxy) {
242 NotifyProxyPrefsChanged();
245 if (pref_name == prefs::kUseSharedProxies) {
246 // kProxy controls kUseSharedProxies and decides if it's managed by
248 NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy);
251 ::options::CoreOptionsHandler::OnPreferenceChanged(service, pref_name);
254 void CoreChromeOSOptionsHandler::NotifySettingsChanged(
255 const std::string& setting_name) {
256 DCHECK(CrosSettings::Get()->IsCrosSettings(setting_name));
257 scoped_ptr<base::Value> value(FetchPref(setting_name));
260 DispatchPrefChangeNotification(setting_name, value.Pass());
263 void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() {
264 proxy_config_service_.UpdateFromPrefs();
265 for (size_t i = 0; i < kProxySettingsCount; ++i) {
266 base::Value* value = NULL;
267 proxy_cros_settings_parser::GetProxyPrefValue(
268 proxy_config_service_, kProxySettings[i], &value);
270 scoped_ptr<base::Value> ptr(value);
271 DispatchPrefChangeNotification(kProxySettings[i], ptr.Pass());
275 } // namespace options
276 } // namespace chromeos