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.
5 #include "components/content_settings/core/browser/content_settings_pref_provider.h"
7 #include "base/auto_reset.h"
8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/default_pref_store.h"
12 #include "base/prefs/overlay_user_pref_store.h"
13 #include "base/prefs/pref_change_registrar.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/prefs/scoped_user_pref_update.h"
16 #include "base/prefs/testing_pref_store.h"
17 #include "base/test/simple_test_clock.h"
18 #include "base/threading/platform_thread.h"
19 #include "base/values.h"
20 #include "chrome/browser/content_settings/content_settings_mock_observer.h"
21 #include "chrome/browser/prefs/browser_prefs.h"
22 #include "chrome/browser/prefs/pref_service_mock_factory.h"
23 #include "chrome/browser/prefs/pref_service_syncable.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/url_constants.h"
27 #include "chrome/test/base/testing_pref_service_syncable.h"
28 #include "chrome/test/base/testing_profile.h"
29 #include "components/content_settings/core/browser/content_settings_pref.h"
30 #include "components/content_settings/core/browser/content_settings_rule.h"
31 #include "components/content_settings/core/browser/content_settings_utils.h"
32 #include "components/content_settings/core/test/content_settings_test_utils.h"
33 #include "components/pref_registry/pref_registry_syncable.h"
34 #include "content/public/test/test_browser_thread_bundle.h"
35 #include "testing/gtest/include/gtest/gtest.h"
40 namespace content_settings
{
42 class DeadlockCheckerThread
: public base::PlatformThread::Delegate
{
44 explicit DeadlockCheckerThread(PrefProvider
* provider
)
45 : provider_(provider
) {}
47 void ThreadMain() override
{
48 EXPECT_TRUE(provider_
->TestAllLocks());
51 PrefProvider
* provider_
;
52 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerThread
);
55 // A helper for observing an preference changes and testing whether
56 // |PrefProvider| holds a lock when the preferences change.
57 class DeadlockCheckerObserver
{
59 // |DeadlockCheckerObserver| doesn't take the ownership of |prefs| or
61 DeadlockCheckerObserver(PrefService
* prefs
, PrefProvider
* provider
)
62 : provider_(provider
),
63 notification_received_(false) {
64 pref_change_registrar_
.Init(prefs
);
65 pref_change_registrar_
.Add(
66 prefs::kContentSettingsPatternPairs
,
68 &DeadlockCheckerObserver::OnContentSettingsPatternPairsChanged
,
69 base::Unretained(this)));
71 virtual ~DeadlockCheckerObserver() {}
73 bool notification_received() const {
74 return notification_received_
;
78 void OnContentSettingsPatternPairsChanged() {
79 // Check whether |provider_| holds its lock. For this, we need a
81 DeadlockCheckerThread
thread(provider_
);
82 base::PlatformThreadHandle handle
;
83 ASSERT_TRUE(base::PlatformThread::Create(0, &thread
, &handle
));
84 base::PlatformThread::Join(handle
);
85 notification_received_
= true;
88 PrefProvider
* provider_
;
89 PrefChangeRegistrar pref_change_registrar_
;
90 bool notification_received_
;
91 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerObserver
);
94 class PrefProviderTest
: public testing::Test
{
95 content::TestBrowserThreadBundle thread_bundle_
;
98 TEST_F(PrefProviderTest
, Observer
) {
99 TestingProfile profile
;
100 PrefProvider
pref_content_settings_provider(profile
.GetPrefs(), false);
102 ContentSettingsPattern pattern
=
103 ContentSettingsPattern::FromString("[*.]example.com");
104 content_settings::MockObserver mock_observer
;
105 EXPECT_CALL(mock_observer
,
106 OnContentSettingChanged(pattern
,
107 ContentSettingsPattern::Wildcard(),
108 CONTENT_SETTINGS_TYPE_IMAGES
,
111 pref_content_settings_provider
.AddObserver(&mock_observer
);
113 pref_content_settings_provider
.SetWebsiteSetting(
115 ContentSettingsPattern::Wildcard(),
116 CONTENT_SETTINGS_TYPE_IMAGES
,
118 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
120 pref_content_settings_provider
.ShutdownOnUIThread();
123 // Test for regression in which the PrefProvider modified the user pref store
124 // of the OTR unintentionally: http://crbug.com/74466.
125 TEST_F(PrefProviderTest
, Incognito
) {
126 PersistentPrefStore
* user_prefs
= new TestingPrefStore();
127 OverlayUserPrefStore
* otr_user_prefs
=
128 new OverlayUserPrefStore(user_prefs
);
130 PrefServiceMockFactory factory
;
131 factory
.set_user_prefs(make_scoped_refptr(user_prefs
));
132 scoped_refptr
<user_prefs::PrefRegistrySyncable
> registry(
133 new user_prefs::PrefRegistrySyncable
);
134 PrefServiceSyncable
* regular_prefs
=
135 factory
.CreateSyncable(registry
.get()).release();
137 chrome::RegisterUserProfilePrefs(registry
.get());
139 PrefServiceMockFactory otr_factory
;
140 otr_factory
.set_user_prefs(make_scoped_refptr(otr_user_prefs
));
141 scoped_refptr
<user_prefs::PrefRegistrySyncable
> otr_registry(
142 new user_prefs::PrefRegistrySyncable
);
143 PrefServiceSyncable
* otr_prefs
=
144 otr_factory
.CreateSyncable(otr_registry
.get()).release();
146 chrome::RegisterUserProfilePrefs(otr_registry
.get());
148 TestingProfile::Builder profile_builder
;
149 profile_builder
.SetPrefService(make_scoped_ptr(regular_prefs
));
150 scoped_ptr
<TestingProfile
> profile
= profile_builder
.Build();
152 TestingProfile::Builder otr_profile_builder
;
153 otr_profile_builder
.SetPrefService(make_scoped_ptr(otr_prefs
));
154 otr_profile_builder
.BuildIncognito(profile
.get());
156 PrefProvider
pref_content_settings_provider(regular_prefs
, false);
157 PrefProvider
pref_content_settings_provider_incognito(otr_prefs
, true);
158 ContentSettingsPattern pattern
=
159 ContentSettingsPattern::FromString("[*.]example.com");
160 pref_content_settings_provider
.SetWebsiteSetting(
163 CONTENT_SETTINGS_TYPE_IMAGES
,
165 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
167 GURL
host("http://example.com/");
168 // The value should of course be visible in the regular PrefProvider.
169 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
170 GetContentSetting(&pref_content_settings_provider
,
173 CONTENT_SETTINGS_TYPE_IMAGES
,
176 // And also in the OTR version.
177 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
178 GetContentSetting(&pref_content_settings_provider_incognito
,
181 CONTENT_SETTINGS_TYPE_IMAGES
,
184 // But the value should not be overridden in the OTR user prefs accidentally.
185 EXPECT_FALSE(otr_user_prefs
->IsSetInOverlay(
186 prefs::kContentSettingsPatternPairs
));
188 pref_content_settings_provider
.ShutdownOnUIThread();
189 pref_content_settings_provider_incognito
.ShutdownOnUIThread();
192 TEST_F(PrefProviderTest
, GetContentSettingsValue
) {
193 TestingProfile testing_profile
;
194 PrefProvider
provider(testing_profile
.GetPrefs(), false);
196 GURL
primary_url("http://example.com/");
197 ContentSettingsPattern primary_pattern
=
198 ContentSettingsPattern::FromString("[*.]example.com");
200 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
201 GetContentSetting(&provider
,
204 CONTENT_SETTINGS_TYPE_IMAGES
,
209 GetContentSettingValue(&provider
,
212 CONTENT_SETTINGS_TYPE_IMAGES
,
216 provider
.SetWebsiteSetting(primary_pattern
,
218 CONTENT_SETTINGS_TYPE_IMAGES
,
220 new base::FundamentalValue(CONTENT_SETTING_BLOCK
));
221 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
222 GetContentSetting(&provider
,
225 CONTENT_SETTINGS_TYPE_IMAGES
,
228 scoped_ptr
<base::Value
> value_ptr(
229 GetContentSettingValue(&provider
,
232 CONTENT_SETTINGS_TYPE_IMAGES
,
236 value_ptr
->GetAsInteger(&int_value
);
237 EXPECT_EQ(CONTENT_SETTING_BLOCK
, IntToContentSetting(int_value
));
239 provider
.SetWebsiteSetting(primary_pattern
,
241 CONTENT_SETTINGS_TYPE_IMAGES
,
245 GetContentSettingValue(&provider
,
248 CONTENT_SETTINGS_TYPE_IMAGES
,
251 provider
.ShutdownOnUIThread();
254 TEST_F(PrefProviderTest
, Patterns
) {
255 TestingProfile testing_profile
;
256 PrefProvider
pref_content_settings_provider(testing_profile
.GetPrefs(),
259 GURL
host1("http://example.com/");
260 GURL
host2("http://www.example.com/");
261 GURL
host3("http://example.org/");
262 GURL
host4("file:///tmp/test.html");
263 ContentSettingsPattern pattern1
=
264 ContentSettingsPattern::FromString("[*.]example.com");
265 ContentSettingsPattern pattern2
=
266 ContentSettingsPattern::FromString("example.org");
267 ContentSettingsPattern pattern3
=
268 ContentSettingsPattern::FromString("file:///tmp/test.html");
270 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
271 GetContentSetting(&pref_content_settings_provider
,
274 CONTENT_SETTINGS_TYPE_IMAGES
,
277 pref_content_settings_provider
.SetWebsiteSetting(
280 CONTENT_SETTINGS_TYPE_IMAGES
,
282 new base::FundamentalValue(CONTENT_SETTING_BLOCK
));
283 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
284 GetContentSetting(&pref_content_settings_provider
,
287 CONTENT_SETTINGS_TYPE_IMAGES
,
290 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
291 GetContentSetting(&pref_content_settings_provider
,
294 CONTENT_SETTINGS_TYPE_IMAGES
,
298 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
299 GetContentSetting(&pref_content_settings_provider
,
302 CONTENT_SETTINGS_TYPE_IMAGES
,
305 pref_content_settings_provider
.SetWebsiteSetting(
308 CONTENT_SETTINGS_TYPE_IMAGES
,
310 new base::FundamentalValue(CONTENT_SETTING_BLOCK
));
311 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
312 GetContentSetting(&pref_content_settings_provider
,
315 CONTENT_SETTINGS_TYPE_IMAGES
,
319 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
320 GetContentSetting(&pref_content_settings_provider
,
323 CONTENT_SETTINGS_TYPE_IMAGES
,
326 pref_content_settings_provider
.SetWebsiteSetting(
329 CONTENT_SETTINGS_TYPE_IMAGES
,
331 new base::FundamentalValue(CONTENT_SETTING_BLOCK
));
332 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
333 GetContentSetting(&pref_content_settings_provider
,
336 CONTENT_SETTINGS_TYPE_IMAGES
,
340 pref_content_settings_provider
.ShutdownOnUIThread();
343 TEST_F(PrefProviderTest
, ResourceIdentifier
) {
344 TestingProfile testing_profile
;
345 PrefProvider
pref_content_settings_provider(testing_profile
.GetPrefs(),
348 GURL
host("http://example.com/");
349 ContentSettingsPattern pattern
=
350 ContentSettingsPattern::FromString("[*.]example.com");
351 std::string
resource1("someplugin");
352 std::string
resource2("otherplugin");
354 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
356 &pref_content_settings_provider
,
357 host
, host
, CONTENT_SETTINGS_TYPE_PLUGINS
,
359 pref_content_settings_provider
.SetWebsiteSetting(
362 CONTENT_SETTINGS_TYPE_PLUGINS
,
364 new base::FundamentalValue(CONTENT_SETTING_BLOCK
));
365 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
367 &pref_content_settings_provider
,
368 host
, host
, CONTENT_SETTINGS_TYPE_PLUGINS
,
370 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
372 &pref_content_settings_provider
,
373 host
, host
, CONTENT_SETTINGS_TYPE_PLUGINS
,
376 pref_content_settings_provider
.ShutdownOnUIThread();
379 TEST_F(PrefProviderTest
, AutoSubmitCertificateContentSetting
) {
380 TestingProfile profile
;
381 TestingPrefServiceSyncable
* prefs
= profile
.GetTestingPrefService();
382 GURL
primary_url("https://www.example.com");
383 GURL
secondary_url("https://www.sample.com");
385 PrefProvider
provider(prefs
, false);
387 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
392 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
396 provider
.SetWebsiteSetting(ContentSettingsPattern::FromURL(primary_url
),
397 ContentSettingsPattern::Wildcard(),
398 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
400 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
401 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
406 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
409 provider
.ShutdownOnUIThread();
412 // http://crosbug.com/17760
413 TEST_F(PrefProviderTest
, Deadlock
) {
414 TestingPrefServiceSyncable prefs
;
415 PrefProvider::RegisterProfilePrefs(prefs
.registry());
417 // Chain of events: a preference changes, |PrefProvider| notices it, and reads
418 // and writes the preference. When the preference is written, a notification
419 // is sent, and this used to happen when |PrefProvider| was still holding its
422 PrefProvider
provider(&prefs
, false);
423 DeadlockCheckerObserver
observer(&prefs
, &provider
);
425 DictionaryPrefUpdate
update(&prefs
,
426 prefs::kContentSettingsPatternPairs
);
427 base::DictionaryValue
* mutable_settings
= update
.Get();
428 mutable_settings
->SetWithoutPathExpansion("www.example.com,*",
429 new base::DictionaryValue());
431 EXPECT_TRUE(observer
.notification_received());
433 provider
.ShutdownOnUIThread();
436 TEST_F(PrefProviderTest
, LastUsage
) {
437 TestingProfile testing_profile
;
438 PrefProvider
pref_content_settings_provider(testing_profile
.GetPrefs(),
440 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
441 test_clock
->SetNow(base::Time::Now());
443 pref_content_settings_provider
.SetClockForTesting(
444 scoped_ptr
<base::Clock
>(test_clock
));
445 GURL
host("http://example.com/");
446 ContentSettingsPattern pattern
=
447 ContentSettingsPattern::FromString("[*.]example.com");
449 base::Time no_usage
= pref_content_settings_provider
.GetLastUsage(
450 pattern
, pattern
, CONTENT_SETTINGS_TYPE_GEOLOCATION
);
451 EXPECT_EQ(no_usage
.ToDoubleT(), 0);
453 pref_content_settings_provider
.UpdateLastUsage(
454 pattern
, pattern
, CONTENT_SETTINGS_TYPE_GEOLOCATION
);
455 base::Time first
= pref_content_settings_provider
.GetLastUsage(
456 pattern
, pattern
, CONTENT_SETTINGS_TYPE_GEOLOCATION
);
458 test_clock
->Advance(base::TimeDelta::FromSeconds(10));
460 pref_content_settings_provider
.UpdateLastUsage(
461 pattern
, pattern
, CONTENT_SETTINGS_TYPE_GEOLOCATION
);
462 base::Time second
= pref_content_settings_provider
.GetLastUsage(
463 pattern
, pattern
, CONTENT_SETTINGS_TYPE_GEOLOCATION
);
465 base::TimeDelta delta
= second
- first
;
466 EXPECT_EQ(delta
.InSeconds(), 10);
468 pref_content_settings_provider
.ShutdownOnUIThread();
472 // TODO(msramek): This tests the correct migration behavior between the old
473 // aggregate dictionary preferences for all content settings types and the new
474 // dictionary preferences for individual types. Remove this when the migration
476 TEST_F(PrefProviderTest
, SyncingOldToNew
) {
477 TestingPrefServiceSyncable prefs
;
478 PrefProvider::RegisterProfilePrefs(prefs
.registry());
479 PrefProvider
provider(&prefs
, false);
481 const std::string pattern
= "google.com,*";
482 const std::string resource_id
= "abcde12345";
483 base::DictionaryValue
* exceptions
= new base::DictionaryValue();
484 base::DictionaryValue
* plugin_resources
= new base::DictionaryValue();
486 // Add exceptions for images and app banner.
487 exceptions
->SetIntegerWithoutPathExpansion(
488 GetTypeName(CONTENT_SETTINGS_TYPE_IMAGES
), CONTENT_SETTING_ALLOW
);
489 exceptions
->SetIntegerWithoutPathExpansion(
490 GetTypeName(CONTENT_SETTINGS_TYPE_APP_BANNER
), CONTENT_SETTING_ALLOW
);
492 // Add a regular exception for plugins, then one with a resource identifier.
493 exceptions
->SetIntegerWithoutPathExpansion(
494 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS
), CONTENT_SETTING_ALLOW
);
495 plugin_resources
->SetIntegerWithoutPathExpansion(
496 resource_id
, CONTENT_SETTING_BLOCK
);
497 exceptions
->SetWithoutPathExpansion(
498 "per_plugin", plugin_resources
);
500 // Change the old dictionary preference and observe changes
501 // in the new preferences.
503 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
504 base::DictionaryValue
* old_dictionary
= update
.Get();
505 old_dictionary
->SetWithoutPathExpansion(pattern
, exceptions
);
508 // The images exception was synced.
510 DictionaryPrefUpdate
update(
511 &prefs
, prefs::kContentSettingsImagesPatternPairs
);
512 const base::DictionaryValue
* images_dictionary
= update
.Get();
514 EXPECT_EQ(1u, images_dictionary
->size());
515 const base::DictionaryValue
* images_exception
;
516 EXPECT_TRUE(images_dictionary
->GetDictionaryWithoutPathExpansion(
517 pattern
, &images_exception
));
519 // And it has a correct value.
520 int images_exception_value
= CONTENT_SETTING_DEFAULT
;
521 EXPECT_TRUE(images_exception
->GetIntegerWithoutPathExpansion(
522 "setting", &images_exception_value
));
523 EXPECT_EQ(CONTENT_SETTING_ALLOW
, images_exception_value
);
526 // The app banner exception was not synced.
528 DictionaryPrefUpdate
update(
529 &prefs
, prefs::kContentSettingsAppBannerPatternPairs
);
530 const base::DictionaryValue
* app_banner_dictionary
= update
.Get();
531 EXPECT_TRUE(app_banner_dictionary
->empty());
534 // The plugins exception was synced, together with the resource identifiers.
536 DictionaryPrefUpdate
update(
537 &prefs
, prefs::kContentSettingsPluginsPatternPairs
);
538 const base::DictionaryValue
* plugins_dictionary
= update
.Get();
539 EXPECT_EQ(1u, plugins_dictionary
->size());
541 const base::DictionaryValue
* plugins_exception
;
542 EXPECT_TRUE(plugins_dictionary
->GetDictionaryWithoutPathExpansion(
543 pattern
, &plugins_exception
));
545 int plugins_exception_value
= CONTENT_SETTING_DEFAULT
;
546 EXPECT_TRUE(plugins_exception
->GetIntegerWithoutPathExpansion(
547 "setting", &plugins_exception_value
));
548 EXPECT_EQ(CONTENT_SETTING_ALLOW
, plugins_exception_value
);
550 int resource_exception_value
= CONTENT_SETTING_DEFAULT
;
551 const base::DictionaryValue
* resource_exception
;
552 EXPECT_TRUE(plugins_exception
->GetDictionaryWithoutPathExpansion(
553 "per_resource", &resource_exception
));
554 EXPECT_TRUE(resource_exception
->GetIntegerWithoutPathExpansion(
555 resource_id
, &resource_exception_value
));
556 EXPECT_EQ(CONTENT_SETTING_BLOCK
, resource_exception_value
);
559 provider
.ShutdownOnUIThread();
562 TEST_F(PrefProviderTest
, SyncingNewToOld
) {
563 TestingPrefServiceSyncable prefs
;
564 PrefProvider::RegisterProfilePrefs(prefs
.registry());
565 PrefProvider
provider(&prefs
, false);
567 const std::string pattern
= "google.com,*";
568 const std::string resource_id
= "abcde12345";
569 base::DictionaryValue block_exception
;
570 block_exception
.SetIntegerWithoutPathExpansion(
571 "setting", CONTENT_SETTING_BLOCK
);
573 // Add a mouselock exception.
575 DictionaryPrefUpdate
update(
576 &prefs
, prefs::kContentSettingsMouseLockPatternPairs
);
577 base::DictionaryValue
* mouselock_dictionary
= update
.Get();
579 mouselock_dictionary
->SetWithoutPathExpansion(
580 pattern
, block_exception
.DeepCopy());
583 // Add a microphone exception.
585 DictionaryPrefUpdate
update(
586 &prefs
, prefs::kContentSettingsMediaStreamMicPatternPairs
);
587 base::DictionaryValue
* microphone_dictionary
= update
.Get();
589 microphone_dictionary
->SetWithoutPathExpansion(
590 pattern
, block_exception
.DeepCopy());
593 // Add a plugin exception with resource identifiers.
595 DictionaryPrefUpdate
update(
596 &prefs
, prefs::kContentSettingsPluginsPatternPairs
);
597 base::DictionaryValue
* plugins_dictionary
= update
.Get();
599 base::DictionaryValue
* plugin_exception
= block_exception
.DeepCopy();
600 plugins_dictionary
->SetWithoutPathExpansion(
601 pattern
, plugin_exception
);
603 base::DictionaryValue
* resource_exception
= new base::DictionaryValue();
604 resource_exception
->SetIntegerWithoutPathExpansion(
605 resource_id
, CONTENT_SETTING_ALLOW
);
607 plugin_exception
->SetWithoutPathExpansion(
608 "per_resource", resource_exception
);
611 // Only the notifications and plugin exceptions should appear in the
612 // old dictionary. We should also have a resource identifiers section
615 DictionaryPrefUpdate
update(
616 &prefs
, prefs::kContentSettingsPatternPairs
);
617 const base::DictionaryValue
* old_dictionary
= update
.Get();
619 const base::DictionaryValue
* exception
;
620 EXPECT_TRUE(old_dictionary
->GetDictionaryWithoutPathExpansion(
621 pattern
, &exception
));
622 EXPECT_EQ(3u, exception
->size());
623 EXPECT_FALSE(exception
->HasKey(
624 GetTypeName(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)));
626 int mouselock_exception_value
= CONTENT_SETTING_DEFAULT
;
627 exception
->GetIntegerWithoutPathExpansion(
628 GetTypeName(CONTENT_SETTINGS_TYPE_MOUSELOCK
),
629 &mouselock_exception_value
);
630 DCHECK_EQ(CONTENT_SETTING_BLOCK
, mouselock_exception_value
);
632 int plugins_exception_value
= CONTENT_SETTING_DEFAULT
;
633 exception
->GetIntegerWithoutPathExpansion(
634 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS
),
635 &plugins_exception_value
);
636 DCHECK_EQ(CONTENT_SETTING_BLOCK
, plugins_exception_value
);
638 int resource_exception_value
= CONTENT_SETTING_DEFAULT
;
639 const base::DictionaryValue
* resource_values
;
640 exception
->GetDictionaryWithoutPathExpansion(
641 "per_plugin", &resource_values
);
642 resource_values
->GetIntegerWithoutPathExpansion(
643 resource_id
, &resource_exception_value
);
644 DCHECK_EQ(CONTENT_SETTING_ALLOW
, resource_exception_value
);
647 provider
.ShutdownOnUIThread();
650 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
651 TEST_F(PrefProviderTest
, PMIMigrateOnlyAllow
) {
652 TestingPrefServiceSyncable prefs
;
653 PrefProvider::RegisterProfilePrefs(prefs
.registry());
655 const std::string pattern_1
= "google.com,*";
656 const std::string pattern_2
= "www.google.com,*";
657 base::DictionaryValue
* exception_1
= new base::DictionaryValue();
658 base::DictionaryValue
* exception_2
= new base::DictionaryValue();
660 // Add both an "allow" and "block" exception for PMI.
661 exception_1
->SetIntegerWithoutPathExpansion(
662 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
),
663 CONTENT_SETTING_ALLOW
);
664 exception_2
->SetIntegerWithoutPathExpansion(
665 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
),
666 CONTENT_SETTING_BLOCK
);
668 // Change the old dictionary preference.
670 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
671 base::DictionaryValue
* old_dictionary
= update
.Get();
672 old_dictionary
->SetWithoutPathExpansion(pattern_1
, exception_1
);
673 old_dictionary
->SetWithoutPathExpansion(pattern_2
, exception_2
);
676 // Create the PrefProvider. It should migrate the settings.
677 PrefProvider
provider(&prefs
, false);
679 // The "block" exception for PMI was migrated, but "allow" was not.
681 DictionaryPrefUpdate
update(
682 &prefs
, prefs::kContentSettingsProtectedMediaIdentifierPatternPairs
);
683 const base::DictionaryValue
* pmi_dictionary
= update
.Get();
684 EXPECT_FALSE(pmi_dictionary
->HasKey(pattern_1
));
685 EXPECT_TRUE(pmi_dictionary
->HasKey(pattern_2
));
688 provider
.ShutdownOnUIThread();
692 TEST_F(PrefProviderTest
, PrefsMigrateVerbatim
) {
693 TestingPrefServiceSyncable prefs
;
694 PrefProvider::RegisterProfilePrefs(prefs
.registry());
696 const std::string pattern_1
= "google.com,*";
697 const std::string pattern_2
= "www.google.com,*";
698 base::DictionaryValue
* exception_1
= new base::DictionaryValue();
699 base::DictionaryValue
* exception_2
= new base::DictionaryValue();
700 scoped_ptr
<base::DictionaryValue
> old_dictionary
;
702 // Add two exceptions.
703 exception_1
->SetIntegerWithoutPathExpansion(
704 GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES
),
705 CONTENT_SETTING_ALLOW
);
706 exception_2
->SetIntegerWithoutPathExpansion(
707 GetTypeName(CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
),
708 CONTENT_SETTING_BLOCK
);
710 // Change the old dictionary preference.
712 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
713 base::DictionaryValue
* dictionary
= update
.Get();
714 dictionary
->SetWithoutPathExpansion(pattern_1
, exception_1
);
715 dictionary
->SetWithoutPathExpansion(pattern_2
, exception_2
);
716 old_dictionary
.reset(dictionary
->DeepCopy());
719 // Create the PrefProvider. It should copy the settings from the old
720 // preference to the new ones.
721 PrefProvider
provider(&prefs
, false);
723 // Force copying back from the new preferences to the old one.
725 DictionaryPrefUpdate
update(
726 &prefs
, prefs::kContentSettingsCookiesPatternPairs
);
729 DictionaryPrefUpdate
update(
730 &prefs
, prefs::kContentSettingsAutomaticDownloadsPatternPairs
);
733 // Test if the value after copying there and back is the same.
735 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
736 base::DictionaryValue
* new_dictionary
= update
.Get();
737 EXPECT_TRUE(old_dictionary
->Equals(new_dictionary
));
740 provider
.ShutdownOnUIThread();
743 TEST_F(PrefProviderTest
, IncognitoInheritsValueMap
) {
744 TestingPrefServiceSyncable prefs
;
745 PrefProvider::RegisterProfilePrefs(prefs
.registry());
747 ContentSettingsPattern pattern_1
=
748 ContentSettingsPattern::FromString("google.com");
749 ContentSettingsPattern pattern_2
=
750 ContentSettingsPattern::FromString("www.google.com");
751 ContentSettingsPattern wildcard
=
752 ContentSettingsPattern::FromString("*");
753 scoped_ptr
<base::Value
> value(
754 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
756 // Create a normal provider and set a setting.
757 PrefProvider
normal_provider(&prefs
, false);
758 normal_provider
.SetWebsiteSetting(pattern_1
,
760 CONTENT_SETTINGS_TYPE_IMAGES
,
764 // Non-OTR provider, Non-OTR iterator has one setting (pattern 1).
766 scoped_ptr
<RuleIterator
> it (normal_provider
.GetRuleIterator(
767 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), false));
768 EXPECT_TRUE(it
->HasNext());
769 EXPECT_EQ(pattern_1
, it
->Next().primary_pattern
);
770 EXPECT_FALSE(it
->HasNext());
773 // Non-OTR provider, OTR iterator has no settings.
775 scoped_ptr
<RuleIterator
> it(normal_provider
.GetRuleIterator(
776 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), true));
777 EXPECT_FALSE(it
->HasNext());
780 // Create an incognito provider and set a setting.
781 PrefProvider
incognito_provider(&prefs
, true);
782 incognito_provider
.SetWebsiteSetting(pattern_2
,
784 CONTENT_SETTINGS_TYPE_IMAGES
,
788 // OTR provider, non-OTR iterator has one setting (pattern 1).
790 scoped_ptr
<RuleIterator
> it(incognito_provider
.GetRuleIterator(
791 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), false));
792 EXPECT_TRUE(it
->HasNext());
793 EXPECT_EQ(pattern_1
, it
->Next().primary_pattern
);
794 EXPECT_FALSE(it
->HasNext());
797 // OTR provider, OTR iterator has one setting (pattern 2).
799 scoped_ptr
<RuleIterator
> it(incognito_provider
.GetRuleIterator(
800 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), true));
801 EXPECT_TRUE(it
->HasNext());
802 EXPECT_EQ(pattern_2
, it
->Next().primary_pattern
);
803 EXPECT_FALSE(it
->HasNext());
806 incognito_provider
.ShutdownOnUIThread();
807 normal_provider
.ShutdownOnUIThread();
810 TEST_F(PrefProviderTest
, ClearAllContentSettingsRules
) {
811 TestingPrefServiceSyncable prefs
;
812 PrefProvider::RegisterProfilePrefs(prefs
.registry());
814 ContentSettingsPattern pattern
=
815 ContentSettingsPattern::FromString("google.com");
816 ContentSettingsPattern wildcard
=
817 ContentSettingsPattern::FromString("*");
818 scoped_ptr
<base::Value
> value(
819 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
820 ResourceIdentifier
res_id("abcde");
822 PrefProvider
provider(&prefs
, false);
824 // Non-empty pattern, syncable, empty resource identifier.
825 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_IMAGES
,
826 ResourceIdentifier(), value
->DeepCopy());
828 // Non-empty pattern, non-syncable, empty resource identifier.
829 provider
.SetWebsiteSetting(pattern
, wildcard
,
830 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
831 ResourceIdentifier(), value
->DeepCopy());
833 // Non-empty pattern, plugins, non-empty resource identifier.
834 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_PLUGINS
,
835 res_id
, value
->DeepCopy());
837 // Empty pattern, plugins, non-empty resource identifier.
838 provider
.SetWebsiteSetting(wildcard
, wildcard
, CONTENT_SETTINGS_TYPE_PLUGINS
,
839 res_id
, value
->DeepCopy());
841 // Non-empty pattern, syncable, empty resource identifier.
842 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_COOKIES
,
843 ResourceIdentifier(), value
->DeepCopy());
845 // Non-empty pattern, non-syncable, empty resource identifier.
846 provider
.SetWebsiteSetting(pattern
, wildcard
,
847 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
848 ResourceIdentifier(), value
->DeepCopy());
850 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_IMAGES
);
851 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
852 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_PLUGINS
);
854 // Test that the new preferences for images, geolocation and plugins
856 const char* empty_prefs
[] = {
857 prefs::kContentSettingsImagesPatternPairs
,
858 prefs::kContentSettingsGeolocationPatternPairs
,
859 prefs::kContentSettingsPluginsPatternPairs
862 for (const char* pref
: empty_prefs
) {
863 DictionaryPrefUpdate
update(&prefs
, pref
);
864 const base::DictionaryValue
* dictionary
= update
.Get();
865 EXPECT_TRUE(dictionary
->empty());
868 // Test that the preferences for cookies and notifications are not empty.
869 const char* nonempty_prefs
[] = {
870 prefs::kContentSettingsCookiesPatternPairs
,
871 prefs::kContentSettingsNotificationsPatternPairs
874 for (const char* pref
: nonempty_prefs
) {
875 DictionaryPrefUpdate
update(&prefs
, pref
);
876 const base::DictionaryValue
* dictionary
= update
.Get();
877 EXPECT_EQ(1u, dictionary
->size());
880 // Test that the old preference only contains cookies and notifications.
882 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
883 const base::DictionaryValue
* dictionary
= update
.Get();
884 const base::DictionaryValue
* exception
;
885 EXPECT_TRUE(dictionary
->GetDictionaryWithoutPathExpansion(
886 CreatePatternString(pattern
, wildcard
), &exception
));
887 EXPECT_EQ(1u, exception
->size());
888 EXPECT_TRUE(exception
->HasKey(GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES
)));
890 // The notification setting was not cleared, but it was also never written
891 // to the old preference, as it is unsyncable.
894 provider
.ShutdownOnUIThread();
897 } // namespace content_settings