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 which did not need to be migrated.
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 exceptions for new content settings types added after the migration.
493 exceptions
->SetIntegerWithoutPathExpansion(
494 GetTypeName(CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT
),
495 CONTENT_SETTING_ALLOW
);
497 // Add a regular exception for plugins, then one with a resource identifier.
498 exceptions
->SetIntegerWithoutPathExpansion(
499 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS
), CONTENT_SETTING_ALLOW
);
500 plugin_resources
->SetIntegerWithoutPathExpansion(
501 resource_id
, CONTENT_SETTING_BLOCK
);
502 exceptions
->SetWithoutPathExpansion(
503 "per_plugin", plugin_resources
);
505 // Change the old dictionary preference and observe changes
506 // in the new preferences.
508 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
509 base::DictionaryValue
* old_dictionary
= update
.Get();
510 old_dictionary
->SetWithoutPathExpansion(pattern
, exceptions
);
513 // The images exception was synced.
515 DictionaryPrefUpdate
update(
516 &prefs
, prefs::kContentSettingsImagesPatternPairs
);
517 const base::DictionaryValue
* images_dictionary
= update
.Get();
519 EXPECT_EQ(1u, images_dictionary
->size());
520 const base::DictionaryValue
* images_exception
;
521 EXPECT_TRUE(images_dictionary
->GetDictionaryWithoutPathExpansion(
522 pattern
, &images_exception
));
524 // And it has a correct value.
525 int images_exception_value
= CONTENT_SETTING_DEFAULT
;
526 EXPECT_TRUE(images_exception
->GetIntegerWithoutPathExpansion(
527 "setting", &images_exception_value
));
528 EXPECT_EQ(CONTENT_SETTING_ALLOW
, images_exception_value
);
531 // The app banner exception was not synced.
533 DictionaryPrefUpdate
update(
534 &prefs
, prefs::kContentSettingsAppBannerPatternPairs
);
535 const base::DictionaryValue
* app_banner_dictionary
= update
.Get();
536 EXPECT_TRUE(app_banner_dictionary
->empty());
539 // The plugins exception was synced, together with the resource identifiers.
541 DictionaryPrefUpdate
update(
542 &prefs
, prefs::kContentSettingsPluginsPatternPairs
);
543 const base::DictionaryValue
* plugins_dictionary
= update
.Get();
544 EXPECT_EQ(1u, plugins_dictionary
->size());
546 const base::DictionaryValue
* plugins_exception
;
547 EXPECT_TRUE(plugins_dictionary
->GetDictionaryWithoutPathExpansion(
548 pattern
, &plugins_exception
));
550 int plugins_exception_value
= CONTENT_SETTING_DEFAULT
;
551 EXPECT_TRUE(plugins_exception
->GetIntegerWithoutPathExpansion(
552 "setting", &plugins_exception_value
));
553 EXPECT_EQ(CONTENT_SETTING_ALLOW
, plugins_exception_value
);
555 int resource_exception_value
= CONTENT_SETTING_DEFAULT
;
556 const base::DictionaryValue
* resource_exception
;
557 EXPECT_TRUE(plugins_exception
->GetDictionaryWithoutPathExpansion(
558 "per_resource", &resource_exception
));
559 EXPECT_TRUE(resource_exception
->GetIntegerWithoutPathExpansion(
560 resource_id
, &resource_exception_value
));
561 EXPECT_EQ(CONTENT_SETTING_BLOCK
, resource_exception_value
);
564 provider
.ShutdownOnUIThread();
567 TEST_F(PrefProviderTest
, SyncingNewToOld
) {
568 TestingPrefServiceSyncable prefs
;
569 PrefProvider::RegisterProfilePrefs(prefs
.registry());
570 PrefProvider
provider(&prefs
, false);
572 const std::string pattern
= "google.com,*";
573 const std::string resource_id
= "abcde12345";
574 base::DictionaryValue block_exception
;
575 block_exception
.SetIntegerWithoutPathExpansion(
576 "setting", CONTENT_SETTING_BLOCK
);
578 // Add a mouselock exception.
580 DictionaryPrefUpdate
update(
581 &prefs
, prefs::kContentSettingsMouseLockPatternPairs
);
582 base::DictionaryValue
* mouselock_dictionary
= update
.Get();
584 mouselock_dictionary
->SetWithoutPathExpansion(
585 pattern
, block_exception
.DeepCopy());
588 // Add a microphone exception.
590 DictionaryPrefUpdate
update(
591 &prefs
, prefs::kContentSettingsMediaStreamMicPatternPairs
);
592 base::DictionaryValue
* microphone_dictionary
= update
.Get();
594 microphone_dictionary
->SetWithoutPathExpansion(
595 pattern
, block_exception
.DeepCopy());
598 // Add a plugin exception with resource identifiers.
600 DictionaryPrefUpdate
update(
601 &prefs
, prefs::kContentSettingsPluginsPatternPairs
);
602 base::DictionaryValue
* plugins_dictionary
= update
.Get();
604 base::DictionaryValue
* plugin_exception
= block_exception
.DeepCopy();
605 plugins_dictionary
->SetWithoutPathExpansion(
606 pattern
, plugin_exception
);
608 base::DictionaryValue
* resource_exception
= new base::DictionaryValue();
609 resource_exception
->SetIntegerWithoutPathExpansion(
610 resource_id
, CONTENT_SETTING_ALLOW
);
612 plugin_exception
->SetWithoutPathExpansion(
613 "per_resource", resource_exception
);
616 // Only the notifications and plugin exceptions should appear in the
617 // old dictionary. We should also have a resource identifiers section
620 DictionaryPrefUpdate
update(
621 &prefs
, prefs::kContentSettingsPatternPairs
);
622 const base::DictionaryValue
* old_dictionary
= update
.Get();
624 const base::DictionaryValue
* exception
;
625 EXPECT_TRUE(old_dictionary
->GetDictionaryWithoutPathExpansion(
626 pattern
, &exception
));
627 EXPECT_EQ(3u, exception
->size());
628 EXPECT_FALSE(exception
->HasKey(
629 GetTypeName(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
)));
631 int mouselock_exception_value
= CONTENT_SETTING_DEFAULT
;
632 exception
->GetIntegerWithoutPathExpansion(
633 GetTypeName(CONTENT_SETTINGS_TYPE_MOUSELOCK
),
634 &mouselock_exception_value
);
635 DCHECK_EQ(CONTENT_SETTING_BLOCK
, mouselock_exception_value
);
637 int plugins_exception_value
= CONTENT_SETTING_DEFAULT
;
638 exception
->GetIntegerWithoutPathExpansion(
639 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS
),
640 &plugins_exception_value
);
641 DCHECK_EQ(CONTENT_SETTING_BLOCK
, plugins_exception_value
);
643 int resource_exception_value
= CONTENT_SETTING_DEFAULT
;
644 const base::DictionaryValue
* resource_values
;
645 exception
->GetDictionaryWithoutPathExpansion(
646 "per_plugin", &resource_values
);
647 resource_values
->GetIntegerWithoutPathExpansion(
648 resource_id
, &resource_exception_value
);
649 DCHECK_EQ(CONTENT_SETTING_ALLOW
, resource_exception_value
);
652 provider
.ShutdownOnUIThread();
655 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
656 TEST_F(PrefProviderTest
, PMIMigrateOnlyAllow
) {
657 TestingPrefServiceSyncable prefs
;
658 PrefProvider::RegisterProfilePrefs(prefs
.registry());
660 const std::string pattern_1
= "google.com,*";
661 const std::string pattern_2
= "www.google.com,*";
662 base::DictionaryValue
* exception_1
= new base::DictionaryValue();
663 base::DictionaryValue
* exception_2
= new base::DictionaryValue();
665 // Add both an "allow" and "block" exception for PMI.
666 exception_1
->SetIntegerWithoutPathExpansion(
667 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
),
668 CONTENT_SETTING_ALLOW
);
669 exception_2
->SetIntegerWithoutPathExpansion(
670 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
),
671 CONTENT_SETTING_BLOCK
);
673 // Change the old dictionary preference.
675 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
676 base::DictionaryValue
* old_dictionary
= update
.Get();
677 old_dictionary
->SetWithoutPathExpansion(pattern_1
, exception_1
);
678 old_dictionary
->SetWithoutPathExpansion(pattern_2
, exception_2
);
681 // Create the PrefProvider. It should migrate the settings.
682 PrefProvider
provider(&prefs
, false);
684 // The "block" exception for PMI was migrated, but "allow" was not.
686 DictionaryPrefUpdate
update(
687 &prefs
, prefs::kContentSettingsProtectedMediaIdentifierPatternPairs
);
688 const base::DictionaryValue
* pmi_dictionary
= update
.Get();
689 EXPECT_FALSE(pmi_dictionary
->HasKey(pattern_1
));
690 EXPECT_TRUE(pmi_dictionary
->HasKey(pattern_2
));
693 provider
.ShutdownOnUIThread();
697 TEST_F(PrefProviderTest
, PrefsMigrateVerbatim
) {
698 TestingPrefServiceSyncable prefs
;
699 PrefProvider::RegisterProfilePrefs(prefs
.registry());
701 const std::string pattern_1
= "google.com,*";
702 const std::string pattern_2
= "www.google.com,*";
703 base::DictionaryValue
* exception_1
= new base::DictionaryValue();
704 base::DictionaryValue
* exception_2
= new base::DictionaryValue();
705 scoped_ptr
<base::DictionaryValue
> old_dictionary
;
707 // Add two exceptions.
708 exception_1
->SetIntegerWithoutPathExpansion(
709 GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES
),
710 CONTENT_SETTING_ALLOW
);
711 exception_2
->SetIntegerWithoutPathExpansion(
712 GetTypeName(CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
),
713 CONTENT_SETTING_BLOCK
);
715 // Change the old dictionary preference.
717 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
718 base::DictionaryValue
* dictionary
= update
.Get();
719 dictionary
->SetWithoutPathExpansion(pattern_1
, exception_1
);
720 dictionary
->SetWithoutPathExpansion(pattern_2
, exception_2
);
721 old_dictionary
.reset(dictionary
->DeepCopy());
724 // Create the PrefProvider. It should copy the settings from the old
725 // preference to the new ones.
726 PrefProvider
provider(&prefs
, false);
728 // Force copying back from the new preferences to the old one.
730 DictionaryPrefUpdate
update(
731 &prefs
, prefs::kContentSettingsCookiesPatternPairs
);
734 DictionaryPrefUpdate
update(
735 &prefs
, prefs::kContentSettingsAutomaticDownloadsPatternPairs
);
738 // Test if the value after copying there and back is the same.
740 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
741 base::DictionaryValue
* new_dictionary
= update
.Get();
742 EXPECT_TRUE(old_dictionary
->Equals(new_dictionary
));
745 provider
.ShutdownOnUIThread();
748 TEST_F(PrefProviderTest
, IncognitoInheritsValueMap
) {
749 TestingPrefServiceSyncable prefs
;
750 PrefProvider::RegisterProfilePrefs(prefs
.registry());
752 ContentSettingsPattern pattern_1
=
753 ContentSettingsPattern::FromString("google.com");
754 ContentSettingsPattern pattern_2
=
755 ContentSettingsPattern::FromString("www.google.com");
756 ContentSettingsPattern wildcard
=
757 ContentSettingsPattern::FromString("*");
758 scoped_ptr
<base::Value
> value(
759 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
761 // Create a normal provider and set a setting.
762 PrefProvider
normal_provider(&prefs
, false);
763 normal_provider
.SetWebsiteSetting(pattern_1
,
765 CONTENT_SETTINGS_TYPE_IMAGES
,
769 // Non-OTR provider, Non-OTR iterator has one setting (pattern 1).
771 scoped_ptr
<RuleIterator
> it(normal_provider
.GetRuleIterator(
772 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), false));
773 EXPECT_TRUE(it
->HasNext());
774 EXPECT_EQ(pattern_1
, it
->Next().primary_pattern
);
775 EXPECT_FALSE(it
->HasNext());
778 // Non-OTR provider, OTR iterator has no settings.
780 scoped_ptr
<RuleIterator
> it(normal_provider
.GetRuleIterator(
781 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), true));
782 EXPECT_FALSE(it
->HasNext());
785 // Create an incognito provider and set a setting.
786 PrefProvider
incognito_provider(&prefs
, true);
787 incognito_provider
.SetWebsiteSetting(pattern_2
,
789 CONTENT_SETTINGS_TYPE_IMAGES
,
793 // OTR provider, non-OTR iterator has one setting (pattern 1).
795 scoped_ptr
<RuleIterator
> it(incognito_provider
.GetRuleIterator(
796 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), false));
797 EXPECT_TRUE(it
->HasNext());
798 EXPECT_EQ(pattern_1
, it
->Next().primary_pattern
);
799 EXPECT_FALSE(it
->HasNext());
802 // OTR provider, OTR iterator has one setting (pattern 2).
804 scoped_ptr
<RuleIterator
> it(incognito_provider
.GetRuleIterator(
805 CONTENT_SETTINGS_TYPE_IMAGES
, std::string(), true));
806 EXPECT_TRUE(it
->HasNext());
807 EXPECT_EQ(pattern_2
, it
->Next().primary_pattern
);
808 EXPECT_FALSE(it
->HasNext());
811 incognito_provider
.ShutdownOnUIThread();
812 normal_provider
.ShutdownOnUIThread();
815 TEST_F(PrefProviderTest
, ClearAllContentSettingsRules
) {
816 TestingPrefServiceSyncable prefs
;
817 PrefProvider::RegisterProfilePrefs(prefs
.registry());
819 ContentSettingsPattern pattern
=
820 ContentSettingsPattern::FromString("google.com");
821 ContentSettingsPattern wildcard
=
822 ContentSettingsPattern::FromString("*");
823 scoped_ptr
<base::Value
> value(
824 new base::FundamentalValue(CONTENT_SETTING_ALLOW
));
825 ResourceIdentifier
res_id("abcde");
827 PrefProvider
provider(&prefs
, false);
829 // Non-empty pattern, syncable, empty resource identifier.
830 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_IMAGES
,
831 ResourceIdentifier(), value
->DeepCopy());
833 // Non-empty pattern, non-syncable, empty resource identifier.
834 provider
.SetWebsiteSetting(pattern
, wildcard
,
835 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
836 ResourceIdentifier(), value
->DeepCopy());
838 // Non-empty pattern, plugins, non-empty resource identifier.
839 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_PLUGINS
,
840 res_id
, value
->DeepCopy());
842 // Empty pattern, plugins, non-empty resource identifier.
843 provider
.SetWebsiteSetting(wildcard
, wildcard
, CONTENT_SETTINGS_TYPE_PLUGINS
,
844 res_id
, value
->DeepCopy());
846 // Non-empty pattern, syncable, empty resource identifier.
847 provider
.SetWebsiteSetting(pattern
, wildcard
, CONTENT_SETTINGS_TYPE_COOKIES
,
848 ResourceIdentifier(), value
->DeepCopy());
850 // Non-empty pattern, non-syncable, empty resource identifier.
851 provider
.SetWebsiteSetting(pattern
, wildcard
,
852 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
853 ResourceIdentifier(), value
->DeepCopy());
855 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_IMAGES
);
856 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
857 provider
.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_PLUGINS
);
859 // Test that the new preferences for images, geolocation and plugins
861 const char* empty_prefs
[] = {
862 prefs::kContentSettingsImagesPatternPairs
,
863 prefs::kContentSettingsGeolocationPatternPairs
,
864 prefs::kContentSettingsPluginsPatternPairs
867 for (const char* pref
: empty_prefs
) {
868 DictionaryPrefUpdate
update(&prefs
, pref
);
869 const base::DictionaryValue
* dictionary
= update
.Get();
870 EXPECT_TRUE(dictionary
->empty());
873 // Test that the preferences for cookies and notifications are not empty.
874 const char* nonempty_prefs
[] = {
875 prefs::kContentSettingsCookiesPatternPairs
,
876 prefs::kContentSettingsNotificationsPatternPairs
879 for (const char* pref
: nonempty_prefs
) {
880 DictionaryPrefUpdate
update(&prefs
, pref
);
881 const base::DictionaryValue
* dictionary
= update
.Get();
882 EXPECT_EQ(1u, dictionary
->size());
885 // Test that the old preference only contains cookies and notifications.
887 DictionaryPrefUpdate
update(&prefs
, prefs::kContentSettingsPatternPairs
);
888 const base::DictionaryValue
* dictionary
= update
.Get();
889 const base::DictionaryValue
* exception
;
890 EXPECT_TRUE(dictionary
->GetDictionaryWithoutPathExpansion(
891 CreatePatternString(pattern
, wildcard
), &exception
));
892 EXPECT_EQ(1u, exception
->size());
893 EXPECT_TRUE(exception
->HasKey(GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES
)));
895 // The notification setting was not cleared, but it was also never written
896 // to the old preference, as it is unsyncable.
899 provider
.ShutdownOnUIThread();
902 } // namespace content_settings