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