device_policy_decoder_chromeos.cc revision 58537e28ecd584eab876aee8be7156509866d23a
14e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved.
24e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org// Use of this source code is governed by a BSD-style license that can be
34e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org// found in the LICENSE file.
44e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org
54e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
64e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org
74e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include <limits>
84e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org
94e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "base/callback.h"
10d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com#include "base/logging.h"
1130a487c7288394ad26ed4a54846567bf868a8f13alokp@chromium.org#include "base/values.h"
1298eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org#include "chrome/browser/chromeos/policy/device_local_account.h"
134e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
144e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "chrome/browser/chromeos/settings/cros_settings_names.h"
154e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "chrome/browser/policy/external_data_fetcher.h"
1698eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org#include "chrome/browser/policy/policy_map.h"
1798eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
184e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org#include "chromeos/dbus/dbus_thread_manager.h"
1998eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org#include "chromeos/dbus/update_engine_client.h"
2098eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org#include "policy/policy_constants.h"
21d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo#include "third_party/cros_system_api/dbus/service_constants.h"
224e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org
23d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mousing google::protobuf::RepeatedField;
24d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mousing google::protobuf::RepeatedPtrField;
25d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo
26d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Monamespace em = enterprise_management;
27d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo
28d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Monamespace policy {
29d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo
30d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Monamespace {
31d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo
32d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo// Decodes a protobuf integer to an IntegerValue. The caller assumes ownership
33d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo// of the return Value*. Returns NULL in case the input value is out of bounds.
34d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao MoValue* DecodeIntegerValue(google::protobuf::int64 value) {
354e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org  if (value < std::numeric_limits<int>::min() ||
36d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo      value > std::numeric_limits<int>::max()) {
3798eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org    LOG(WARNING) << "Integer value " << value
3898eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org                 << " out of numeric limits, ignoring.";
3998eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org    return NULL;
40d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com  }
41d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com
4298eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org  return Value::CreateIntegerValue(static_cast<int>(value));
43d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo}
44d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo
45d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao MoValue* DecodeConnectionType(int value) {
46d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo  static const char* const kConnectionTypes[] = {
47d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo    flimflam::kTypeEthernet,
4898eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org    flimflam::kTypeWifi,
49d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo    flimflam::kTypeWimax,
5098eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org    flimflam::kTypeBluetooth,
5198eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org    flimflam::kTypeCellular,
5298eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org  };
53d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com
54d526f9895c0aa867adb74a78e53832a9240c6ad6Zhenyao Mo  if (value < 0 || value >= static_cast<int>(arraysize(kConnectionTypes)))
55d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com    return NULL;
5698eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org
5798eec91296f500b38c0f274e9de6dcfa03fcfd41alokp@chromium.org  return Value::CreateStringValue(kConnectionTypes[value]);
584e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org}
594e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org
604e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.orgvoid DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
614e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org                         PolicyMap* policies) {
624e4b807d219f58fad5f7b96ed23c9fdd1fc5de15alokp@chromium.org  if (policy.has_guest_mode_enabled()) {
63    const em::GuestModeEnabledProto& container(policy.guest_mode_enabled());
64    if (container.has_guest_mode_enabled()) {
65      policies->Set(key::kDeviceGuestModeEnabled,
66                    POLICY_LEVEL_MANDATORY,
67                    POLICY_SCOPE_MACHINE,
68                    Value::CreateBooleanValue(container.guest_mode_enabled()),
69                    NULL);
70    }
71  }
72
73  if (policy.has_show_user_names()) {
74    const em::ShowUserNamesOnSigninProto& container(policy.show_user_names());
75    if (container.has_show_user_names()) {
76      policies->Set(key::kDeviceShowUserNamesOnSignin,
77                    POLICY_LEVEL_MANDATORY,
78                    POLICY_SCOPE_MACHINE,
79                    Value::CreateBooleanValue(container.show_user_names()),
80                    NULL);
81    }
82  }
83
84  if (policy.has_allow_new_users()) {
85    const em::AllowNewUsersProto& container(policy.allow_new_users());
86    if (container.has_allow_new_users()) {
87      policies->Set(key::kDeviceAllowNewUsers,
88                    POLICY_LEVEL_MANDATORY,
89                    POLICY_SCOPE_MACHINE,
90                    Value::CreateBooleanValue(container.allow_new_users()),
91                    NULL);
92    }
93  }
94
95  if (policy.has_user_whitelist()) {
96    const em::UserWhitelistProto& container(policy.user_whitelist());
97    ListValue* whitelist = new ListValue();
98    RepeatedPtrField<std::string>::const_iterator entry;
99    for (entry = container.user_whitelist().begin();
100         entry != container.user_whitelist().end();
101         ++entry) {
102      whitelist->Append(Value::CreateStringValue(*entry));
103    }
104    policies->Set(key::kDeviceUserWhitelist,
105                  POLICY_LEVEL_MANDATORY,
106                  POLICY_SCOPE_MACHINE,
107                  whitelist,
108                  NULL);
109  }
110
111  if (policy.has_ephemeral_users_enabled()) {
112    const em::EphemeralUsersEnabledProto& container(
113        policy.ephemeral_users_enabled());
114    if (container.has_ephemeral_users_enabled()) {
115      policies->Set(key::kDeviceEphemeralUsersEnabled,
116                    POLICY_LEVEL_MANDATORY,
117                    POLICY_SCOPE_MACHINE,
118                    Value::CreateBooleanValue(
119                        container.ephemeral_users_enabled()),
120                    NULL);
121    }
122  }
123
124  if (policy.has_device_local_accounts()) {
125    const em::DeviceLocalAccountsProto& container(
126        policy.device_local_accounts());
127    const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
128        container.account();
129    scoped_ptr<base::ListValue> account_list(new base::ListValue());
130    RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
131    for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
132      scoped_ptr<base::DictionaryValue> entry_dict(
133          new base::DictionaryValue());
134      if (entry->has_type()) {
135        if (entry->has_account_id()) {
136          entry_dict->SetStringWithoutPathExpansion(
137              chromeos::kAccountsPrefDeviceLocalAccountsKeyId,
138              entry->account_id());
139        }
140        entry_dict->SetIntegerWithoutPathExpansion(
141            chromeos::kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
142        if (entry->kiosk_app().has_app_id()) {
143          entry_dict->SetStringWithoutPathExpansion(
144              chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
145              entry->kiosk_app().app_id());
146        }
147        if (entry->kiosk_app().has_update_url()) {
148          entry_dict->SetStringWithoutPathExpansion(
149              chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
150              entry->kiosk_app().update_url());
151        }
152      } else if (entry->has_deprecated_public_session_id()) {
153        // Deprecated public session specification.
154        entry_dict->SetStringWithoutPathExpansion(
155            chromeos::kAccountsPrefDeviceLocalAccountsKeyId,
156            entry->deprecated_public_session_id());
157        entry_dict->SetIntegerWithoutPathExpansion(
158            chromeos::kAccountsPrefDeviceLocalAccountsKeyType,
159            DeviceLocalAccount::TYPE_PUBLIC_SESSION);
160      }
161      account_list->Append(entry_dict.release());
162    }
163    policies->Set(key::kDeviceLocalAccounts,
164                  POLICY_LEVEL_MANDATORY,
165                  POLICY_SCOPE_MACHINE,
166                  account_list.release(),
167                  NULL);
168    if (container.has_auto_login_id()) {
169      policies->Set(key::kDeviceLocalAccountAutoLoginId,
170                    POLICY_LEVEL_MANDATORY,
171                    POLICY_SCOPE_MACHINE,
172                    Value::CreateStringValue(container.auto_login_id()),
173                    NULL);
174    }
175    if (container.has_auto_login_delay()) {
176      policies->Set(key::kDeviceLocalAccountAutoLoginDelay,
177                    POLICY_LEVEL_MANDATORY,
178                    POLICY_SCOPE_MACHINE,
179                    DecodeIntegerValue(container.auto_login_delay()),
180                    NULL);
181    }
182    if (container.has_enable_auto_login_bailout()) {
183      policies->Set(key::kDeviceLocalAccountAutoLoginBailoutEnabled,
184                    POLICY_LEVEL_MANDATORY,
185                    POLICY_SCOPE_MACHINE,
186                    Value::CreateBooleanValue(
187                        container.enable_auto_login_bailout()),
188                    NULL);
189    }
190  }
191
192  if (policy.has_supervised_users_settings()) {
193    const em::SupervisedUsersSettingsProto& container =
194        policy.supervised_users_settings();
195    if (container.has_supervised_users_enabled()) {
196      Value* value = Value::CreateBooleanValue(
197          container.supervised_users_enabled());
198      policies->Set(key::kSupervisedUsersEnabled,
199                    POLICY_LEVEL_MANDATORY,
200                    POLICY_SCOPE_MACHINE,
201                    value,
202                    NULL);
203    }
204  }
205}
206
207void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy,
208                         PolicyMap* policies,
209                         EnterpriseInstallAttributes* install_attributes) {
210  // No policies if this is not KIOSK.
211  if (install_attributes->GetMode() != DEVICE_MODE_RETAIL_KIOSK)
212    return;
213
214  if (policy.has_forced_logout_timeouts()) {
215    const em::ForcedLogoutTimeoutsProto& container(
216        policy.forced_logout_timeouts());
217    if (container.has_idle_logout_timeout()) {
218      policies->Set(key::kDeviceIdleLogoutTimeout,
219                    POLICY_LEVEL_MANDATORY,
220                    POLICY_SCOPE_MACHINE,
221                    DecodeIntegerValue(container.idle_logout_timeout()),
222                    NULL);
223    }
224    if (container.has_idle_logout_warning_duration()) {
225      policies->Set(key::kDeviceIdleLogoutWarningDuration,
226                    POLICY_LEVEL_MANDATORY,
227                    POLICY_SCOPE_MACHINE,
228                    DecodeIntegerValue(
229                        container.idle_logout_warning_duration()),
230                    NULL);
231    }
232  }
233
234  if (policy.has_login_screen_saver()) {
235    const em::ScreenSaverProto& container(
236        policy.login_screen_saver());
237    if (container.has_screen_saver_extension_id()) {
238      policies->Set(key::kDeviceLoginScreenSaverId,
239                    POLICY_LEVEL_MANDATORY,
240                    POLICY_SCOPE_MACHINE,
241                    Value::CreateStringValue(
242                        container.screen_saver_extension_id()),
243                    NULL);
244    }
245    if (container.has_screen_saver_timeout()) {
246      policies->Set(key::kDeviceLoginScreenSaverTimeout,
247                    POLICY_LEVEL_MANDATORY,
248                    POLICY_SCOPE_MACHINE,
249                    DecodeIntegerValue(container.screen_saver_timeout()),
250                    NULL);
251    }
252  }
253
254  if (policy.has_app_pack()) {
255    const em::AppPackProto& container(policy.app_pack());
256    base::ListValue* app_pack_list = new base::ListValue();
257    for (int i = 0; i < container.app_pack_size(); ++i) {
258      const em::AppPackEntryProto& entry(container.app_pack(i));
259      if (entry.has_extension_id() && entry.has_update_url()) {
260        base::DictionaryValue* dict = new base::DictionaryValue();
261        dict->SetString(chromeos::kAppPackKeyExtensionId, entry.extension_id());
262        dict->SetString(chromeos::kAppPackKeyUpdateUrl, entry.update_url());
263        app_pack_list->Append(dict);
264      }
265    }
266    policies->Set(key::kDeviceAppPack,
267                  POLICY_LEVEL_MANDATORY,
268                  POLICY_SCOPE_MACHINE,
269                  app_pack_list,
270                  NULL);
271  }
272
273  if (policy.has_pinned_apps()) {
274    const em::PinnedAppsProto& container(policy.pinned_apps());
275    base::ListValue* pinned_apps_list = new base::ListValue();
276    for (int i = 0; i < container.app_id_size(); ++i)
277      pinned_apps_list->Append(Value::CreateStringValue(container.app_id(i)));
278
279    policies->Set(key::kPinnedLauncherApps,
280                  POLICY_LEVEL_RECOMMENDED,
281                  POLICY_SCOPE_MACHINE,
282                  pinned_apps_list,
283                  NULL);
284  }
285}
286
287void DecodeNetworkPolicies(const em::ChromeDeviceSettingsProto& policy,
288                           PolicyMap* policies,
289                           EnterpriseInstallAttributes* install_attributes) {
290  if (policy.has_device_proxy_settings()) {
291    const em::DeviceProxySettingsProto& container(
292        policy.device_proxy_settings());
293    scoped_ptr<DictionaryValue> proxy_settings(new DictionaryValue);
294    if (container.has_proxy_mode())
295      proxy_settings->SetString(key::kProxyMode, container.proxy_mode());
296    if (container.has_proxy_server())
297      proxy_settings->SetString(key::kProxyServer, container.proxy_server());
298    if (container.has_proxy_pac_url())
299      proxy_settings->SetString(key::kProxyPacUrl, container.proxy_pac_url());
300    if (container.has_proxy_bypass_list()) {
301      proxy_settings->SetString(key::kProxyBypassList,
302                                container.proxy_bypass_list());
303    }
304
305    // Figure out the level. Proxy policy is mandatory in kiosk mode.
306    PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
307    if (install_attributes->GetMode() == DEVICE_MODE_RETAIL_KIOSK)
308      level = POLICY_LEVEL_MANDATORY;
309
310    if (!proxy_settings->empty()) {
311      policies->Set(key::kProxySettings,
312                    level,
313                    POLICY_SCOPE_MACHINE,
314                    proxy_settings.release(),
315                    NULL);
316    }
317  }
318
319  if (policy.has_data_roaming_enabled()) {
320    const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled());
321    if (container.has_data_roaming_enabled()) {
322      policies->Set(key::kDeviceDataRoamingEnabled,
323                    POLICY_LEVEL_MANDATORY,
324                    POLICY_SCOPE_MACHINE,
325                    Value::CreateBooleanValue(
326                        container.data_roaming_enabled()),
327                    NULL);
328    }
329  }
330
331  if (policy.has_open_network_configuration() &&
332      policy.open_network_configuration().has_open_network_configuration()) {
333    std::string config(
334        policy.open_network_configuration().open_network_configuration());
335    policies->Set(key::kDeviceOpenNetworkConfiguration,
336                  POLICY_LEVEL_MANDATORY,
337                  POLICY_SCOPE_MACHINE,
338                  Value::CreateStringValue(config),
339                  NULL);
340  }
341}
342
343void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy,
344                             PolicyMap* policies) {
345  if (policy.has_device_reporting()) {
346    const em::DeviceReportingProto& container(policy.device_reporting());
347    if (container.has_report_version_info()) {
348      policies->Set(key::kReportDeviceVersionInfo,
349                    POLICY_LEVEL_MANDATORY,
350                    POLICY_SCOPE_MACHINE,
351                    Value::CreateBooleanValue(container.report_version_info()),
352                    NULL);
353    }
354    if (container.has_report_activity_times()) {
355      policies->Set(key::kReportDeviceActivityTimes,
356                    POLICY_LEVEL_MANDATORY,
357                    POLICY_SCOPE_MACHINE,
358                    Value::CreateBooleanValue(
359                        container.report_activity_times()),
360                    NULL);
361    }
362    if (container.has_report_boot_mode()) {
363      policies->Set(key::kReportDeviceBootMode,
364                    POLICY_LEVEL_MANDATORY,
365                    POLICY_SCOPE_MACHINE,
366                    Value::CreateBooleanValue(container.report_boot_mode()),
367                    NULL);
368    }
369    if (container.has_report_location()) {
370      policies->Set(key::kReportDeviceLocation,
371                    POLICY_LEVEL_MANDATORY,
372                    POLICY_SCOPE_MACHINE,
373                    Value::CreateBooleanValue(container.report_location()),
374                    NULL);
375    }
376    if (container.has_report_network_interfaces()) {
377      policies->Set(key::kReportDeviceNetworkInterfaces,
378                    POLICY_LEVEL_MANDATORY,
379                    POLICY_SCOPE_MACHINE,
380                    Value::CreateBooleanValue(
381                        container.report_network_interfaces()),
382                    NULL);
383    }
384  }
385}
386
387void DecodeAutoUpdatePolicies(const em::ChromeDeviceSettingsProto& policy,
388                              PolicyMap* policies) {
389  if (policy.has_release_channel()) {
390    const em::ReleaseChannelProto& container(policy.release_channel());
391    if (container.has_release_channel()) {
392      std::string channel(container.release_channel());
393      policies->Set(key::kChromeOsReleaseChannel,
394                    POLICY_LEVEL_MANDATORY,
395                    POLICY_SCOPE_MACHINE,
396                    Value::CreateStringValue(channel),
397                    NULL);
398      // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
399      // have to pass the channel in here, only ping the update engine to tell
400      // it to fetch the channel from the policy.
401      chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
402          SetChannel(channel, false);
403    }
404    if (container.has_release_channel_delegated()) {
405      policies->Set(key::kChromeOsReleaseChannelDelegated,
406                    POLICY_LEVEL_MANDATORY,
407                    POLICY_SCOPE_MACHINE,
408                    Value::CreateBooleanValue(
409                        container.release_channel_delegated()),
410                    NULL);
411    }
412  }
413
414  if (policy.has_auto_update_settings()) {
415    const em::AutoUpdateSettingsProto& container(policy.auto_update_settings());
416    if (container.has_update_disabled()) {
417      policies->Set(key::kDeviceAutoUpdateDisabled,
418                    POLICY_LEVEL_MANDATORY,
419                    POLICY_SCOPE_MACHINE,
420                    Value::CreateBooleanValue(container.update_disabled()),
421                    NULL);
422    }
423
424    if (container.has_target_version_prefix()) {
425      policies->Set(key::kDeviceTargetVersionPrefix,
426                    POLICY_LEVEL_MANDATORY,
427                    POLICY_SCOPE_MACHINE,
428                    Value::CreateStringValue(
429                        container.target_version_prefix()),
430                    NULL);
431    }
432
433    // target_version_display_name is not actually a policy, but a display
434    // string for target_version_prefix, so we ignore it.
435
436    if (container.has_scatter_factor_in_seconds()) {
437      policies->Set(key::kDeviceUpdateScatterFactor,
438                    POLICY_LEVEL_MANDATORY,
439                    POLICY_SCOPE_MACHINE,
440                    Value::CreateIntegerValue(
441                        container.scatter_factor_in_seconds()),
442                    NULL);
443    }
444
445    if (container.allowed_connection_types_size()) {
446      ListValue* allowed_connection_types = new ListValue();
447      RepeatedField<int>::const_iterator entry;
448      for (entry = container.allowed_connection_types().begin();
449           entry != container.allowed_connection_types().end();
450           ++entry) {
451        base::Value* value = DecodeConnectionType(*entry);
452        if (value)
453          allowed_connection_types->Append(value);
454      }
455      policies->Set(key::kDeviceUpdateAllowedConnectionTypes,
456                    POLICY_LEVEL_MANDATORY,
457                    POLICY_SCOPE_MACHINE,
458                    allowed_connection_types,
459                    NULL);
460    }
461
462    if (container.has_reboot_after_update()) {
463      policies->Set(key::kRebootAfterUpdate,
464                    POLICY_LEVEL_MANDATORY,
465                    POLICY_SCOPE_MACHINE,
466                    Value::CreateBooleanValue(container.reboot_after_update()),
467                    NULL);
468    }
469
470    if (container.has_p2p_enabled()) {
471      policies->Set(key::kDeviceAutoUpdateP2PEnabled,
472                    POLICY_LEVEL_MANDATORY,
473                    POLICY_SCOPE_MACHINE,
474                    Value::CreateBooleanValue(container.p2p_enabled()),
475                    NULL);
476    }
477  }
478}
479
480void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy,
481                                 PolicyMap* policies) {
482  if (policy.has_accessibility_settings()) {
483    const em::AccessibilitySettingsProto&
484        container(policy.accessibility_settings());
485
486    if (container.has_login_screen_default_large_cursor_enabled()) {
487      policies->Set(
488          key::kDeviceLoginScreenDefaultLargeCursorEnabled,
489          POLICY_LEVEL_MANDATORY,
490          POLICY_SCOPE_MACHINE,
491          Value::CreateBooleanValue(
492              container.login_screen_default_large_cursor_enabled()),
493          NULL);
494    }
495
496    if (container.has_login_screen_default_spoken_feedback_enabled()) {
497      policies->Set(
498          key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
499          POLICY_LEVEL_MANDATORY,
500          POLICY_SCOPE_MACHINE,
501          Value::CreateBooleanValue(
502              container.login_screen_default_spoken_feedback_enabled()),
503          NULL);
504    }
505
506    if (container.has_login_screen_default_high_contrast_enabled()) {
507      policies->Set(
508          key::kDeviceLoginScreenDefaultHighContrastEnabled,
509          POLICY_LEVEL_MANDATORY,
510          POLICY_SCOPE_MACHINE,
511          Value::CreateBooleanValue(
512              container.login_screen_default_high_contrast_enabled()),
513          NULL);
514    }
515
516    if (container.has_login_screen_default_screen_magnifier_type()) {
517      policies->Set(
518          key::kDeviceLoginScreenDefaultScreenMagnifierType,
519          POLICY_LEVEL_MANDATORY,
520          POLICY_SCOPE_MACHINE,
521          DecodeIntegerValue(
522              container.login_screen_default_screen_magnifier_type()),
523          NULL);
524    }
525  }
526}
527
528void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
529                           PolicyMap* policies) {
530  if (policy.has_device_policy_refresh_rate()) {
531    const em::DevicePolicyRefreshRateProto& container(
532        policy.device_policy_refresh_rate());
533    if (container.has_device_policy_refresh_rate()) {
534      policies->Set(key::kDevicePolicyRefreshRate,
535                    POLICY_LEVEL_MANDATORY,
536                    POLICY_SCOPE_MACHINE,
537                    DecodeIntegerValue(container.device_policy_refresh_rate()),
538                    NULL);
539    }
540  }
541
542  if (policy.has_metrics_enabled()) {
543    const em::MetricsEnabledProto& container(policy.metrics_enabled());
544    if (container.has_metrics_enabled()) {
545      policies->Set(key::kDeviceMetricsReportingEnabled,
546                    POLICY_LEVEL_MANDATORY,
547                    POLICY_SCOPE_MACHINE,
548                    Value::CreateBooleanValue(container.metrics_enabled()),
549                    NULL);
550    }
551  }
552
553  if (policy.has_start_up_urls()) {
554    const em::StartUpUrlsProto& container(policy.start_up_urls());
555    ListValue* urls = new ListValue();
556    RepeatedPtrField<std::string>::const_iterator entry;
557    for (entry = container.start_up_urls().begin();
558         entry != container.start_up_urls().end();
559         ++entry) {
560      urls->Append(Value::CreateStringValue(*entry));
561    }
562    policies->Set(key::kDeviceStartUpUrls,
563                  POLICY_LEVEL_MANDATORY,
564                  POLICY_SCOPE_MACHINE,
565                  urls,
566                  NULL);
567  }
568
569  if (policy.has_system_timezone()) {
570    if (policy.system_timezone().has_timezone()) {
571      policies->Set(key::kSystemTimezone,
572                    POLICY_LEVEL_MANDATORY,
573                    POLICY_SCOPE_MACHINE,
574                    Value::CreateStringValue(
575                        policy.system_timezone().timezone()),
576                    NULL);
577    }
578  }
579
580  if (policy.has_use_24hour_clock()) {
581    if (policy.use_24hour_clock().has_use_24hour_clock()) {
582      policies->Set(key::kSystemUse24HourClock,
583                    POLICY_LEVEL_MANDATORY,
584                    POLICY_SCOPE_MACHINE,
585                    Value::CreateBooleanValue(
586                        policy.use_24hour_clock().use_24hour_clock()),
587                    NULL);
588    }
589  }
590
591  if (policy.has_allow_redeem_offers()) {
592    const em::AllowRedeemChromeOsRegistrationOffersProto& container(
593        policy.allow_redeem_offers());
594    if (container.has_allow_redeem_offers()) {
595      policies->Set(key::kDeviceAllowRedeemChromeOsRegistrationOffers,
596                    POLICY_LEVEL_MANDATORY,
597                    POLICY_SCOPE_MACHINE,
598                    Value::CreateBooleanValue(
599                        container.allow_redeem_offers()),
600                    NULL);
601    }
602  }
603
604  if (policy.has_uptime_limit()) {
605    const em::UptimeLimitProto& container(policy.uptime_limit());
606    if (container.has_uptime_limit()) {
607      policies->Set(key::kUptimeLimit,
608                    POLICY_LEVEL_MANDATORY,
609                    POLICY_SCOPE_MACHINE,
610                    DecodeIntegerValue(container.uptime_limit()),
611                    NULL);
612    }
613  }
614
615  if (policy.has_start_up_flags()) {
616    const em::StartUpFlagsProto& container(policy.start_up_flags());
617    ListValue* flags = new ListValue();
618    RepeatedPtrField<std::string>::const_iterator entry;
619    for (entry = container.flags().begin();
620         entry != container.flags().end();
621         ++entry) {
622      flags->Append(Value::CreateStringValue(*entry));
623    }
624    policies->Set(key::kDeviceStartUpFlags,
625                  POLICY_LEVEL_MANDATORY,
626                  POLICY_SCOPE_MACHINE,
627                  flags,
628                  NULL);
629  }
630
631  if (policy.has_variations_parameter()) {
632    if (policy.variations_parameter().has_parameter()) {
633      policies->Set(key::kDeviceVariationsRestrictParameter,
634                    POLICY_LEVEL_MANDATORY,
635                    POLICY_SCOPE_MACHINE,
636                    Value::CreateStringValue(
637                        policy.variations_parameter().parameter()),
638                    NULL);
639    }
640  }
641
642  if (policy.has_attestation_settings()) {
643    if (policy.attestation_settings().has_attestation_enabled()) {
644      policies->Set(key::kAttestationEnabledForDevice,
645                    POLICY_LEVEL_MANDATORY,
646                    POLICY_SCOPE_MACHINE,
647                    Value::CreateBooleanValue(
648                        policy.attestation_settings().attestation_enabled()),
649                    NULL);
650    }
651    if (policy.attestation_settings().has_content_protection_enabled()) {
652      policies->Set(
653          key::kAttestationForContentProtectionEnabled,
654          POLICY_LEVEL_MANDATORY,
655          POLICY_SCOPE_MACHINE,
656          Value::CreateBooleanValue(
657              policy.attestation_settings().content_protection_enabled()),
658          NULL);
659    }
660  }
661
662  if (policy.has_login_screen_power_management()) {
663    const em::LoginScreenPowerManagementProto& container(
664        policy.login_screen_power_management());
665    if (container.has_login_screen_power_management()) {
666      policies->Set(key::kDeviceLoginScreenPowerManagement,
667                    POLICY_LEVEL_MANDATORY,
668                    POLICY_SCOPE_MACHINE,
669                    Value::CreateStringValue(
670                        container.login_screen_power_management()),
671                    NULL);
672    }
673  }
674}
675
676}  // namespace
677
678void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
679                        PolicyMap* policies,
680                        EnterpriseInstallAttributes* install_attributes) {
681  // Decode the various groups of policies.
682  DecodeLoginPolicies(policy, policies);
683  DecodeKioskPolicies(policy, policies, install_attributes);
684  DecodeNetworkPolicies(policy, policies, install_attributes);
685  DecodeReportingPolicies(policy, policies);
686  DecodeAutoUpdatePolicies(policy, policies);
687  DecodeAccessibilityPolicies(policy, policies);
688  DecodeGenericPolicies(policy, policies);
689}
690
691}  // namespace policy
692