OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/configuration_policy_pref_store.h" | 5 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "base/string16.h" | 11 #include "base/string16.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "chrome/browser/prefs/proxy_prefs.h" | |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/policy/configuration_policy_provider.h" | 17 #include "chrome/browser/policy/configuration_policy_provider.h" |
17 #if defined(OS_WIN) | 18 #if defined(OS_WIN) |
18 #include "chrome/browser/policy/configuration_policy_provider_win.h" | 19 #include "chrome/browser/policy/configuration_policy_provider_win.h" |
19 #elif defined(OS_MACOSX) | 20 #elif defined(OS_MACOSX) |
20 #include "chrome/browser/policy/configuration_policy_provider_mac.h" | 21 #include "chrome/browser/policy/configuration_policy_provider_mac.h" |
21 #elif defined(OS_POSIX) | 22 #elif defined(OS_POSIX) |
22 #include "chrome/browser/policy/config_dir_policy_provider.h" | 23 #include "chrome/browser/policy/config_dir_policy_provider.h" |
23 #endif | 24 #endif |
24 #include "chrome/browser/policy/device_management_policy_provider.h" | 25 #include "chrome/browser/policy/device_management_policy_provider.h" |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, | 236 { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, |
236 key::kDefaultSearchProviderKeyword }, | 237 key::kDefaultSearchProviderKeyword }, |
237 { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, | 238 { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, |
238 key::kDefaultSearchProviderSearchURL }, | 239 key::kDefaultSearchProviderSearchURL }, |
239 { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, | 240 { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, |
240 key::kDefaultSearchProviderSuggestURL }, | 241 key::kDefaultSearchProviderSuggestURL }, |
241 { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, | 242 { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, |
242 key::kDefaultSearchProviderIconURL }, | 243 key::kDefaultSearchProviderIconURL }, |
243 { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, | 244 { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, |
244 key::kDefaultSearchProviderEncodings }, | 245 key::kDefaultSearchProviderEncodings }, |
245 { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode }, | 246 { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode }, |
246 { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, | 247 { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, |
247 { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, | 248 { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, |
248 { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, | 249 { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, |
249 { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, | 250 { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, |
250 key::kAlternateErrorPagesEnabled }, | 251 key::kAlternateErrorPagesEnabled }, |
251 { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, | 252 { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, |
252 key::kSearchSuggestEnabled }, | 253 key::kSearchSuggestEnabled }, |
253 { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, | 254 { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, |
254 key::kDnsPrefetchingEnabled }, | 255 key::kDnsPrefetchingEnabled }, |
255 { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, | 256 { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 entries, | 315 entries, |
315 entries + arraysize(entries), | 316 entries + arraysize(entries), |
316 }; | 317 }; |
317 return &policy_list; | 318 return &policy_list; |
318 } | 319 } |
319 | 320 |
320 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( | 321 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( |
321 ConfigurationPolicyProvider* provider) | 322 ConfigurationPolicyProvider* provider) |
322 : provider_(provider), | 323 : provider_(provider), |
323 prefs_(new DictionaryValue()), | 324 prefs_(new DictionaryValue()), |
324 lower_priority_proxy_settings_overridden_(false), | 325 error_in_proxy_settings_(false) { |
325 proxy_disabled_(false), | |
326 proxy_configuration_specified_(false), | |
327 use_system_proxy_(false) { | |
328 if (!provider_->Provide(this)) | 326 if (!provider_->Provide(this)) |
329 LOG(WARNING) << "Failed to get policy from provider."; | 327 LOG(WARNING) << "Failed to get policy from provider."; |
330 FinalizeDefaultSearchPolicySettings(); | 328 FinalizeDefaultSearchPolicySettings(); |
331 } | 329 } |
332 | 330 |
333 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} | 331 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} |
334 | 332 |
335 PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( | 333 PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( |
336 const std::string& key, | 334 const std::string& key, |
337 Value** value) const { | 335 Value** value) const { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 return new ConfigurationPolicyPrefStore(provider); | 395 return new ConfigurationPolicyPrefStore(provider); |
398 } | 396 } |
399 | 397 |
400 // static | 398 // static |
401 ConfigurationPolicyPrefStore* | 399 ConfigurationPolicyPrefStore* |
402 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { | 400 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { |
403 return new ConfigurationPolicyPrefStore( | 401 return new ConfigurationPolicyPrefStore( |
404 g_configuration_policy_provider_keeper.Get().recommended_provider()); | 402 g_configuration_policy_provider_keeper.Get().recommended_provider()); |
405 } | 403 } |
406 | 404 |
407 // static | |
408 void ConfigurationPolicyPrefStore::GetProxyPreferenceSet( | |
409 ProxyPreferenceSet* proxy_pref_set) { | |
410 proxy_pref_set->clear(); | |
411 for (size_t current = 0; current < arraysize(kProxyPolicyMap); ++current) { | |
412 proxy_pref_set->insert(kProxyPolicyMap[current].preference_path); | |
413 } | |
414 proxy_pref_set->insert(prefs::kNoProxyServer); | |
415 proxy_pref_set->insert(prefs::kProxyAutoDetect); | |
416 } | |
417 | |
418 const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* | 405 const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* |
419 ConfigurationPolicyPrefStore::FindPolicyInMap( | 406 ConfigurationPolicyPrefStore::FindPolicyInMap( |
420 ConfigurationPolicyType policy, | 407 ConfigurationPolicyType policy, |
421 const PolicyToPreferenceMapEntry* map, | 408 const PolicyToPreferenceMapEntry* map, |
422 int table_size) const { | 409 int table_size) const { |
423 for (int i = 0; i < table_size; ++i) { | 410 for (int i = 0; i < table_size; ++i) { |
424 if (map[i].policy_type == policy) | 411 if (map[i].policy_type == policy) |
425 return map + i; | 412 return map + i; |
426 } | 413 } |
427 return NULL; | 414 return NULL; |
(...skipping 23 matching lines...) Expand all Loading... | |
451 prefs_->Set(map[current].preference_path, value); | 438 prefs_->Set(map[current].preference_path, value); |
452 return true; | 439 return true; |
453 } | 440 } |
454 } | 441 } |
455 return false; | 442 return false; |
456 } | 443 } |
457 | 444 |
458 bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( | 445 bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( |
459 ConfigurationPolicyType policy, | 446 ConfigurationPolicyType policy, |
460 Value* value) { | 447 Value* value) { |
461 bool result = false; | 448 // We only collect the values until we have sufficient information when |
462 bool warn_about_proxy_disable_config = false; | 449 // Completed() is called to determine whether the presented values were |
463 bool warn_about_proxy_system_config = false; | 450 // correct and apply them in that case. |
Mattias Nissler (ping if slow)
2010/12/21 15:54:29
Why can't we just write to the real dictionary ins
battre (please use the other)
2010/12/21 20:14:09
This would mean that we need some rollback mechani
Mattias Nissler (ping if slow)
2010/12/22 10:22:11
The rollback mechanism is delete-all-proxy-prefs-f
battre
2010/12/22 14:41:16
Well, the point is that eventually we want a singl
Mattias Nissler (ping if slow)
2010/12/22 15:26:15
OK, but if you want to keep the evaluate-later app
battre
2010/12/22 16:15:12
Done.
| |
451 scoped_ptr<Value>* target_container = NULL; | |
452 switch (policy) { | |
453 case kPolicyProxyMode: | |
danno
2010/12/21 16:16:38
Indenting is not right here: http://google-stylegu
battre (please use the other)
2010/12/21 20:14:09
Done.
| |
454 target_container = &proxy_mode_container_; | |
455 break; | |
456 case kPolicyProxyServer: | |
457 target_container = &proxy_server_container_; | |
458 break; | |
459 case kPolicyProxyPacUrl: | |
460 target_container = &proxy_pac_url_container_; | |
461 break; | |
462 case kPolicyProxyBypassList: | |
463 target_container = &proxy_bypass_list_container_; | |
464 break; | |
465 default: | |
466 // We are not interested in this policy. | |
467 return false; | |
468 } | |
469 CHECK(target_container); | |
464 | 470 |
465 const PolicyToPreferenceMapEntry* match_entry = | 471 if (error_in_proxy_settings_) { |
466 FindPolicyInMap(policy, kProxyPolicyMap, arraysize(kProxyPolicyMap)); | 472 delete value; |
467 | 473 return true; |
468 // When the first proxy-related policy is applied, ALL proxy-related | |
469 // preferences that have been set by command-line switches, extensions, | |
470 // user preferences or any other mechanism are overridden. Otherwise | |
471 // it's possible for a user to interfere with proxy policy by setting | |
472 // proxy-related command-line switches or set proxy-related prefs in an | |
473 // extension that are related, but not identical, to the ones set through | |
474 // policy. | |
475 if (!lower_priority_proxy_settings_overridden_ && | |
476 (match_entry || | |
477 policy == kPolicyProxyServerMode)) { | |
478 ProxyPreferenceSet proxy_preference_set; | |
479 GetProxyPreferenceSet(&proxy_preference_set); | |
480 for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin(); | |
481 i != proxy_preference_set.end(); ++i) { | |
482 // We use values of TYPE_NULL to mark preferences for which | |
483 // READ_USE_DEFAULT should be returned by GetValue(). | |
484 prefs_->Set(*i, Value::CreateNullValue()); | |
485 } | |
486 lower_priority_proxy_settings_overridden_ = true; | |
487 } | 474 } |
488 | 475 |
489 // Translate the proxy policy into preferences. | 476 if ((*target_container).get()) { |
490 if (policy == kPolicyProxyServerMode) { | 477 LOG(ERROR) << "Ignoring proxy policies because a policy was defined twice."; |
Mattias Nissler (ping if slow)
2010/12/21 15:54:29
This is not what we want. The idea is that you can
battre (please use the other)
2010/12/21 20:14:09
Done.
Mattias Nissler (ping if slow)
2010/12/22 10:22:11
Not done?
battre
2010/12/22 14:41:16
Sorry. I deleted some other code related to this b
| |
491 int int_value; | 478 delete value; |
492 bool proxy_auto_detect = false; | 479 return true; |
493 if (value->GetAsInteger(&int_value)) { | |
494 result = true; | |
495 switch (int_value) { | |
496 case kPolicyNoProxyServerMode: | |
497 if (!proxy_disabled_) { | |
498 if (proxy_configuration_specified_) | |
499 warn_about_proxy_disable_config = true; | |
500 proxy_disabled_ = true; | |
501 } | |
502 break; | |
503 case kPolicyAutoDetectProxyMode: | |
504 proxy_auto_detect = true; | |
505 break; | |
506 case kPolicyManuallyConfiguredProxyMode: | |
507 break; | |
508 case kPolicyUseSystemProxyMode: | |
509 if (!use_system_proxy_) { | |
510 if (proxy_configuration_specified_) | |
511 warn_about_proxy_system_config = true; | |
512 use_system_proxy_ = true; | |
513 } | |
514 break; | |
515 default: | |
516 // Not a valid policy, don't assume ownership of |value| | |
517 result = false; | |
518 break; | |
519 } | |
520 | |
521 if (int_value != kPolicyUseSystemProxyMode) { | |
522 prefs_->Set(prefs::kNoProxyServer, | |
523 Value::CreateBooleanValue(proxy_disabled_)); | |
524 prefs_->Set(prefs::kProxyAutoDetect, | |
525 Value::CreateBooleanValue(proxy_auto_detect)); | |
526 } | |
527 } | |
528 } else if (match_entry) { | |
529 // Determine if the applied proxy policy settings conflict and issue | |
530 // a corresponding warning if they do. | |
531 if (!proxy_configuration_specified_) { | |
532 if (proxy_disabled_) | |
533 warn_about_proxy_disable_config = true; | |
534 if (use_system_proxy_) | |
535 warn_about_proxy_system_config = true; | |
536 proxy_configuration_specified_ = true; | |
537 } | |
538 if (!use_system_proxy_ && !proxy_disabled_) { | |
539 prefs_->Set(match_entry->preference_path, value); | |
540 // The ownership of value has been passed on to |prefs_|, | |
541 // don't clean it up later. | |
542 value = NULL; | |
543 } | |
544 result = true; | |
545 } | 480 } |
546 | 481 |
547 if (warn_about_proxy_disable_config) { | 482 (*target_container).reset(value); |
548 LOG(WARNING) << "A centrally-administered policy disables the use of" | 483 return true; |
549 << " a proxy but also specifies an explicit proxy" | 484 } |
550 << " configuration."; | 485 |
486 void ConfigurationPolicyPrefStore::Completed() { | |
Mattias Nissler (ping if slow)
2010/12/21 15:54:29
Note that for default search, we just call Finaliz
danno
2010/12/21 16:16:38
I am not sure I agree. I like that there's a metho
Mattias Nissler (ping if slow)
2010/12/21 16:22:41
My rationale for opposing the idea is this: We'd a
battre (please use the other)
2010/12/21 20:14:09
I checked the code again and agree with Mattias. H
| |
487 if (CheckProxySettings()) | |
488 ApplyProxySettings(); | |
489 proxy_mode_container_.reset(NULL); | |
490 proxy_server_container_.reset(NULL); | |
491 proxy_pac_url_container_.reset(NULL); | |
492 proxy_bypass_list_container_.reset(NULL); | |
493 } | |
494 | |
495 bool ConfigurationPolicyPrefStore::CheckProxySettings() { | |
496 if (error_in_proxy_settings_) | |
497 return false; | |
498 | |
499 bool mode = proxy_mode_container_.get() && | |
500 !proxy_mode_container_->IsType(Value::TYPE_NULL); | |
501 bool server = proxy_server_container_.get() && | |
502 !proxy_server_container_->IsType(Value::TYPE_NULL); | |
503 bool pac_url = proxy_pac_url_container_.get() && | |
504 !proxy_pac_url_container_->IsType(Value::TYPE_NULL); | |
505 bool bypass_list = proxy_bypass_list_container_.get() && | |
506 !proxy_bypass_list_container_->IsType(Value::TYPE_NULL); | |
507 | |
508 if ((server || pac_url || bypass_list) && !mode) { | |
509 LOG(WARNING) << "A centrally-administered policy defines proxy setting" | |
510 << " details without setting a proxy mode."; | |
511 return false; | |
551 } | 512 } |
552 | 513 |
553 if (warn_about_proxy_system_config) { | 514 if (!mode) |
554 LOG(WARNING) << "A centrally-administered policy dictates that the" | 515 return true; |
555 << " system proxy settings should be used but also specifies" | 516 |
556 << " an explicit proxy configuration."; | 517 int mode_value; |
518 if (!proxy_mode_container_->GetAsInteger(&mode_value)) { | |
519 LOG(WARNING) << "Invalid proxy mode value."; | |
520 return false; | |
557 } | 521 } |
558 | 522 |
559 // If the policy was a proxy policy, cleanup |value|. | 523 switch (mode_value) { |
560 if (result && value) | 524 case kPolicyNoProxyServerMode: |
561 delete value; | 525 if (server || pac_url || bypass_list) { |
562 return result; | 526 LOG(WARNING) << "A centrally-administered policy disables the use of" |
527 << " a proxy but also specifies an explicit proxy" | |
528 << " configuration."; | |
529 return false; | |
530 } | |
531 break; | |
532 case kPolicyAutoDetectProxyMode: | |
533 if (server || bypass_list) { | |
534 LOG(WARNING) << "A centrally-administered policy dictates that a proxy" | |
535 << " shall be auto configured but specifies fixed proxy" | |
536 << " servers or a by-pass list."; | |
537 return false; | |
538 } | |
539 break; | |
540 case kPolicyManuallyConfiguredProxyMode: | |
541 if (!server) { | |
542 LOG(WARNING) << "A centrally-administered policy dictates that the" | |
543 << " system proxy settings should use fixed proxy servers" | |
544 << " without specifying which ones."; | |
545 return false; | |
546 } | |
547 if (pac_url) { | |
548 LOG(WARNING) << "A centrally-administered policy dictates that the" | |
549 << " system proxy settings should use fixed proxy servers" | |
550 << " but also specifies a PAC script."; | |
551 return false; | |
552 } | |
553 break; | |
554 case kPolicyUseSystemProxyMode: | |
555 if (server || pac_url || bypass_list) { | |
556 LOG(WARNING) << "A centrally-administered policy dictates that the" | |
557 << " system proxy settings should be used but also specifies" | |
558 << " an explicit proxy configuration."; | |
559 return false; | |
560 } | |
561 break; | |
562 default: | |
563 LOG(WARNING) << "Invalid proxy mode " << mode_value; | |
564 return false; | |
565 } | |
566 return true; | |
567 } | |
568 | |
569 void ConfigurationPolicyPrefStore::ApplyProxySettings() { | |
570 if (proxy_mode_container_.get() == NULL || | |
571 proxy_mode_container_->IsType(Value::TYPE_NULL)) | |
572 return; | |
573 | |
574 int int_mode; | |
575 CHECK(proxy_mode_container_->GetAsInteger(&int_mode)); | |
576 ProxyPrefs::ProxyMode mode; | |
577 switch (int_mode) { | |
578 case kPolicyNoProxyServerMode: | |
579 mode = ProxyPrefs::DISABLED; | |
580 break; | |
581 case kPolicyAutoDetectProxyMode: | |
582 mode = ProxyPrefs::AUTO_DETECT; | |
583 if (proxy_pac_url_container_.get() && | |
584 !proxy_pac_url_container_->IsType(Value::TYPE_NULL)) { | |
585 mode = ProxyPrefs::PAC_SCRIPT; | |
586 } | |
587 break; | |
588 case kPolicyManuallyConfiguredProxyMode: | |
589 mode = ProxyPrefs::FIXED_SERVERS; | |
590 break; | |
591 case kPolicyUseSystemProxyMode: | |
592 mode = ProxyPrefs::SYSTEM; | |
593 break; | |
594 default: | |
595 mode = ProxyPrefs::DISABLED; | |
596 NOTREACHED(); | |
597 } | |
598 prefs_->Set(prefs::kProxyMode, Value::CreateIntegerValue(mode)); | |
599 | |
600 if (proxy_server_container_.get() && | |
601 !proxy_server_container_->IsType(Value::TYPE_NULL)) { | |
602 prefs_->Set(prefs::kProxyServer, proxy_server_container_.release()); | |
603 } else { | |
604 prefs_->Set(prefs::kProxyServer, Value::CreateNullValue()); | |
605 } | |
606 if (proxy_pac_url_container_.get() && | |
607 !proxy_pac_url_container_->IsType(Value::TYPE_NULL)) { | |
608 prefs_->Set(prefs::kProxyPacUrl, proxy_pac_url_container_.release()); | |
609 } else { | |
610 prefs_->Set(prefs::kProxyPacUrl, Value::CreateNullValue()); | |
611 } | |
612 if (proxy_bypass_list_container_.get() && | |
613 !proxy_bypass_list_container_->IsType(Value::TYPE_NULL)) { | |
614 prefs_->Set(prefs::kProxyBypassList, | |
615 proxy_bypass_list_container_.release()); | |
616 } else { | |
617 prefs_->Set(prefs::kProxyBypassList, Value::CreateNullValue()); | |
618 } | |
563 } | 619 } |
564 | 620 |
565 bool ConfigurationPolicyPrefStore::ApplySyncPolicy( | 621 bool ConfigurationPolicyPrefStore::ApplySyncPolicy( |
566 ConfigurationPolicyType policy, Value* value) { | 622 ConfigurationPolicyType policy, Value* value) { |
567 if (policy == kPolicySyncDisabled) { | 623 if (policy == kPolicySyncDisabled) { |
568 bool disable_sync; | 624 bool disable_sync; |
569 if (value->GetAsBoolean(&disable_sync) && disable_sync) | 625 if (value->GetAsBoolean(&disable_sync) && disable_sync) |
570 prefs_->Set(prefs::kSyncManaged, value); | 626 prefs_->Set(prefs::kSyncManaged, value); |
571 else | 627 else |
572 delete value; | 628 delete value; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 std::string()); | 716 std::string()); |
661 return; | 717 return; |
662 } | 718 } |
663 } | 719 } |
664 // Required entries are not there. Remove any related entries. | 720 // Required entries are not there. Remove any related entries. |
665 RemovePreferencesOfMap(kDefaultSearchPolicyMap, | 721 RemovePreferencesOfMap(kDefaultSearchPolicyMap, |
666 arraysize(kDefaultSearchPolicyMap)); | 722 arraysize(kDefaultSearchPolicyMap)); |
667 } | 723 } |
668 | 724 |
669 } // namespace policy | 725 } // namespace policy |
OLD | NEW |