Upstream version 6.35.121.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       } else if (entry->has_deprecated_public_session_id()) {
202         // Deprecated public session specification.
203         entry_dict->SetStringWithoutPathExpansion(
204             chromeos::kAccountsPrefDeviceLocalAccountsKeyId,
205             entry->deprecated_public_session_id());
206         entry_dict->SetIntegerWithoutPathExpansion(
207             chromeos::kAccountsPrefDeviceLocalAccountsKeyType,
208             DeviceLocalAccount::TYPE_PUBLIC_SESSION);
209       }
210       account_list->Append(entry_dict.release());
211     }
212     policies->Set(key::kDeviceLocalAccounts,
213                   POLICY_LEVEL_MANDATORY,
214                   POLICY_SCOPE_MACHINE,
215                   account_list.release(),
216                   NULL);
217     if (container.has_auto_login_id()) {
218       policies->Set(key::kDeviceLocalAccountAutoLoginId,
219                     POLICY_LEVEL_MANDATORY,
220                     POLICY_SCOPE_MACHINE,
221                     new base::StringValue(container.auto_login_id()),
222                     NULL);
223     }
224     if (container.has_auto_login_delay()) {
225       policies->Set(key::kDeviceLocalAccountAutoLoginDelay,
226                     POLICY_LEVEL_MANDATORY,
227                     POLICY_SCOPE_MACHINE,
228                     DecodeIntegerValue(container.auto_login_delay()).release(),
229                     NULL);
230     }
231     if (container.has_enable_auto_login_bailout()) {
232       policies->Set(key::kDeviceLocalAccountAutoLoginBailoutEnabled,
233                     POLICY_LEVEL_MANDATORY,
234                     POLICY_SCOPE_MACHINE,
235                     new base::FundamentalValue(
236                         container.enable_auto_login_bailout()),
237                     NULL);
238     }
239     if (container.has_prompt_for_network_when_offline()) {
240       policies->Set(key::kDeviceLocalAccountPromptForNetworkWhenOffline,
241                     POLICY_LEVEL_MANDATORY,
242                     POLICY_SCOPE_MACHINE,
243                     new base::FundamentalValue(
244                         container.prompt_for_network_when_offline()),
245                     NULL);
246     }
247   }
248
249   if (policy.has_supervised_users_settings()) {
250     const em::SupervisedUsersSettingsProto& container =
251         policy.supervised_users_settings();
252     if (container.has_supervised_users_enabled()) {
253       base::Value* value = new base::FundamentalValue(
254           container.supervised_users_enabled());
255       policies->Set(key::kSupervisedUsersEnabled,
256                     POLICY_LEVEL_MANDATORY,
257                     POLICY_SCOPE_MACHINE,
258                     value,
259                     NULL);
260     }
261   }
262 }
263
264 void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy,
265                          PolicyMap* policies,
266                          EnterpriseInstallAttributes* install_attributes) {
267   // No policies if this is not KIOSK.
268   if (install_attributes->GetMode() != DEVICE_MODE_RETAIL_KIOSK)
269     return;
270
271   if (policy.has_forced_logout_timeouts()) {
272     const em::ForcedLogoutTimeoutsProto& container(
273         policy.forced_logout_timeouts());
274     if (container.has_idle_logout_timeout()) {
275       policies->Set(
276           key::kDeviceIdleLogoutTimeout,
277           POLICY_LEVEL_MANDATORY,
278           POLICY_SCOPE_MACHINE,
279           DecodeIntegerValue(container.idle_logout_timeout()).release(),
280           NULL);
281     }
282     if (container.has_idle_logout_warning_duration()) {
283       policies->Set(key::kDeviceIdleLogoutWarningDuration,
284                     POLICY_LEVEL_MANDATORY,
285                     POLICY_SCOPE_MACHINE,
286                     DecodeIntegerValue(container.idle_logout_warning_duration())
287                         .release(),
288                     NULL);
289     }
290   }
291
292   if (policy.has_login_screen_saver()) {
293     const em::ScreenSaverProto& container(
294         policy.login_screen_saver());
295     if (container.has_screen_saver_extension_id()) {
296       policies->Set(key::kDeviceLoginScreenSaverId,
297                     POLICY_LEVEL_MANDATORY,
298                     POLICY_SCOPE_MACHINE,
299                     new base::StringValue(
300                         container.screen_saver_extension_id()),
301                     NULL);
302     }
303     if (container.has_screen_saver_timeout()) {
304       policies->Set(
305           key::kDeviceLoginScreenSaverTimeout,
306           POLICY_LEVEL_MANDATORY,
307           POLICY_SCOPE_MACHINE,
308           DecodeIntegerValue(container.screen_saver_timeout()).release(),
309           NULL);
310     }
311   }
312
313   if (policy.has_app_pack()) {
314     const em::AppPackProto& container(policy.app_pack());
315     base::ListValue* app_pack_list = new base::ListValue();
316     for (int i = 0; i < container.app_pack_size(); ++i) {
317       const em::AppPackEntryProto& entry(container.app_pack(i));
318       if (entry.has_extension_id() && entry.has_update_url()) {
319         base::DictionaryValue* dict = new base::DictionaryValue();
320         dict->SetString(chromeos::kAppPackKeyExtensionId, entry.extension_id());
321         dict->SetString(chromeos::kAppPackKeyUpdateUrl, entry.update_url());
322         app_pack_list->Append(dict);
323       }
324     }
325     policies->Set(key::kDeviceAppPack,
326                   POLICY_LEVEL_MANDATORY,
327                   POLICY_SCOPE_MACHINE,
328                   app_pack_list,
329                   NULL);
330   }
331
332   if (policy.has_pinned_apps()) {
333     const em::PinnedAppsProto& container(policy.pinned_apps());
334     base::ListValue* pinned_apps_list = new base::ListValue();
335     for (int i = 0; i < container.app_id_size(); ++i) {
336       pinned_apps_list->Append(
337           new base::StringValue(container.app_id(i)));
338     }
339
340     policies->Set(key::kPinnedLauncherApps,
341                   POLICY_LEVEL_RECOMMENDED,
342                   POLICY_SCOPE_MACHINE,
343                   pinned_apps_list,
344                   NULL);
345   }
346 }
347
348 void DecodeNetworkPolicies(const em::ChromeDeviceSettingsProto& policy,
349                            PolicyMap* policies,
350                            EnterpriseInstallAttributes* install_attributes) {
351   if (policy.has_device_proxy_settings()) {
352     const em::DeviceProxySettingsProto& container(
353         policy.device_proxy_settings());
354     scoped_ptr<base::DictionaryValue> proxy_settings(new base::DictionaryValue);
355     if (container.has_proxy_mode())
356       proxy_settings->SetString(key::kProxyMode, container.proxy_mode());
357     if (container.has_proxy_server())
358       proxy_settings->SetString(key::kProxyServer, container.proxy_server());
359     if (container.has_proxy_pac_url())
360       proxy_settings->SetString(key::kProxyPacUrl, container.proxy_pac_url());
361     if (container.has_proxy_bypass_list()) {
362       proxy_settings->SetString(key::kProxyBypassList,
363                                 container.proxy_bypass_list());
364     }
365
366     // Figure out the level. Proxy policy is mandatory in kiosk mode.
367     PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
368     if (install_attributes->GetMode() == DEVICE_MODE_RETAIL_KIOSK)
369       level = POLICY_LEVEL_MANDATORY;
370
371     if (!proxy_settings->empty()) {
372       policies->Set(key::kProxySettings,
373                     level,
374                     POLICY_SCOPE_MACHINE,
375                     proxy_settings.release(),
376                     NULL);
377     }
378   }
379
380   if (policy.has_data_roaming_enabled()) {
381     const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled());
382     if (container.has_data_roaming_enabled()) {
383       policies->Set(key::kDeviceDataRoamingEnabled,
384                     POLICY_LEVEL_MANDATORY,
385                     POLICY_SCOPE_MACHINE,
386                     new base::FundamentalValue(
387                         container.data_roaming_enabled()),
388                     NULL);
389     }
390   }
391
392   if (policy.has_open_network_configuration() &&
393       policy.open_network_configuration().has_open_network_configuration()) {
394     std::string config(
395         policy.open_network_configuration().open_network_configuration());
396     policies->Set(key::kDeviceOpenNetworkConfiguration,
397                   POLICY_LEVEL_MANDATORY,
398                   POLICY_SCOPE_MACHINE,
399                   new base::StringValue(config),
400                   NULL);
401   }
402 }
403
404 void DecodeReportingPolicies(const em::ChromeDeviceSettingsProto& policy,
405                              PolicyMap* policies) {
406   if (policy.has_device_reporting()) {
407     const em::DeviceReportingProto& container(policy.device_reporting());
408     if (container.has_report_version_info()) {
409       policies->Set(key::kReportDeviceVersionInfo,
410                     POLICY_LEVEL_MANDATORY,
411                     POLICY_SCOPE_MACHINE,
412                     new base::FundamentalValue(
413                         container.report_version_info()),
414                     NULL);
415     }
416     if (container.has_report_activity_times()) {
417       policies->Set(key::kReportDeviceActivityTimes,
418                     POLICY_LEVEL_MANDATORY,
419                     POLICY_SCOPE_MACHINE,
420                     new base::FundamentalValue(
421                         container.report_activity_times()),
422                     NULL);
423     }
424     if (container.has_report_boot_mode()) {
425       policies->Set(key::kReportDeviceBootMode,
426                     POLICY_LEVEL_MANDATORY,
427                     POLICY_SCOPE_MACHINE,
428                     new base::FundamentalValue(
429                         container.report_boot_mode()),
430                     NULL);
431     }
432     if (container.has_report_location()) {
433       policies->Set(key::kReportDeviceLocation,
434                     POLICY_LEVEL_MANDATORY,
435                     POLICY_SCOPE_MACHINE,
436                     new base::FundamentalValue(
437                         container.report_location()),
438                     NULL);
439     }
440     if (container.has_report_network_interfaces()) {
441       policies->Set(key::kReportDeviceNetworkInterfaces,
442                     POLICY_LEVEL_MANDATORY,
443                     POLICY_SCOPE_MACHINE,
444                     new base::FundamentalValue(
445                         container.report_network_interfaces()),
446                     NULL);
447     }
448     if (container.has_report_users()) {
449       policies->Set(key::kReportDeviceUsers,
450                     POLICY_LEVEL_MANDATORY,
451                     POLICY_SCOPE_MACHINE,
452                     new base::FundamentalValue(container.report_users()),
453                     NULL);
454     }
455   }
456 }
457
458 void DecodeAutoUpdatePolicies(const em::ChromeDeviceSettingsProto& policy,
459                               PolicyMap* policies) {
460   if (policy.has_release_channel()) {
461     const em::ReleaseChannelProto& container(policy.release_channel());
462     if (container.has_release_channel()) {
463       std::string channel(container.release_channel());
464       policies->Set(key::kChromeOsReleaseChannel,
465                     POLICY_LEVEL_MANDATORY,
466                     POLICY_SCOPE_MACHINE,
467                     new base::StringValue(channel),
468                     NULL);
469       // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
470       // have to pass the channel in here, only ping the update engine to tell
471       // it to fetch the channel from the policy.
472       chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
473           SetChannel(channel, false);
474     }
475     if (container.has_release_channel_delegated()) {
476       policies->Set(key::kChromeOsReleaseChannelDelegated,
477                     POLICY_LEVEL_MANDATORY,
478                     POLICY_SCOPE_MACHINE,
479                     new base::FundamentalValue(
480                         container.release_channel_delegated()),
481                     NULL);
482     }
483   }
484
485   if (policy.has_auto_update_settings()) {
486     const em::AutoUpdateSettingsProto& container(policy.auto_update_settings());
487     if (container.has_update_disabled()) {
488       policies->Set(key::kDeviceAutoUpdateDisabled,
489                     POLICY_LEVEL_MANDATORY,
490                     POLICY_SCOPE_MACHINE,
491                     new base::FundamentalValue(
492                         container.update_disabled()),
493                     NULL);
494     }
495
496     if (container.has_target_version_prefix()) {
497       policies->Set(key::kDeviceTargetVersionPrefix,
498                     POLICY_LEVEL_MANDATORY,
499                     POLICY_SCOPE_MACHINE,
500                     new base::StringValue(
501                         container.target_version_prefix()),
502                     NULL);
503     }
504
505     // target_version_display_name is not actually a policy, but a display
506     // string for target_version_prefix, so we ignore it.
507
508     if (container.has_scatter_factor_in_seconds()) {
509       policies->Set(key::kDeviceUpdateScatterFactor,
510                     POLICY_LEVEL_MANDATORY,
511                     POLICY_SCOPE_MACHINE,
512                     new base::FundamentalValue(static_cast<int>(
513                         container.scatter_factor_in_seconds())),
514                     NULL);
515     }
516
517     if (container.allowed_connection_types_size()) {
518       base::ListValue* allowed_connection_types = new base::ListValue();
519       RepeatedField<int>::const_iterator entry;
520       for (entry = container.allowed_connection_types().begin();
521            entry != container.allowed_connection_types().end();
522            ++entry) {
523         base::Value* value = DecodeConnectionType(*entry);
524         if (value)
525           allowed_connection_types->Append(value);
526       }
527       policies->Set(key::kDeviceUpdateAllowedConnectionTypes,
528                     POLICY_LEVEL_MANDATORY,
529                     POLICY_SCOPE_MACHINE,
530                     allowed_connection_types,
531                     NULL);
532     }
533
534     if (container.has_http_downloads_enabled()) {
535       policies->Set(
536           key::kDeviceUpdateHttpDownloadsEnabled,
537           POLICY_LEVEL_MANDATORY,
538           POLICY_SCOPE_MACHINE,
539           new base::FundamentalValue(container.http_downloads_enabled()),
540           NULL);
541     }
542
543     if (container.has_reboot_after_update()) {
544       policies->Set(key::kRebootAfterUpdate,
545                     POLICY_LEVEL_MANDATORY,
546                     POLICY_SCOPE_MACHINE,
547                     new base::FundamentalValue(
548                         container.reboot_after_update()),
549                     NULL);
550     }
551
552     if (container.has_p2p_enabled()) {
553       policies->Set(key::kDeviceAutoUpdateP2PEnabled,
554                     POLICY_LEVEL_MANDATORY,
555                     POLICY_SCOPE_MACHINE,
556                     new base::FundamentalValue(container.p2p_enabled()),
557                     NULL);
558     }
559   }
560 }
561
562 void DecodeAccessibilityPolicies(const em::ChromeDeviceSettingsProto& policy,
563                                  PolicyMap* policies) {
564   if (policy.has_accessibility_settings()) {
565     const em::AccessibilitySettingsProto&
566         container(policy.accessibility_settings());
567
568     if (container.has_login_screen_default_large_cursor_enabled()) {
569       policies->Set(
570           key::kDeviceLoginScreenDefaultLargeCursorEnabled,
571           POLICY_LEVEL_MANDATORY,
572           POLICY_SCOPE_MACHINE,
573           new base::FundamentalValue(
574               container.login_screen_default_large_cursor_enabled()),
575           NULL);
576     }
577
578     if (container.has_login_screen_default_spoken_feedback_enabled()) {
579       policies->Set(
580           key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
581           POLICY_LEVEL_MANDATORY,
582           POLICY_SCOPE_MACHINE,
583           new base::FundamentalValue(
584               container.login_screen_default_spoken_feedback_enabled()),
585           NULL);
586     }
587
588     if (container.has_login_screen_default_high_contrast_enabled()) {
589       policies->Set(
590           key::kDeviceLoginScreenDefaultHighContrastEnabled,
591           POLICY_LEVEL_MANDATORY,
592           POLICY_SCOPE_MACHINE,
593           new base::FundamentalValue(
594               container.login_screen_default_high_contrast_enabled()),
595           NULL);
596     }
597
598     if (container.has_login_screen_default_screen_magnifier_type()) {
599       policies->Set(
600           key::kDeviceLoginScreenDefaultScreenMagnifierType,
601           POLICY_LEVEL_MANDATORY,
602           POLICY_SCOPE_MACHINE,
603           DecodeIntegerValue(
604               container.login_screen_default_screen_magnifier_type()).release(),
605           NULL);
606     }
607     if (container.has_login_screen_default_virtual_keyboard_enabled()) {
608       policies->Set(
609           key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled,
610           POLICY_LEVEL_MANDATORY,
611           POLICY_SCOPE_MACHINE,
612           new base::FundamentalValue(
613               container.login_screen_default_virtual_keyboard_enabled()),
614           NULL);
615     }
616   }
617 }
618
619 void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
620                            PolicyMap* policies) {
621   if (policy.has_device_policy_refresh_rate()) {
622     const em::DevicePolicyRefreshRateProto& container(
623         policy.device_policy_refresh_rate());
624     if (container.has_device_policy_refresh_rate()) {
625       policies->Set(
626           key::kDevicePolicyRefreshRate,
627           POLICY_LEVEL_MANDATORY,
628           POLICY_SCOPE_MACHINE,
629           DecodeIntegerValue(container.device_policy_refresh_rate()).release(),
630           NULL);
631     }
632   }
633
634   if (policy.has_metrics_enabled()) {
635     const em::MetricsEnabledProto& container(policy.metrics_enabled());
636     if (container.has_metrics_enabled()) {
637       policies->Set(key::kDeviceMetricsReportingEnabled,
638                     POLICY_LEVEL_MANDATORY,
639                     POLICY_SCOPE_MACHINE,
640                     new base::FundamentalValue(
641                         container.metrics_enabled()),
642                     NULL);
643     }
644   }
645
646   if (policy.has_start_up_urls()) {
647     const em::StartUpUrlsProto& container(policy.start_up_urls());
648     base::ListValue* urls = new base::ListValue();
649     RepeatedPtrField<std::string>::const_iterator entry;
650     for (entry = container.start_up_urls().begin();
651          entry != container.start_up_urls().end();
652          ++entry) {
653       urls->Append(new base::StringValue(*entry));
654     }
655     policies->Set(key::kDeviceStartUpUrls,
656                   POLICY_LEVEL_MANDATORY,
657                   POLICY_SCOPE_MACHINE,
658                   urls,
659                   NULL);
660   }
661
662   if (policy.has_system_timezone()) {
663     if (policy.system_timezone().has_timezone()) {
664       policies->Set(key::kSystemTimezone,
665                     POLICY_LEVEL_MANDATORY,
666                     POLICY_SCOPE_MACHINE,
667                     new base::StringValue(
668                         policy.system_timezone().timezone()),
669                     NULL);
670     }
671   }
672
673   if (policy.has_use_24hour_clock()) {
674     if (policy.use_24hour_clock().has_use_24hour_clock()) {
675       policies->Set(key::kSystemUse24HourClock,
676                     POLICY_LEVEL_MANDATORY,
677                     POLICY_SCOPE_MACHINE,
678                     new base::FundamentalValue(
679                         policy.use_24hour_clock().use_24hour_clock()),
680                     NULL);
681     }
682   }
683
684   if (policy.has_allow_redeem_offers()) {
685     const em::AllowRedeemChromeOsRegistrationOffersProto& container(
686         policy.allow_redeem_offers());
687     if (container.has_allow_redeem_offers()) {
688       policies->Set(key::kDeviceAllowRedeemChromeOsRegistrationOffers,
689                     POLICY_LEVEL_MANDATORY,
690                     POLICY_SCOPE_MACHINE,
691                     new base::FundamentalValue(
692                         container.allow_redeem_offers()),
693                     NULL);
694     }
695   }
696
697   if (policy.has_uptime_limit()) {
698     const em::UptimeLimitProto& container(policy.uptime_limit());
699     if (container.has_uptime_limit()) {
700       policies->Set(key::kUptimeLimit,
701                     POLICY_LEVEL_MANDATORY,
702                     POLICY_SCOPE_MACHINE,
703                     DecodeIntegerValue(container.uptime_limit()).release(),
704                     NULL);
705     }
706   }
707
708   if (policy.has_start_up_flags()) {
709     const em::StartUpFlagsProto& container(policy.start_up_flags());
710     base::ListValue* flags = new base::ListValue();
711     RepeatedPtrField<std::string>::const_iterator entry;
712     for (entry = container.flags().begin();
713          entry != container.flags().end();
714          ++entry) {
715       flags->Append(new base::StringValue(*entry));
716     }
717     policies->Set(key::kDeviceStartUpFlags,
718                   POLICY_LEVEL_MANDATORY,
719                   POLICY_SCOPE_MACHINE,
720                   flags,
721                   NULL);
722   }
723
724   if (policy.has_variations_parameter()) {
725     if (policy.variations_parameter().has_parameter()) {
726       policies->Set(key::kDeviceVariationsRestrictParameter,
727                     POLICY_LEVEL_MANDATORY,
728                     POLICY_SCOPE_MACHINE,
729                     new base::StringValue(
730                         policy.variations_parameter().parameter()),
731                     NULL);
732     }
733   }
734
735   if (policy.has_attestation_settings()) {
736     if (policy.attestation_settings().has_attestation_enabled()) {
737       policies->Set(key::kAttestationEnabledForDevice,
738                     POLICY_LEVEL_MANDATORY,
739                     POLICY_SCOPE_MACHINE,
740                     new base::FundamentalValue(
741                         policy.attestation_settings().attestation_enabled()),
742                     NULL);
743     }
744     if (policy.attestation_settings().has_content_protection_enabled()) {
745       policies->Set(
746           key::kAttestationForContentProtectionEnabled,
747           POLICY_LEVEL_MANDATORY,
748           POLICY_SCOPE_MACHINE,
749           new base::FundamentalValue(
750               policy.attestation_settings().content_protection_enabled()),
751           NULL);
752     }
753   }
754
755   if (policy.has_login_screen_power_management()) {
756     const em::LoginScreenPowerManagementProto& container(
757         policy.login_screen_power_management());
758     if (container.has_login_screen_power_management()) {
759       scoped_ptr<base::Value> decoded_json;
760       decoded_json = DecodeJsonStringAndDropUnknownBySchema(
761           container.login_screen_power_management(),
762           key::kDeviceLoginScreenPowerManagement);
763       if (decoded_json) {
764         policies->Set(key::kDeviceLoginScreenPowerManagement,
765                       POLICY_LEVEL_MANDATORY,
766                       POLICY_SCOPE_MACHINE,
767                       decoded_json.release(),
768                       NULL);
769       }
770     }
771   }
772   if (policy.has_auto_clean_up_settings()) {
773     const em::AutoCleanupSettigsProto& container(
774         policy.auto_clean_up_settings());
775     if (container.has_clean_up_strategy()) {
776       policies->Set(key::kAutoCleanUpStrategy,
777                     POLICY_LEVEL_MANDATORY,
778                     POLICY_SCOPE_MACHINE,
779                     new base::StringValue(
780                         container.clean_up_strategy()),
781                     NULL);
782     }
783   }
784 }
785
786 }  // namespace
787
788 void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
789                         PolicyMap* policies,
790                         EnterpriseInstallAttributes* install_attributes) {
791   // TODO(achuith): Remove this once crbug.com/263527 is resolved.
792   VLOG(2) << "DecodeDevicePolicy " << policy.SerializeAsString();
793
794   // Decode the various groups of policies.
795   DecodeLoginPolicies(policy, policies);
796   DecodeKioskPolicies(policy, policies, install_attributes);
797   DecodeNetworkPolicies(policy, policies, install_attributes);
798   DecodeReportingPolicies(policy, policies);
799   DecodeAutoUpdatePolicies(policy, policies);
800   DecodeAccessibilityPolicies(policy, policies);
801   DecodeGenericPolicies(policy, policies);
802 }
803
804 }  // namespace policy