Home | History | Annotate | Download | only in policy
      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 
     23 using google::protobuf::RepeatedField;
     24 using google::protobuf::RepeatedPtrField;
     25 
     26 namespace em = enterprise_management;
     27 
     28 namespace policy {
     29 
     30 namespace {
     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.
     34 Value* 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 
     45 Value* 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 
     60 void 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         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 
    207 void 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 
    287 void 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 
    343 void 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 
    387 void 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 }
    471 
    472 void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy,
    473                                  PolicyMap* policies) {
    474   if (policy.has_accessibility_settings()) {
    475     const em::AccessibilitySettingsProto&
    476         container(policy.accessibility_settings());
    477 
    478     if (container.has_login_screen_default_large_cursor_enabled()) {
    479       policies->Set(
    480           key::kDeviceLoginScreenDefaultLargeCursorEnabled,
    481           POLICY_LEVEL_MANDATORY,
    482           POLICY_SCOPE_MACHINE,
    483           Value::CreateBooleanValue(
    484               container.login_screen_default_large_cursor_enabled()),
    485           NULL);
    486     }
    487 
    488     if (container.has_login_screen_default_spoken_feedback_enabled()) {
    489       policies->Set(
    490           key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
    491           POLICY_LEVEL_MANDATORY,
    492           POLICY_SCOPE_MACHINE,
    493           Value::CreateBooleanValue(
    494               container.login_screen_default_spoken_feedback_enabled()),
    495           NULL);
    496     }
    497 
    498     if (container.has_login_screen_default_high_contrast_enabled()) {
    499       policies->Set(
    500           key::kDeviceLoginScreenDefaultHighContrastEnabled,
    501           POLICY_LEVEL_MANDATORY,
    502           POLICY_SCOPE_MACHINE,
    503           Value::CreateBooleanValue(
    504               container.login_screen_default_high_contrast_enabled()),
    505           NULL);
    506     }
    507 
    508     if (container.has_login_screen_default_screen_magnifier_type()) {
    509       policies->Set(
    510           key::kDeviceLoginScreenDefaultScreenMagnifierType,
    511           POLICY_LEVEL_MANDATORY,
    512           POLICY_SCOPE_MACHINE,
    513           DecodeIntegerValue(
    514               container.login_screen_default_screen_magnifier_type()),
    515           NULL);
    516     }
    517   }
    518 }
    519 
    520 void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
    521                            PolicyMap* policies) {
    522   if (policy.has_device_policy_refresh_rate()) {
    523     const em::DevicePolicyRefreshRateProto& container(
    524         policy.device_policy_refresh_rate());
    525     if (container.has_device_policy_refresh_rate()) {
    526       policies->Set(key::kDevicePolicyRefreshRate,
    527                     POLICY_LEVEL_MANDATORY,
    528                     POLICY_SCOPE_MACHINE,
    529                     DecodeIntegerValue(container.device_policy_refresh_rate()),
    530                     NULL);
    531     }
    532   }
    533 
    534   if (policy.has_metrics_enabled()) {
    535     const em::MetricsEnabledProto& container(policy.metrics_enabled());
    536     if (container.has_metrics_enabled()) {
    537       policies->Set(key::kDeviceMetricsReportingEnabled,
    538                     POLICY_LEVEL_MANDATORY,
    539                     POLICY_SCOPE_MACHINE,
    540                     Value::CreateBooleanValue(container.metrics_enabled()),
    541                     NULL);
    542     }
    543   }
    544 
    545   if (policy.has_start_up_urls()) {
    546     const em::StartUpUrlsProto& container(policy.start_up_urls());
    547     ListValue* urls = new ListValue();
    548     RepeatedPtrField<std::string>::const_iterator entry;
    549     for (entry = container.start_up_urls().begin();
    550          entry != container.start_up_urls().end();
    551          ++entry) {
    552       urls->Append(Value::CreateStringValue(*entry));
    553     }
    554     policies->Set(key::kDeviceStartUpUrls,
    555                   POLICY_LEVEL_MANDATORY,
    556                   POLICY_SCOPE_MACHINE,
    557                   urls,
    558                   NULL);
    559   }
    560 
    561   if (policy.has_system_timezone()) {
    562     if (policy.system_timezone().has_timezone()) {
    563       policies->Set(key::kSystemTimezone,
    564                     POLICY_LEVEL_MANDATORY,
    565                     POLICY_SCOPE_MACHINE,
    566                     Value::CreateStringValue(
    567                         policy.system_timezone().timezone()),
    568                     NULL);
    569     }
    570   }
    571 
    572   if (policy.has_use_24hour_clock()) {
    573     if (policy.use_24hour_clock().has_use_24hour_clock()) {
    574       policies->Set(key::kSystemUse24HourClock,
    575                     POLICY_LEVEL_MANDATORY,
    576                     POLICY_SCOPE_MACHINE,
    577                     Value::CreateBooleanValue(
    578                         policy.use_24hour_clock().use_24hour_clock()),
    579                     NULL);
    580     }
    581   }
    582 
    583   if (policy.has_allow_redeem_offers()) {
    584     const em::AllowRedeemChromeOsRegistrationOffersProto& container(
    585         policy.allow_redeem_offers());
    586     if (container.has_allow_redeem_offers()) {
    587       policies->Set(key::kDeviceAllowRedeemChromeOsRegistrationOffers,
    588                     POLICY_LEVEL_MANDATORY,
    589                     POLICY_SCOPE_MACHINE,
    590                     Value::CreateBooleanValue(
    591                         container.allow_redeem_offers()),
    592                     NULL);
    593     }
    594   }
    595 
    596   if (policy.has_uptime_limit()) {
    597     const em::UptimeLimitProto& container(policy.uptime_limit());
    598     if (container.has_uptime_limit()) {
    599       policies->Set(key::kUptimeLimit,
    600                     POLICY_LEVEL_MANDATORY,
    601                     POLICY_SCOPE_MACHINE,
    602                     DecodeIntegerValue(container.uptime_limit()),
    603                     NULL);
    604     }
    605   }
    606 
    607   if (policy.has_start_up_flags()) {
    608     const em::StartUpFlagsProto& container(policy.start_up_flags());
    609     ListValue* flags = new ListValue();
    610     RepeatedPtrField<std::string>::const_iterator entry;
    611     for (entry = container.flags().begin();
    612          entry != container.flags().end();
    613          ++entry) {
    614       flags->Append(Value::CreateStringValue(*entry));
    615     }
    616     policies->Set(key::kDeviceStartUpFlags,
    617                   POLICY_LEVEL_MANDATORY,
    618                   POLICY_SCOPE_MACHINE,
    619                   flags,
    620                   NULL);
    621   }
    622 
    623   if (policy.has_variations_parameter()) {
    624     if (policy.variations_parameter().has_parameter()) {
    625       policies->Set(key::kDeviceVariationsRestrictParameter,
    626                     POLICY_LEVEL_MANDATORY,
    627                     POLICY_SCOPE_MACHINE,
    628                     Value::CreateStringValue(
    629                         policy.variations_parameter().parameter()),
    630                     NULL);
    631     }
    632   }
    633 
    634   if (policy.has_attestation_settings()) {
    635     if (policy.attestation_settings().has_attestation_enabled()) {
    636       policies->Set(key::kAttestationEnabledForDevice,
    637                     POLICY_LEVEL_MANDATORY,
    638                     POLICY_SCOPE_MACHINE,
    639                     Value::CreateBooleanValue(
    640                         policy.attestation_settings().attestation_enabled()),
    641                     NULL);
    642     }
    643   }
    644 
    645   if (policy.has_login_screen_power_management()) {
    646     const em::LoginScreenPowerManagementProto& container(
    647         policy.login_screen_power_management());
    648     if (container.has_login_screen_power_management()) {
    649       policies->Set(key::kDeviceLoginScreenPowerManagement,
    650                     POLICY_LEVEL_MANDATORY,
    651                     POLICY_SCOPE_MACHINE,
    652                     Value::CreateStringValue(
    653                         container.login_screen_power_management()),
    654                     NULL);
    655     }
    656   }
    657 }
    658 
    659 }  // namespace
    660 
    661 void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
    662                         PolicyMap* policies,
    663                         EnterpriseInstallAttributes* install_attributes) {
    664   // Decode the various groups of policies.
    665   DecodeLoginPolicies(policy, policies);
    666   DecodeKioskPolicies(policy, policies, install_attributes);
    667   DecodeNetworkPolicies(policy, policies, install_attributes);
    668   DecodeReportingPolicies(policy, policies);
    669   DecodeAutoUpdatePolicies(policy, policies);
    670   DecodeAccessibilityPolicies(policy, policies);
    671   DecodeGenericPolicies(policy, policies);
    672 }
    673 
    674 }  // namespace policy
    675