Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: chrome/browser/policy/device_policy_cache.cc

Issue 10885015: Implement new-style CloudPolicyStore for Chrome OS device policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/device_policy_cache.h" 5 #include "chrome/browser/policy/device_policy_cache.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
Joao da Silva 2012/08/28 19:56:57 nit: vector and limits not used
Mattias Nissler (ping if slow) 2012/08/31 14:13:18 Done.
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/values.h" 17 #include "base/values.h"
18 #include "chrome/browser/policy/app_pack_updater.h"
19 #include "chrome/browser/policy/cloud_policy_data_store.h" 18 #include "chrome/browser/policy/cloud_policy_data_store.h"
19 #include "chrome/browser/policy/device_policy_decoder_chromeos.h"
20 #include "chrome/browser/policy/enterprise_install_attributes.h" 20 #include "chrome/browser/policy/enterprise_install_attributes.h"
21 #include "chrome/browser/policy/enterprise_metrics.h" 21 #include "chrome/browser/policy/enterprise_metrics.h"
22 #include "chrome/browser/policy/policy_map.h" 22 #include "chrome/browser/policy/policy_map.h"
23 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" 23 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
24 #include "chrome/browser/policy/proto/device_management_backend.pb.h" 24 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
25 #include "chrome/browser/policy/proto/device_management_local.pb.h" 25 #include "chrome/browser/policy/proto/device_management_local.pb.h"
26 #include "chrome/common/net/gaia/gaia_auth_util.h" 26 #include "chrome/common/net/gaia/gaia_auth_util.h"
27 #include "chromeos/dbus/dbus_thread_manager.h"
28 #include "chromeos/dbus/update_engine_client.h"
29 #include "policy/policy_constants.h"
30 #include "third_party/cros_system_api/dbus/service_constants.h"
31
32 using google::protobuf::RepeatedField;
33 using google::protobuf::RepeatedPtrField;
34 27
35 namespace em = enterprise_management; 28 namespace em = enterprise_management;
36 29
37 namespace {
38
39 // Decodes a protobuf integer to an IntegerValue. The caller assumes ownership
40 // of the return Value*. Returns NULL in case the input value is out of bounds.
41 Value* DecodeIntegerValue(google::protobuf::int64 value) {
42 if (value < std::numeric_limits<int>::min() ||
43 value > std::numeric_limits<int>::max()) {
44 LOG(WARNING) << "Integer value " << value
45 << " out of numeric limits, ignoring.";
46 return NULL;
47 }
48
49 return Value::CreateIntegerValue(static_cast<int>(value));
50 }
51
52 Value* DecodeConnectionType(int value) {
53 static const char* const kConnectionTypes[] = {
54 flimflam::kTypeEthernet,
55 flimflam::kTypeWifi,
56 flimflam::kTypeWimax,
57 flimflam::kTypeBluetooth,
58 flimflam::kTypeCellular,
59 };
60
61 if (value < 0 || value >= static_cast<int>(arraysize(kConnectionTypes)))
62 return NULL;
63
64 return Value::CreateStringValue(kConnectionTypes[value]);
65 }
66
67 } // namespace
68
69 namespace policy { 30 namespace policy {
70 31
71 DevicePolicyCache::DevicePolicyCache( 32 DevicePolicyCache::DevicePolicyCache(
72 CloudPolicyDataStore* data_store, 33 CloudPolicyDataStore* data_store,
73 EnterpriseInstallAttributes* install_attributes) 34 EnterpriseInstallAttributes* install_attributes)
74 : data_store_(data_store), 35 : data_store_(data_store),
75 install_attributes_(install_attributes), 36 install_attributes_(install_attributes),
76 device_settings_service_(chromeos::DeviceSettingsService::Get()), 37 device_settings_service_(chromeos::DeviceSettingsService::Get()),
77 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 38 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
78 policy_fetch_pending_(false) { 39 policy_fetch_pending_(false) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR, 96 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
136 CloudPolicySubsystem::POLICY_LOCAL_ERROR); 97 CloudPolicySubsystem::POLICY_LOCAL_ERROR);
137 return false; 98 return false;
138 } 99 }
139 100
140 set_last_policy_refresh_time(base::Time::NowFromSystemTime()); 101 set_last_policy_refresh_time(base::Time::NowFromSystemTime());
141 102
142 // Start a store operation. 103 // Start a store operation.
143 policy_fetch_pending_ = true; 104 policy_fetch_pending_ = true;
144 device_settings_service_->Store( 105 device_settings_service_->Store(
145 policy.SerializeAsString(), 106 scoped_ptr<em::PolicyFetchResponse>(new em::PolicyFetchResponse(policy)),
Joao da Silva 2012/08/28 19:56:57 #include "base/memory/scoped_ptr.h"
Mattias Nissler (ping if slow) 2012/08/31 14:13:18 Done.
146 base::Bind(&DevicePolicyCache::PolicyStoreOpCompleted, 107 base::Bind(&DevicePolicyCache::PolicyStoreOpCompleted,
147 weak_ptr_factory_.GetWeakPtr())); 108 weak_ptr_factory_.GetWeakPtr()));
148 return true; 109 return true;
149 } 110 }
150 111
151 void DevicePolicyCache::SetUnmanaged() { 112 void DevicePolicyCache::SetUnmanaged() {
152 LOG(WARNING) << "Tried to set DevicePolicyCache to 'unmanaged'!"; 113 LOG(WARNING) << "Tried to set DevicePolicyCache to 'unmanaged'!";
153 // This is not supported for DevicePolicyCache. 114 // This is not supported for DevicePolicyCache.
154 } 115 }
155 116
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } 165 }
205 } 166 }
206 167
207 bool DevicePolicyCache::DecodePolicyData(const em::PolicyData& policy_data, 168 bool DevicePolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
208 PolicyMap* policies) { 169 PolicyMap* policies) {
209 em::ChromeDeviceSettingsProto policy; 170 em::ChromeDeviceSettingsProto policy;
210 if (!policy.ParseFromString(policy_data.policy_value())) { 171 if (!policy.ParseFromString(policy_data.policy_value())) {
211 LOG(WARNING) << "Failed to parse ChromeDeviceSettingsProto."; 172 LOG(WARNING) << "Failed to parse ChromeDeviceSettingsProto.";
212 return false; 173 return false;
213 } 174 }
214 DecodeDevicePolicy(policy, policies); 175 DecodeDevicePolicy(policy, policies, install_attributes_);
215 return true; 176 return true;
216 } 177 }
217 178
218 void DevicePolicyCache::PolicyStoreOpCompleted() { 179 void DevicePolicyCache::PolicyStoreOpCompleted() {
219 DCHECK(CalledOnValidThread()); 180 DCHECK(CalledOnValidThread());
220 chromeos::DeviceSettingsService::Status status = 181 chromeos::DeviceSettingsService::Status status =
221 device_settings_service_->status(); 182 device_settings_service_->status();
222 if (status != chromeos::DeviceSettingsService::STORE_SUCCESS) { 183 if (status != chromeos::DeviceSettingsService::STORE_SUCCESS) {
223 UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyStoreFailed, 184 UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyStoreFailed,
224 kMetricPolicySize); 185 kMetricPolicySize);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 SetReady(); 257 SetReady();
297 } 258 }
298 259
299 void DevicePolicyCache::CheckFetchingDone() { 260 void DevicePolicyCache::CheckFetchingDone() {
300 if (policy_fetch_pending_) { 261 if (policy_fetch_pending_) {
301 CloudPolicyCacheBase::SetFetchingDone(); 262 CloudPolicyCacheBase::SetFetchingDone();
302 policy_fetch_pending_ = false; 263 policy_fetch_pending_ = false;
303 } 264 }
304 } 265 }
305 266
306 void DevicePolicyCache::DecodeDevicePolicy(
307 const em::ChromeDeviceSettingsProto& policy,
308 PolicyMap* policies) {
309 // Decode the various groups of policies.
310 DecodeLoginPolicies(policy, policies);
311 DecodeKioskPolicies(policy, policies, install_attributes_);
312 DecodeNetworkPolicies(policy, policies, install_attributes_);
313 DecodeReportingPolicies(policy, policies);
314 DecodeAutoUpdatePolicies(policy, policies);
315 DecodeGenericPolicies(policy, policies);
316 }
317
318 // static
319 void DevicePolicyCache::DecodeLoginPolicies(
320 const em::ChromeDeviceSettingsProto& policy,
321 PolicyMap* policies) {
322 if (policy.has_guest_mode_enabled()) {
323 const em::GuestModeEnabledProto& container(policy.guest_mode_enabled());
324 if (container.has_guest_mode_enabled()) {
325 policies->Set(key::kDeviceGuestModeEnabled,
326 POLICY_LEVEL_MANDATORY,
327 POLICY_SCOPE_MACHINE,
328 Value::CreateBooleanValue(container.guest_mode_enabled()));
329 }
330 }
331
332 if (policy.has_show_user_names()) {
333 const em::ShowUserNamesOnSigninProto& container(policy.show_user_names());
334 if (container.has_show_user_names()) {
335 policies->Set(key::kDeviceShowUserNamesOnSignin,
336 POLICY_LEVEL_MANDATORY,
337 POLICY_SCOPE_MACHINE,
338 Value::CreateBooleanValue(container.show_user_names()));
339 }
340 }
341
342 if (policy.has_allow_new_users()) {
343 const em::AllowNewUsersProto& container(policy.allow_new_users());
344 if (container.has_allow_new_users()) {
345 policies->Set(key::kDeviceAllowNewUsers,
346 POLICY_LEVEL_MANDATORY,
347 POLICY_SCOPE_MACHINE,
348 Value::CreateBooleanValue(container.allow_new_users()));
349 }
350 }
351
352 if (policy.has_user_whitelist()) {
353 const em::UserWhitelistProto& container(policy.user_whitelist());
354 if (container.user_whitelist_size()) {
355 ListValue* whitelist = new ListValue();
356 RepeatedPtrField<std::string>::const_iterator entry;
357 for (entry = container.user_whitelist().begin();
358 entry != container.user_whitelist().end();
359 ++entry) {
360 whitelist->Append(Value::CreateStringValue(*entry));
361 }
362 policies->Set(key::kDeviceUserWhitelist,
363 POLICY_LEVEL_MANDATORY,
364 POLICY_SCOPE_MACHINE,
365 whitelist);
366 }
367 }
368
369 if (policy.has_ephemeral_users_enabled()) {
370 const em::EphemeralUsersEnabledProto& container(
371 policy.ephemeral_users_enabled());
372 if (container.has_ephemeral_users_enabled()) {
373 policies->Set(key::kDeviceEphemeralUsersEnabled,
374 POLICY_LEVEL_MANDATORY,
375 POLICY_SCOPE_MACHINE,
376 Value::CreateBooleanValue(
377 container.ephemeral_users_enabled()));
378 }
379 }
380 }
381
382 // static
383 void DevicePolicyCache::DecodeKioskPolicies(
384 const em::ChromeDeviceSettingsProto& policy,
385 PolicyMap* policies,
386 EnterpriseInstallAttributes* install_attributes) {
387 // No policies if this is not KIOSK.
388 if (install_attributes->GetMode() != DEVICE_MODE_KIOSK)
389 return;
390
391 if (policy.has_forced_logout_timeouts()) {
392 const em::ForcedLogoutTimeoutsProto& container(
393 policy.forced_logout_timeouts());
394 if (container.has_idle_logout_timeout()) {
395 policies->Set(key::kDeviceIdleLogoutTimeout,
396 POLICY_LEVEL_MANDATORY,
397 POLICY_SCOPE_MACHINE,
398 DecodeIntegerValue(container.idle_logout_timeout()));
399 }
400 if (container.has_idle_logout_warning_duration()) {
401 policies->Set(key::kDeviceIdleLogoutWarningDuration,
402 POLICY_LEVEL_MANDATORY,
403 POLICY_SCOPE_MACHINE,
404 DecodeIntegerValue(
405 container.idle_logout_warning_duration()));
406 }
407 }
408
409 if (policy.has_login_screen_saver()) {
410 const em::ScreenSaverProto& container(
411 policy.login_screen_saver());
412 if (container.has_screen_saver_extension_id()) {
413 policies->Set(key::kDeviceLoginScreenSaverId,
414 POLICY_LEVEL_MANDATORY,
415 POLICY_SCOPE_MACHINE,
416 Value::CreateStringValue(
417 container.screen_saver_extension_id()));
418 }
419 if (container.has_screen_saver_timeout()) {
420 policies->Set(key::kDeviceLoginScreenSaverTimeout,
421 POLICY_LEVEL_MANDATORY,
422 POLICY_SCOPE_MACHINE,
423 DecodeIntegerValue(container.screen_saver_timeout()));
424 }
425 }
426
427 if (policy.has_app_pack()) {
428 const em::AppPackProto& container(policy.app_pack());
429 base::ListValue* app_pack_list = new base::ListValue();
430 for (int i = 0; i < container.app_pack_size(); ++i) {
431 const em::AppPackEntryProto& entry(container.app_pack(i));
432 if (entry.has_extension_id() && entry.has_update_url()) {
433 base::DictionaryValue* dict = new base::DictionaryValue();
434 dict->SetString(AppPackUpdater::kExtensionId, entry.extension_id());
435 dict->SetString(AppPackUpdater::kUpdateUrl, entry.update_url());
436 app_pack_list->Append(dict);
437 }
438 }
439 policies->Set(key::kDeviceAppPack,
440 POLICY_LEVEL_MANDATORY,
441 POLICY_SCOPE_MACHINE,
442 app_pack_list);
443 }
444
445 if (policy.has_pinned_apps()) {
446 const em::PinnedAppsProto& container(policy.pinned_apps());
447 base::ListValue* pinned_apps_list = new base::ListValue();
448 for (int i = 0; i < container.app_id_size(); ++i)
449 pinned_apps_list->Append(Value::CreateStringValue(container.app_id(i)));
450
451 policies->Set(key::kPinnedLauncherApps,
452 POLICY_LEVEL_RECOMMENDED,
453 POLICY_SCOPE_MACHINE,
454 pinned_apps_list);
455 }
456 }
457
458 // static
459 void DevicePolicyCache::DecodeNetworkPolicies(
460 const em::ChromeDeviceSettingsProto& policy,
461 PolicyMap* policies,
462 EnterpriseInstallAttributes* install_attributes) {
463 if (policy.has_device_proxy_settings()) {
464 const em::DeviceProxySettingsProto& container(
465 policy.device_proxy_settings());
466 scoped_ptr<DictionaryValue> proxy_settings(new DictionaryValue);
467 if (container.has_proxy_mode())
468 proxy_settings->SetString(key::kProxyMode, container.proxy_mode());
469 if (container.has_proxy_server())
470 proxy_settings->SetString(key::kProxyServer, container.proxy_server());
471 if (container.has_proxy_pac_url())
472 proxy_settings->SetString(key::kProxyPacUrl, container.proxy_pac_url());
473 if (container.has_proxy_bypass_list()) {
474 proxy_settings->SetString(key::kProxyBypassList,
475 container.proxy_bypass_list());
476 }
477
478 // Figure out the level. Proxy policy is mandatory in kiosk mode.
479 PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
480 if (install_attributes->GetMode() == DEVICE_MODE_KIOSK)
481 level = POLICY_LEVEL_MANDATORY;
482
483 if (!proxy_settings->empty()) {
484 policies->Set(key::kProxySettings,
485 level,
486 POLICY_SCOPE_MACHINE,
487 proxy_settings.release());
488 }
489 }
490
491 if (policy.has_data_roaming_enabled()) {
492 const em::DataRoamingEnabledProto& container(policy.data_roaming_enabled());
493 if (container.has_data_roaming_enabled()) {
494 policies->Set(key::kDeviceDataRoamingEnabled,
495 POLICY_LEVEL_MANDATORY,
496 POLICY_SCOPE_MACHINE,
497 Value::CreateBooleanValue(
498 container.data_roaming_enabled()));
499 }
500 }
501
502 if (policy.has_open_network_configuration() &&
503 policy.open_network_configuration().has_open_network_configuration()) {
504 std::string config(
505 policy.open_network_configuration().open_network_configuration());
506 policies->Set(key::kDeviceOpenNetworkConfiguration,
507 POLICY_LEVEL_MANDATORY,
508 POLICY_SCOPE_MACHINE,
509 Value::CreateStringValue(config));
510 }
511 }
512
513 // static
514 void DevicePolicyCache::DecodeReportingPolicies(
515 const em::ChromeDeviceSettingsProto& policy,
516 PolicyMap* policies) {
517 if (policy.has_device_reporting()) {
518 const em::DeviceReportingProto& container(policy.device_reporting());
519 if (container.has_report_version_info()) {
520 policies->Set(key::kReportDeviceVersionInfo,
521 POLICY_LEVEL_MANDATORY,
522 POLICY_SCOPE_MACHINE,
523 Value::CreateBooleanValue(container.report_version_info()));
524 }
525 if (container.has_report_activity_times()) {
526 policies->Set(key::kReportDeviceActivityTimes,
527 POLICY_LEVEL_MANDATORY,
528 POLICY_SCOPE_MACHINE,
529 Value::CreateBooleanValue(
530 container.report_activity_times()));
531 }
532 if (container.has_report_boot_mode()) {
533 policies->Set(key::kReportDeviceBootMode,
534 POLICY_LEVEL_MANDATORY,
535 POLICY_SCOPE_MACHINE,
536 Value::CreateBooleanValue(container.report_boot_mode()));
537 }
538 if (container.has_report_location()) {
539 policies->Set(key::kReportDeviceLocation,
540 POLICY_LEVEL_MANDATORY,
541 POLICY_SCOPE_MACHINE,
542 Value::CreateBooleanValue(container.report_location()));
543 }
544 }
545 }
546
547 // static
548 void DevicePolicyCache::DecodeAutoUpdatePolicies(
549 const em::ChromeDeviceSettingsProto& policy,
550 PolicyMap* policies) {
551 if (policy.has_release_channel()) {
552 const em::ReleaseChannelProto& container(policy.release_channel());
553 if (container.has_release_channel()) {
554 std::string channel(container.release_channel());
555 policies->Set(key::kChromeOsReleaseChannel,
556 POLICY_LEVEL_MANDATORY,
557 POLICY_SCOPE_MACHINE,
558 Value::CreateStringValue(channel));
559 // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
560 // have to pass the channel in here, only ping the update engine to tell
561 // it to fetch the channel from the policy.
562 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
563 SetReleaseTrack(channel);
564 }
565 if (container.has_release_channel_delegated()) {
566 policies->Set(key::kChromeOsReleaseChannelDelegated,
567 POLICY_LEVEL_MANDATORY,
568 POLICY_SCOPE_MACHINE,
569 Value::CreateBooleanValue(
570 container.release_channel_delegated()));
571 }
572 }
573
574 if (policy.has_auto_update_settings()) {
575 const em::AutoUpdateSettingsProto& container(policy.auto_update_settings());
576 if (container.has_update_disabled()) {
577 policies->Set(key::kDeviceAutoUpdateDisabled,
578 POLICY_LEVEL_MANDATORY,
579 POLICY_SCOPE_MACHINE,
580 Value::CreateBooleanValue(container.update_disabled()));
581 }
582
583 if (container.has_target_version_prefix()) {
584 policies->Set(key::kDeviceTargetVersionPrefix,
585 POLICY_LEVEL_MANDATORY,
586 POLICY_SCOPE_MACHINE,
587 Value::CreateStringValue(
588 container.target_version_prefix()));
589 }
590
591 // target_version_display_name is not actually a policy, but a display
592 // string for target_version_prefix, so we ignore it.
593
594 if (container.has_scatter_factor_in_seconds()) {
595 policies->Set(key::kDeviceUpdateScatterFactor,
596 POLICY_LEVEL_MANDATORY,
597 POLICY_SCOPE_MACHINE,
598 Value::CreateIntegerValue(
599 container.scatter_factor_in_seconds()));
600 }
601
602 if (container.allowed_connection_types_size()) {
603 ListValue* allowed_connection_types = new ListValue();
604 RepeatedField<int>::const_iterator entry;
605 for (entry = container.allowed_connection_types().begin();
606 entry != container.allowed_connection_types().end();
607 ++entry) {
608 base::Value* value = DecodeConnectionType(*entry);
609 if (value)
610 allowed_connection_types->Append(value);
611 }
612 policies->Set(key::kDeviceUpdateAllowedConnectionTypes,
613 POLICY_LEVEL_MANDATORY,
614 POLICY_SCOPE_MACHINE,
615 allowed_connection_types);
616 }
617 }
618 }
619
620 // static
621 void DevicePolicyCache::DecodeGenericPolicies(
622 const em::ChromeDeviceSettingsProto& policy,
623 PolicyMap* policies) {
624 if (policy.has_device_policy_refresh_rate()) {
625 const em::DevicePolicyRefreshRateProto& container(
626 policy.device_policy_refresh_rate());
627 if (container.has_device_policy_refresh_rate()) {
628 policies->Set(key::kDevicePolicyRefreshRate,
629 POLICY_LEVEL_MANDATORY,
630 POLICY_SCOPE_MACHINE,
631 DecodeIntegerValue(container.device_policy_refresh_rate()));
632 }
633 }
634
635 if (policy.has_metrics_enabled()) {
636 const em::MetricsEnabledProto& container(policy.metrics_enabled());
637 if (container.has_metrics_enabled()) {
638 policies->Set(key::kDeviceMetricsReportingEnabled,
639 POLICY_LEVEL_MANDATORY,
640 POLICY_SCOPE_MACHINE,
641 Value::CreateBooleanValue(container.metrics_enabled()));
642 }
643 }
644
645 if (policy.has_start_up_urls()) {
646 const em::StartUpUrlsProto& container(policy.start_up_urls());
647 if (container.start_up_urls_size()) {
648 ListValue* urls = new 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(Value::CreateStringValue(*entry));
654 }
655 policies->Set(key::kDeviceStartUpUrls,
656 POLICY_LEVEL_MANDATORY,
657 POLICY_SCOPE_MACHINE,
658 urls);
659 }
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 Value::CreateStringValue(
668 policy.system_timezone().timezone()));
669 }
670 }
671 }
672
673 } // namespace policy 267 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698