Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / device_policy_decoder_chromeos.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/policy/device_policy_decoder_chromeos.h"
6
7 #include <limits>
8 #include <string>
9
10 #include "base/callback.h"
11 #include "base/json/json_reader.h"
12 #include "base/logging.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chromeos/policy/device_local_account.h"
16 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
17 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
18 #include "chromeos/dbus/dbus_thread_manager.h"
19 #include "chromeos/dbus/update_engine_client.h"
20 #include "chromeos/settings/cros_settings_names.h"
21 #include "components/policy/core/browser/browser_policy_connector.h"
22 #include "components/policy/core/common/external_data_fetcher.h"
23 #include "components/policy/core/common/policy_map.h"
24 #include "components/policy/core/common/schema.h"
25 #include "policy/policy_constants.h"
26 #include "third_party/cros_system_api/dbus/service_constants.h"
27
28 using google::protobuf::RepeatedField;
29 using google::protobuf::RepeatedPtrField;
30
31 namespace em = enterprise_management;
32
33 namespace policy {
34
35 namespace {
36
37 // Decodes a protobuf integer to an IntegerValue. Returns NULL in case the input
38 // value is out of bounds.
39 scoped_ptr<base::Value> DecodeIntegerValue(google::protobuf::int64 value) {
40   if (value < std::numeric_limits<int>::min() ||
41       value > std::numeric_limits<int>::max()) {
42     LOG(WARNING) << "Integer value " << value
43                  << " out of numeric limits, ignoring.";
44     return scoped_ptr<base::Value>();
45   }
46
47   return scoped_ptr<base::Value>(
48       new base::FundamentalValue(static_cast<int>(value)));
49 }
50
51 // Decodes a JSON string to a base::Value, and drops unknown properties
52 // according to a policy schema. |policy_name| is the name of a policy schema
53 // defined in policy_templates.json. Returns NULL in case the input is not a
54 // valid JSON string.
55 scoped_ptr<base::Value> DecodeJsonStringAndDropUnknownBySchema(
56     const std::string& json_string,
57     const std::string& policy_name) {
58   std::string error;
59   base::Value* root(base::JSONReader::ReadAndReturnError(
60       json_string, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error));
61
62   if (!root) {
63     LOG(WARNING) << "Invalid JSON string: " << error << ", ignoring.";
64     return scoped_ptr<base::Value>();
65   }
66
67   const Schema& schema = g_browser_process
68                              ->browser_policy_connector()
69                              ->GetChromeSchema()
70                              .GetKnownProperty(policy_name);
71
72   if (schema.valid()) {
73     std::string error_path;
74     bool changed = false;
75
76     if (!schema.Normalize(
77             root, SCHEMA_ALLOW_UNKNOWN, &error_path, &error, &changed)) {
78       LOG(WARNING) << "Invalid policy value for " << policy_name << ": "
79                    << error << " at " << error_path << ".";
80       return scoped_ptr<base::Value>();
81     }
82
83     if (changed) {
84       LOG(WARNING) << "Some properties in " << policy_name
85                    << " were dropped: " << error << " at " << error_path << ".";
86     }
87   } else {
88     LOG(WARNING) << "Unknown or invalid policy schema for " << policy_name
89                  << ".";
90     return scoped_ptr<base::Value>();
91   }
92
93   return scoped_ptr<base::Value>(root);
94 }
95
96 base::Value* DecodeConnectionType(int value) {
97   static const char* const kConnectionTypes[] = {
98     shill::kTypeEthernet,
99     shill::kTypeWifi,
100     shill::kTypeWimax,
101     shill::kTypeBluetooth,
102     shill::kTypeCellular,
103   };
104
105   if (value < 0 || value >= static_cast<int>(arraysize(kConnectionTypes)))
106     return NULL;
107
108   return new base::StringValue(kConnectionTypes[value]);
109 }
110
111 void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
112                          PolicyMap* policies) {
113   if (policy.has_guest_mode_enabled()) {
114     const em::GuestModeEnabledProto& container(policy.guest_mode_enabled());
115     if (container.has_guest_mode_enabled()) {
116       policies->Set(key::kDeviceGuestModeEnabled,
117                     POLICY_LEVEL_MANDATORY,
118                     POLICY_SCOPE_MACHINE,
119                     new base::FundamentalValue(
120                         container.guest_mode_enabled()),
121                     NULL);
122     }
123   }
124
125   if (policy.has_show_user_names()) {
126     const em::ShowUserNamesOnSigninProto& container(policy.show_user_names());
127     if (container.has_show_user_names()) {
128       policies->Set(key::kDeviceShowUserNamesOnSignin,
129                     POLICY_LEVEL_MANDATORY,
130                     POLICY_SCOPE_MACHINE,
131                     new base::FundamentalValue(
132                         container.show_user_names()),
133                     NULL);
134     }
135   }
136
137   if (policy.has_allow_new_users()) {
138     const em::AllowNewUsersProto& container(policy.allow_new_users());
139     if (container.has_allow_new_users()) {
140       policies->Set(key::kDeviceAllowNewUsers,
141                     POLICY_LEVEL_MANDATORY,
142                     POLICY_SCOPE_MACHINE,
143                     new base::FundamentalValue(
144                         container.allow_new_users()),
145                     NULL);
146     }
147   }
148
149   if (policy.has_user_whitelist()) {
150     const em::UserWhitelistProto& container(policy.user_whitelist());
151     base::ListValue* whitelist = new base::ListValue();
152     RepeatedPtrField<std::string>::const_iterator entry;
153     for (entry = container.user_whitelist().begin();
154          entry != container.user_whitelist().end();
155          ++entry) {
156       whitelist->Append(new base::StringValue(*entry));
157     }
158     policies->Set(key::kDeviceUserWhitelist,
159                   POLICY_LEVEL_MANDATORY,
160                   POLICY_SCOPE_MACHINE,
161                   whitelist,
162                   NULL);
163   }
164
165   if (policy.has_ephemeral_users_enabled()) {
166     const em::EphemeralUsersEnabledProto& container(
167         policy.ephemeral_users_enabled());
168     if (container.has_ephemeral_users_enabled()) {
169       policies->Set(key::kDeviceEphemeralUsersEnabled,
170                     POLICY_LEVEL_MANDATORY,
171                     POLICY_SCOPE_MACHINE,
172                     new base::FundamentalValue(
173                         container.ephemeral_users_enabled()),
174                     NULL);
175     }
176   }
177
178   if (policy.has_device_local_accounts()) {
179     const em::DeviceLocalAccountsProto& container(
180         policy.device_local_accounts());
181     const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
182         container.account();
183     scoped_ptr<base::ListValue> account_list(new base::ListValue());
184     RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
185     for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
186       scoped_ptr<base::DictionaryValue> entry_dict(
187           new base::DictionaryValue());
188       if (entry->has_type()) {
189         if (entry->has_account_id()) {
190           entry_dict->SetStringWithoutPathExpansion(
191               chromeos::kAccountsPrefDeviceLocalAccountsKeyId,
192               entry->account_id());
193         }
194         entry_dict->SetIntegerWithoutPathExpansion(
195             chromeos::kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
196         if (entry->kiosk_app().has_app_id()) {
197           entry_dict->SetStringWithoutPathExpansion(
198               chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
199               entry->kiosk_app().app_id());
200         }
201         if (entry->kiosk_app().has_update_url()) {
202           entry_dict->SetStringWithoutPathExpansion(
203               chromeos::kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
204               entry->kiosk_app().update_url());
205         }
206       } else if (entry->has_deprecated_public_session_id()) {
207         // Deprecated public session specification.
208         entry_dict->SetStringWithoutPathExpansion(
209             chromeos::kAccountsPrefDeviceLocalAccountsKeyId,
210             entry->deprecated_public_session_id());
211         entry_dict->SetIntegerWithoutPathExpansion(
212             chromeos::kAccountsPrefDeviceLocalAccountsKeyType,
213             DeviceLocalAccount::TYPE_PUBLIC_SESSION);
214       }
215       account_list->Append(entry_dict.release());
216     }
217     policies->Set(key::kDeviceLocalAccounts,
218                   POLICY_LEVEL_MANDATORY,
219                   POLICY_SCOPE_MACHINE,
220                   account_list.release(),
221                   NULL);
222     if (container.has_auto_login_id()) {
223       policies->Set(key::kDeviceLocalAccountAutoLoginId,
224                     POLICY_LEVEL_MANDATORY,
225                     POLICY_SCOPE_MACHINE,
226                     new base::StringValue(container.auto_login_id()),
227                     NULL);
228     }
229     if (container.has_auto_login_delay()) {
230       policies->Set(key::kDeviceLocalAccountAutoLoginDelay,
231                     POLICY_LEVEL_MANDATORY,
232                     POLICY_SCOPE_MACHINE,
233                     DecodeIntegerValue(container.auto_login_delay()).release(),
234                     NULL);
235     }
236     if (container.has_enable_auto_login_bailout()) {
237       policies->Set(key::kDeviceLocalAccountAutoLoginBailoutEnabled,
238                     POLICY_LEVEL_MANDATORY,
239                     POLICY_SCOPE_MACHINE,
240                     new base::FundamentalValue(
241                         container.enable_auto_login_bailout()),
242                     NULL);
243     }
244     if (container.has_prompt_for_network_when_offline()) {
245       policies->Set(key::kDeviceLocalAccountPromptForNetworkWhenOffline,
246                     POLICY_LEVEL_MANDATORY,
247                     POLICY_SCOPE_MACHINE,
248                     new base::FundamentalValue(
249                         container.prompt_for_network_when_offline()),
250                     NULL);
251     }
252   }
253
254   if (policy.has_supervised_users_settings()) {
255     const em::SupervisedUsersSettingsProto& container =
256         policy.supervised_users_settings();
257     if (container.has_supervised_users_enabled()) {
258       base::Value* value = new base::FundamentalValue(
259           container.supervised_users_enabled());
260       policies->Set(key::kSupervisedUsersEnabled,
261                     POLICY_LEVEL_MANDATORY,
262                     POLICY_SCOPE_MACHINE,
263                     value,
264                     NULL);
265     }
266   }
267
268   if (policy.has_saml_settings()) {
269     const em::SAMLSettingsProto& container(policy.saml_settings());
270     if (container.has_transfer_saml_cookies()) {
271       policies->Set(key::kDeviceTransferSAMLCookies,
272                     POLICY_LEVEL_MANDATORY,
273                     POLICY_SCOPE_MACHINE,
274                     new base::FundamentalValue(
275                         container.transfer_saml_cookies()),
276                     NULL);
277     }
278   }
279 }
280
281 void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy,
282                          PolicyMap* policies,
283                          EnterpriseInstallAttributes* install_attributes) {
284   // No policies if this is not KIOSK.
285   if (install_attributes->GetMode() != DEVICE_MODE_RETAIL_KIOSK)
286     return;
287
288   if (policy.has_forced_logout_timeouts()) {
289     const em::ForcedLogoutTimeoutsProto& container(
290         policy.forced_logout_timeouts());
291     if (container.has_idle_logout_timeout()) {
292       policies->Set(
293           key::kDeviceIdleLogoutTimeout,
294           POLICY_LEVEL_MANDATORY,
295           POLICY_SCOPE_MACHINE,
296           DecodeIntegerValue(container.idle_logout_timeout()).release(),
297           NULL);
298     }
299     if (container.has_idle_logout_warning_duration()) {
300       policies->Set(key::kDeviceIdleLogoutWarningDuration,
301                     POLICY_LEVEL_MANDATORY,
302                     POLICY_SCOPE_MACHINE,
303                     DecodeIntegerValue(container.idle_logout_warning_duration())
304                         .release(),
305                     NULL);
306     }
307   }
308
309   if (policy.has_login_screen_saver()) {
310     const em::ScreenSaverProto& container(
311         policy.login_screen_saver());
312     if (container.has_screen_saver_extension_id()) {
313       policies->Set(key::kDeviceLoginScreenSaverId,
314                     POLICY_LEVEL_MANDATORY,
315                     POLICY_SCOPE_MACHINE,
316                     new base::StringValue(
317                         container.screen_saver_extension_id()),
318                     NULL);
319     }
320     if (container.has_screen_saver_timeout()) {
321       policies->Set(
322           key::kDeviceLoginScreenSaverTimeout,
323           POLICY_LEVEL_MANDATORY,
324           POLICY_SCOPE_MACHINE,
325           DecodeIntegerValue(container.screen_saver_timeout()).release(),
326           NULL);
327     }
328   }
329
330   if (policy.has_app_pack()) {
331     const em::AppPackProto& container(policy.app_pack());
332     base::ListValue* app_pack_list = new base::ListValue();
333     for (int i = 0; i < container.app_pack_size(); ++i) {
334       const em::AppPackEntryProto& entry(container.app_pack(i));
335       if (entry.has_extension_id() && entry.has_update_url()) {
336         base::DictionaryValue* dict = new base::DictionaryValue();
337         dict->SetString(chromeos::kAppPackKeyExtensionId, entry.extension_id());
338         dict->SetString(chromeos::kAppPackKeyUpdateUrl, entry.update_url());
339         app_pack_list->Append(dict);
340       }
341     }
342     policies->Set(key::kDeviceAppPack,
343                   POLICY_LEVEL_MANDATORY,
344                   POLICY_SCOPE_MACHINE,
345                   app_pack_list,
346                   NULL);
347   }
348
349   if (policy.has_pinned_apps()) {
350     const em::PinnedAppsProto& container(policy.pinned_apps());
351     base::ListValue* pinned_apps_list = new base::ListValue();
352     for (int i = 0; i < container.app_id_size(); ++i) {
353       pinned_apps_list->Append(
354           new base::StringValue(container.app_id(i)));
355     }
356
357     policies->Set(key::kPinnedLauncherApps,
358                   POLICY_LEVEL_RECOMMENDED,
359                   POLICY_SCOPE_MACHINE,
360                   pinned_apps_list,
361                   NULL);
362   }
363 }
364
365 void DecodeNetworkPolicies(const em::ChromeDeviceSettingsProto& policy,
366                            PolicyMap* policies,
367                            EnterpriseInstallAttributes* install_attributes) {
368   if (policy.has_device_proxy_settings()) {
369     const em::DeviceProxySettingsProto& container(
370         policy.device_proxy_settings());
371     scoped_ptr<base::DictionaryValue> proxy_settings(new base::DictionaryValue);
372     if (container.has_proxy_mode())
373       proxy_settings->SetString(key::kProxyMode, container.proxy_mode());
374     if (container.has_proxy_server())
375       proxy_settings->SetString(key::kProxyServer, container.proxy_server());
376     if (container.has_proxy_pac_url())
377       proxy_settings->SetString(key::kProxyPacUrl, container.proxy_pac_url());
378     if (container.has_proxy_bypass_list()) {
379       proxy_settings->SetString(key::kProxyBypassList,
380                                 container.proxy_bypass_list());
381     }
382
383     // Figure out the level. Proxy policy is mandatory in kiosk mode.
384     PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
385     if (install_attributes->GetMode() == DEVICE_MODE_RETAIL_KIOSK)
386       level = POLICY_LEVEL_MANDATORY;
387
388     if (!proxy_settings->empty()) {
389       policies->Set(key::kProxySettings,
390                     level,
391                     POLICY_SCOPE_MACHINE,
392                     proxy_settings.release(),
393                     NULL);
394     }
395   }
396
397   if (policy.has_data_roaming_enabled()) {
398     const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled());
399     if (container.has_data_roaming_enabled()) {
400       policies->Set(key::kDeviceDataRoamingEnabled,
401                     POLICY_LEVEL_MANDATORY,
402                     POLICY_SCOPE_MACHINE,
403                     new base::FundamentalValue(
404                         container.data_roaming_enabled()),
405                     NULL);
406     }
407   }
408
409   if (policy.has_open_network_configuration() &&
410       policy.open_network_configuration().has_open_network_configuration()) {
411     std::string config(
412         policy.open_network_configuration().open_network_configuration());
413     policies->Set(key::kDeviceOpenNetworkConfiguration,
414                   POLICY_LEVEL_MANDATORY,
415                   POLICY_SCOPE_MACHINE,
416                   new base::StringValue(config),
417                   NULL);
418   }
419 }
420
421 void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy,
422                              PolicyMap* policies) {
423   if (policy.has_device_reporting()) {
424     const em::DeviceReportingProto& container(policy.device_reporting());
425     if (container.has_report_version_info()) {
426       policies->Set(key::kReportDeviceVersionInfo,
427                     POLICY_LEVEL_MANDATORY,
428                     POLICY_SCOPE_MACHINE,
429                     new base::FundamentalValue(
430                         container.report_version_info()),
431                     NULL);
432     }
433     if (container.has_report_activity_times()) {
434       policies->Set(key::kReportDeviceActivityTimes,
435                     POLICY_LEVEL_MANDATORY,
436                     POLICY_SCOPE_MACHINE,
437                     new base::FundamentalValue(
438                         container.report_activity_times()),
439                     NULL);
440     }
441     if (container.has_report_boot_mode()) {
442       policies->Set(key::kReportDeviceBootMode,
443                     POLICY_LEVEL_MANDATORY,
444                     POLICY_SCOPE_MACHINE,
445                     new base::FundamentalValue(
446                         container.report_boot_mode()),
447                     NULL);
448     }
449     if (container.has_report_location()) {
450       policies->Set(key::kReportDeviceLocation,
451                     POLICY_LEVEL_MANDATORY,
452                     POLICY_SCOPE_MACHINE,
453                     new base::FundamentalValue(
454                         container.report_location()),
455                     NULL);
456     }
457     if (container.has_report_network_interfaces()) {
458       policies->Set(key::kReportDeviceNetworkInterfaces,
459                     POLICY_LEVEL_MANDATORY,
460                     POLICY_SCOPE_MACHINE,
461                     new base::FundamentalValue(
462                         container.report_network_interfaces()),
463                     NULL);
464     }
465     if (container.has_report_users()) {
466       policies->Set(key::kReportDeviceUsers,
467                     POLICY_LEVEL_MANDATORY,
468                     POLICY_SCOPE_MACHINE,
469                     new base::FundamentalValue(container.report_users()),
470                     NULL);
471     }
472   }
473 }
474
475 void DecodeAutoUpdatePolicies(const em::ChromeDeviceSettingsProto& policy,
476                               PolicyMap* policies) {
477   if (policy.has_release_channel()) {
478     const em::ReleaseChannelProto& container(policy.release_channel());
479     if (container.has_release_channel()) {
480       std::string channel(container.release_channel());
481       policies->Set(key::kChromeOsReleaseChannel,
482                     POLICY_LEVEL_MANDATORY,
483                     POLICY_SCOPE_MACHINE,
484                     new base::StringValue(channel),
485                     NULL);
486       // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
487       // have to pass the channel in here, only ping the update engine to tell
488       // it to fetch the channel from the policy.
489       chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
490           SetChannel(channel, false);
491     }
492     if (container.has_release_channel_delegated()) {
493       policies->Set(key::kChromeOsReleaseChannelDelegated,
494                     POLICY_LEVEL_MANDATORY,
495                     POLICY_SCOPE_MACHINE,
496                     new base::FundamentalValue(
497                         container.release_channel_delegated()),
498                     NULL);
499     }
500   }
501
502   if (policy.has_auto_update_settings()) {
503     const em::AutoUpdateSettingsProto& container(policy.auto_update_settings());
504     if (container.has_update_disabled()) {
505       policies->Set(key::kDeviceAutoUpdateDisabled,
506                     POLICY_LEVEL_MANDATORY,
507                     POLICY_SCOPE_MACHINE,
508                     new base::FundamentalValue(
509                         container.update_disabled()),
510                     NULL);
511     }
512
513     if (container.has_target_version_prefix()) {
514       policies->Set(key::kDeviceTargetVersionPrefix,
515                     POLICY_LEVEL_MANDATORY,
516                     POLICY_SCOPE_MACHINE,
517                     new base::StringValue(
518                         container.target_version_prefix()),
519                     NULL);
520     }
521
522     // target_version_display_name is not actually a policy, but a display
523     // string for target_version_prefix, so we ignore it.
524
525     if (container.has_scatter_factor_in_seconds()) {
526       policies->Set(key::kDeviceUpdateScatterFactor,
527                     POLICY_LEVEL_MANDATORY,
528                     POLICY_SCOPE_MACHINE,
529                     new base::FundamentalValue(static_cast<int>(
530                         container.scatter_factor_in_seconds())),
531                     NULL);
532     }
533
534     if (container.allowed_connection_types_size()) {
535       base::ListValue* allowed_connection_types = new base::ListValue();
536       RepeatedField<int>::const_iterator entry;
537       for (entry = container.allowed_connection_types().begin();
538            entry != container.allowed_connection_types().end();
539            ++entry) {
540         base::Value* value = DecodeConnectionType(*entry);
541         if (value)
542           allowed_connection_types->Append(value);
543       }
544       policies->Set(key::kDeviceUpdateAllowedConnectionTypes,
545                     POLICY_LEVEL_MANDATORY,
546                     POLICY_SCOPE_MACHINE,
547                     allowed_connection_types,
548                     NULL);
549     }
550
551     if (container.has_http_downloads_enabled()) {
552       policies->Set(
553           key::kDeviceUpdateHttpDownloadsEnabled,
554           POLICY_LEVEL_MANDATORY,
555           POLICY_SCOPE_MACHINE,
556           new base::FundamentalValue(container.http_downloads_enabled()),
557           NULL);
558     }
559
560     if (container.has_reboot_after_update()) {
561       policies->Set(key::kRebootAfterUpdate,
562                     POLICY_LEVEL_MANDATORY,
563                     POLICY_SCOPE_MACHINE,
564                     new base::FundamentalValue(
565                         container.reboot_after_update()),
566                     NULL);
567     }
568
569     if (container.has_p2p_enabled()) {
570       policies->Set(key::kDeviceAutoUpdateP2PEnabled,
571                     POLICY_LEVEL_MANDATORY,
572                     POLICY_SCOPE_MACHINE,
573                     new base::FundamentalValue(container.p2p_enabled()),
574                     NULL);
575     }
576   }
577 }
578
579 void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy,
580                                  PolicyMap* policies) {
581   if (policy.has_accessibility_settings()) {
582     const em::AccessibilitySettingsProto&
583         container(policy.accessibility_settings());
584
585     if (container.has_login_screen_default_large_cursor_enabled()) {
586       policies->Set(
587           key::kDeviceLoginScreenDefaultLargeCursorEnabled,
588           POLICY_LEVEL_MANDATORY,
589           POLICY_SCOPE_MACHINE,
590           new base::FundamentalValue(
591               container.login_screen_default_large_cursor_enabled()),
592           NULL);
593     }
594
595     if (container.has_login_screen_default_spoken_feedback_enabled()) {
596       policies->Set(
597           key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
598           POLICY_LEVEL_MANDATORY,
599           POLICY_SCOPE_MACHINE,
600           new base::FundamentalValue(
601               container.login_screen_default_spoken_feedback_enabled()),
602           NULL);
603     }
604
605     if (container.has_login_screen_default_high_contrast_enabled()) {
606       policies->Set(
607           key::kDeviceLoginScreenDefaultHighContrastEnabled,
608           POLICY_LEVEL_MANDATORY,
609           POLICY_SCOPE_MACHINE,
610           new base::FundamentalValue(
611               container.login_screen_default_high_contrast_enabled()),
612           NULL);
613     }
614
615     if (container.has_login_screen_default_screen_magnifier_type()) {
616       policies->Set(
617           key::kDeviceLoginScreenDefaultScreenMagnifierType,
618           POLICY_LEVEL_MANDATORY,
619           POLICY_SCOPE_MACHINE,
620           DecodeIntegerValue(
621               container.login_screen_default_screen_magnifier_type()).release(),
622           NULL);
623     }
624     if (container.has_login_screen_default_virtual_keyboard_enabled()) {
625       policies->Set(
626           key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled,
627           POLICY_LEVEL_MANDATORY,
628           POLICY_SCOPE_MACHINE,
629           new base::FundamentalValue(
630               container.login_screen_default_virtual_keyboard_enabled()),
631           NULL);
632     }
633   }
634 }
635
636 void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
637                            PolicyMap* policies) {
638   if (policy.has_device_policy_refresh_rate()) {
639     const em::DevicePolicyRefreshRateProto& container(
640         policy.device_policy_refresh_rate());
641     if (container.has_device_policy_refresh_rate()) {
642       policies->Set(
643           key::kDevicePolicyRefreshRate,
644           POLICY_LEVEL_MANDATORY,
645           POLICY_SCOPE_MACHINE,
646           DecodeIntegerValue(container.device_policy_refresh_rate()).release(),
647           NULL);
648     }
649   }
650
651   if (policy.has_metrics_enabled()) {
652     const em::MetricsEnabledProto& container(policy.metrics_enabled());
653     if (container.has_metrics_enabled()) {
654       policies->Set(key::kDeviceMetricsReportingEnabled,
655                     POLICY_LEVEL_MANDATORY,
656                     POLICY_SCOPE_MACHINE,
657                     new base::FundamentalValue(
658                         container.metrics_enabled()),
659                     NULL);
660     }
661   }
662
663   if (policy.has_start_up_urls()) {
664     const em::StartUpUrlsProto& container(policy.start_up_urls());
665     base::ListValue* urls = new base::ListValue();
666     RepeatedPtrField<std::string>::const_iterator entry;
667     for (entry = container.start_up_urls().begin();
668          entry != container.start_up_urls().end();
669          ++entry) {
670       urls->Append(new base::StringValue(*entry));
671     }
672     policies->Set(key::kDeviceStartUpUrls,
673                   POLICY_LEVEL_MANDATORY,
674                   POLICY_SCOPE_MACHINE,
675                   urls,
676                   NULL);
677   }
678
679   if (policy.has_system_timezone()) {
680     if (policy.system_timezone().has_timezone()) {
681       policies->Set(key::kSystemTimezone,
682                     POLICY_LEVEL_MANDATORY,
683                     POLICY_SCOPE_MACHINE,
684                     new base::StringValue(
685                         policy.system_timezone().timezone()),
686                     NULL);
687     }
688   }
689
690   if (policy.has_use_24hour_clock()) {
691     if (policy.use_24hour_clock().has_use_24hour_clock()) {
692       policies->Set(key::kSystemUse24HourClock,
693                     POLICY_LEVEL_MANDATORY,
694                     POLICY_SCOPE_MACHINE,
695                     new base::FundamentalValue(
696                         policy.use_24hour_clock().use_24hour_clock()),
697                     NULL);
698     }
699   }
700
701   if (policy.has_allow_redeem_offers()) {
702     const em::AllowRedeemChromeOsRegistrationOffersProto& container(
703         policy.allow_redeem_offers());
704     if (container.has_allow_redeem_offers()) {
705       policies->Set(key::kDeviceAllowRedeemChromeOsRegistrationOffers,
706                     POLICY_LEVEL_MANDATORY,
707                     POLICY_SCOPE_MACHINE,
708                     new base::FundamentalValue(
709                         container.allow_redeem_offers()),
710                     NULL);
711     }
712   }
713
714   if (policy.has_uptime_limit()) {
715     const em::UptimeLimitProto& container(policy.uptime_limit());
716     if (container.has_uptime_limit()) {
717       policies->Set(key::kUptimeLimit,
718                     POLICY_LEVEL_MANDATORY,
719                     POLICY_SCOPE_MACHINE,
720                     DecodeIntegerValue(container.uptime_limit()).release(),
721                     NULL);
722     }
723   }
724
725   if (policy.has_start_up_flags()) {
726     const em::StartUpFlagsProto& container(policy.start_up_flags());
727     base::ListValue* flags = new base::ListValue();
728     RepeatedPtrField<std::string>::const_iterator entry;
729     for (entry = container.flags().begin();
730          entry != container.flags().end();
731          ++entry) {
732       flags->Append(new base::StringValue(*entry));
733     }
734     policies->Set(key::kDeviceStartUpFlags,
735                   POLICY_LEVEL_MANDATORY,
736                   POLICY_SCOPE_MACHINE,
737                   flags,
738                   NULL);
739   }
740
741   if (policy.has_variations_parameter()) {
742     if (policy.variations_parameter().has_parameter()) {
743       policies->Set(key::kDeviceVariationsRestrictParameter,
744                     POLICY_LEVEL_MANDATORY,
745                     POLICY_SCOPE_MACHINE,
746                     new base::StringValue(
747                         policy.variations_parameter().parameter()),
748                     NULL);
749     }
750   }
751
752   if (policy.has_attestation_settings()) {
753     if (policy.attestation_settings().has_attestation_enabled()) {
754       policies->Set(key::kAttestationEnabledForDevice,
755                     POLICY_LEVEL_MANDATORY,
756                     POLICY_SCOPE_MACHINE,
757                     new base::FundamentalValue(
758                         policy.attestation_settings().attestation_enabled()),
759                     NULL);
760     }
761     if (policy.attestation_settings().has_content_protection_enabled()) {
762       policies->Set(
763           key::kAttestationForContentProtectionEnabled,
764           POLICY_LEVEL_MANDATORY,
765           POLICY_SCOPE_MACHINE,
766           new base::FundamentalValue(
767               policy.attestation_settings().content_protection_enabled()),
768           NULL);
769     }
770   }
771
772   if (policy.has_login_screen_power_management()) {
773     const em::LoginScreenPowerManagementProto& container(
774         policy.login_screen_power_management());
775     if (container.has_login_screen_power_management()) {
776       scoped_ptr<base::Value> decoded_json;
777       decoded_json = DecodeJsonStringAndDropUnknownBySchema(
778           container.login_screen_power_management(),
779           key::kDeviceLoginScreenPowerManagement);
780       if (decoded_json) {
781         policies->Set(key::kDeviceLoginScreenPowerManagement,
782                       POLICY_LEVEL_MANDATORY,
783                       POLICY_SCOPE_MACHINE,
784                       decoded_json.release(),
785                       NULL);
786       }
787     }
788   }
789
790   if (policy.has_system_settings()) {
791     const em::SystemSettingsProto& container(policy.system_settings());
792     if (container.has_block_devmode()) {
793       policies->Set(
794           key::kDeviceBlockDevmode,
795           POLICY_LEVEL_MANDATORY,
796           POLICY_SCOPE_MACHINE,
797           new base::FundamentalValue(container.block_devmode()),
798           NULL);
799     }
800   }
801 }
802
803 }  // namespace
804
805 void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
806                         PolicyMap* policies,
807                         EnterpriseInstallAttributes* install_attributes) {
808   // TODO(achuith): Remove this once crbug.com/263527 is resolved.
809   VLOG(2) << "DecodeDevicePolicy " << policy.SerializeAsString();
810
811   // Decode the various groups of policies.
812   DecodeLoginPolicies(policy, policies);
813   DecodeKioskPolicies(policy, policies, install_attributes);
814   DecodeNetworkPolicies(policy, policies, install_attributes);
815   DecodeReportingPolicies(policy, policies);
816   DecodeAutoUpdatePolicies(policy, policies);
817   DecodeAccessibilityPolicies(policy, policies);
818   DecodeGenericPolicies(policy, policies);
819 }
820
821 }  // namespace policy