Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_pref_provider_unittest.cc
blobdf6826558778e3167180863524dea1b137829ecd
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 "chrome/browser/content_settings/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/content_settings/content_settings_utils.h"
22 #include "chrome/browser/prefs/browser_prefs.h"
23 #include "chrome/browser/prefs/pref_service_mock_factory.h"
24 #include "chrome/browser/prefs/pref_service_syncable.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/test/base/testing_pref_service_syncable.h"
29 #include "chrome/test/base/testing_profile.h"
30 #include "components/pref_registry/pref_registry_syncable.h"
31 #include "content/public/test/test_browser_thread.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "url/gurl.h"
35 using ::testing::_;
36 using content::BrowserThread;
38 namespace content_settings {
40 class DeadlockCheckerThread : public base::PlatformThread::Delegate {
41 public:
42 explicit DeadlockCheckerThread(PrefProvider* provider)
43 : provider_(provider) {}
45 virtual void ThreadMain() override {
46 bool got_lock = provider_->lock_.Try();
47 EXPECT_TRUE(got_lock);
48 if (got_lock)
49 provider_->lock_.Release();
51 private:
52 PrefProvider* provider_;
53 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerThread);
56 // A helper for observing an preference changes and testing whether
57 // |PrefProvider| holds a lock when the preferences change.
58 class DeadlockCheckerObserver {
59 public:
60 // |DeadlockCheckerObserver| doesn't take the ownership of |prefs| or
61 // ||provider|.
62 DeadlockCheckerObserver(PrefService* prefs, PrefProvider* provider)
63 : provider_(provider),
64 notification_received_(false) {
65 pref_change_registrar_.Init(prefs);
66 pref_change_registrar_.Add(
67 prefs::kContentSettingsPatternPairs,
68 base::Bind(
69 &DeadlockCheckerObserver::OnContentSettingsPatternPairsChanged,
70 base::Unretained(this)));
72 virtual ~DeadlockCheckerObserver() {}
74 bool notification_received() const {
75 return notification_received_;
78 private:
79 void OnContentSettingsPatternPairsChanged() {
80 // Check whether |provider_| holds its lock. For this, we need a
81 // separate thread.
82 DeadlockCheckerThread thread(provider_);
83 base::PlatformThreadHandle handle;
84 ASSERT_TRUE(base::PlatformThread::Create(0, &thread, &handle));
85 base::PlatformThread::Join(handle);
86 notification_received_ = true;
89 PrefProvider* provider_;
90 PrefChangeRegistrar pref_change_registrar_;
91 bool notification_received_;
92 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerObserver);
95 class PrefProviderTest : public testing::Test {
96 public:
97 PrefProviderTest() : ui_thread_(
98 BrowserThread::UI, &message_loop_) {
101 protected:
102 base::MessageLoop message_loop_;
103 content::TestBrowserThread ui_thread_;
106 TEST_F(PrefProviderTest, Observer) {
107 TestingProfile profile;
108 PrefProvider pref_content_settings_provider(profile.GetPrefs(), false);
110 ContentSettingsPattern pattern =
111 ContentSettingsPattern::FromString("[*.]example.com");
112 content_settings::MockObserver mock_observer;
113 EXPECT_CALL(mock_observer,
114 OnContentSettingChanged(pattern,
115 ContentSettingsPattern::Wildcard(),
116 CONTENT_SETTINGS_TYPE_IMAGES,
117 ""));
119 pref_content_settings_provider.AddObserver(&mock_observer);
121 pref_content_settings_provider.SetWebsiteSetting(
122 pattern,
123 ContentSettingsPattern::Wildcard(),
124 CONTENT_SETTINGS_TYPE_IMAGES,
125 std::string(),
126 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
128 pref_content_settings_provider.ShutdownOnUIThread();
131 // Test for regression in which the PrefProvider modified the user pref store
132 // of the OTR unintentionally: http://crbug.com/74466.
133 TEST_F(PrefProviderTest, Incognito) {
134 PersistentPrefStore* user_prefs = new TestingPrefStore();
135 OverlayUserPrefStore* otr_user_prefs =
136 new OverlayUserPrefStore(user_prefs);
138 PrefServiceMockFactory factory;
139 factory.set_user_prefs(make_scoped_refptr(user_prefs));
140 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
141 new user_prefs::PrefRegistrySyncable);
142 PrefServiceSyncable* regular_prefs =
143 factory.CreateSyncable(registry.get()).release();
145 chrome::RegisterUserProfilePrefs(registry.get());
147 PrefServiceMockFactory otr_factory;
148 otr_factory.set_user_prefs(make_scoped_refptr(otr_user_prefs));
149 scoped_refptr<user_prefs::PrefRegistrySyncable> otr_registry(
150 new user_prefs::PrefRegistrySyncable);
151 PrefServiceSyncable* otr_prefs =
152 otr_factory.CreateSyncable(otr_registry.get()).release();
154 chrome::RegisterUserProfilePrefs(otr_registry.get());
156 TestingProfile::Builder profile_builder;
157 profile_builder.SetPrefService(make_scoped_ptr(regular_prefs));
158 scoped_ptr<TestingProfile> profile = profile_builder.Build();
160 TestingProfile::Builder otr_profile_builder;
161 otr_profile_builder.SetPrefService(make_scoped_ptr(otr_prefs));
162 otr_profile_builder.BuildIncognito(profile.get());
164 PrefProvider pref_content_settings_provider(regular_prefs, false);
165 PrefProvider pref_content_settings_provider_incognito(otr_prefs, true);
166 ContentSettingsPattern pattern =
167 ContentSettingsPattern::FromString("[*.]example.com");
168 pref_content_settings_provider.SetWebsiteSetting(
169 pattern,
170 pattern,
171 CONTENT_SETTINGS_TYPE_IMAGES,
172 std::string(),
173 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
175 GURL host("http://example.com/");
176 // The value should of course be visible in the regular PrefProvider.
177 EXPECT_EQ(CONTENT_SETTING_ALLOW,
178 GetContentSetting(&pref_content_settings_provider,
179 host,
180 host,
181 CONTENT_SETTINGS_TYPE_IMAGES,
182 std::string(),
183 false));
184 // And also in the OTR version.
185 EXPECT_EQ(CONTENT_SETTING_ALLOW,
186 GetContentSetting(&pref_content_settings_provider_incognito,
187 host,
188 host,
189 CONTENT_SETTINGS_TYPE_IMAGES,
190 std::string(),
191 false));
192 // But the value should not be overridden in the OTR user prefs accidentally.
193 EXPECT_FALSE(otr_user_prefs->IsSetInOverlay(
194 prefs::kContentSettingsPatternPairs));
196 pref_content_settings_provider.ShutdownOnUIThread();
197 pref_content_settings_provider_incognito.ShutdownOnUIThread();
200 TEST_F(PrefProviderTest, GetContentSettingsValue) {
201 TestingProfile testing_profile;
202 PrefProvider provider(testing_profile.GetPrefs(), false);
204 GURL primary_url("http://example.com/");
205 ContentSettingsPattern primary_pattern =
206 ContentSettingsPattern::FromString("[*.]example.com");
208 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
209 GetContentSetting(&provider,
210 primary_url,
211 primary_url,
212 CONTENT_SETTINGS_TYPE_IMAGES,
213 std::string(),
214 false));
216 EXPECT_EQ(NULL,
217 GetContentSettingValue(&provider,
218 primary_url,
219 primary_url,
220 CONTENT_SETTINGS_TYPE_IMAGES,
221 std::string(),
222 false));
224 provider.SetWebsiteSetting(primary_pattern,
225 primary_pattern,
226 CONTENT_SETTINGS_TYPE_IMAGES,
227 std::string(),
228 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
229 EXPECT_EQ(CONTENT_SETTING_BLOCK,
230 GetContentSetting(&provider,
231 primary_url,
232 primary_url,
233 CONTENT_SETTINGS_TYPE_IMAGES,
234 std::string(),
235 false));
236 scoped_ptr<base::Value> value_ptr(
237 GetContentSettingValue(&provider,
238 primary_url,
239 primary_url,
240 CONTENT_SETTINGS_TYPE_IMAGES,
241 std::string(),
242 false));
243 int int_value = -1;
244 value_ptr->GetAsInteger(&int_value);
245 EXPECT_EQ(CONTENT_SETTING_BLOCK, IntToContentSetting(int_value));
247 provider.SetWebsiteSetting(primary_pattern,
248 primary_pattern,
249 CONTENT_SETTINGS_TYPE_IMAGES,
250 std::string(),
251 NULL);
252 EXPECT_EQ(NULL,
253 GetContentSettingValue(&provider,
254 primary_url,
255 primary_url,
256 CONTENT_SETTINGS_TYPE_IMAGES,
257 std::string(),
258 false));
259 provider.ShutdownOnUIThread();
262 TEST_F(PrefProviderTest, Patterns) {
263 TestingProfile testing_profile;
264 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
265 false);
267 GURL host1("http://example.com/");
268 GURL host2("http://www.example.com/");
269 GURL host3("http://example.org/");
270 GURL host4("file:///tmp/test.html");
271 ContentSettingsPattern pattern1 =
272 ContentSettingsPattern::FromString("[*.]example.com");
273 ContentSettingsPattern pattern2 =
274 ContentSettingsPattern::FromString("example.org");
275 ContentSettingsPattern pattern3 =
276 ContentSettingsPattern::FromString("file:///tmp/test.html");
278 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
279 GetContentSetting(&pref_content_settings_provider,
280 host1,
281 host1,
282 CONTENT_SETTINGS_TYPE_IMAGES,
283 std::string(),
284 false));
285 pref_content_settings_provider.SetWebsiteSetting(
286 pattern1,
287 pattern1,
288 CONTENT_SETTINGS_TYPE_IMAGES,
289 std::string(),
290 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
291 EXPECT_EQ(CONTENT_SETTING_BLOCK,
292 GetContentSetting(&pref_content_settings_provider,
293 host1,
294 host1,
295 CONTENT_SETTINGS_TYPE_IMAGES,
296 std::string(),
297 false));
298 EXPECT_EQ(CONTENT_SETTING_BLOCK,
299 GetContentSetting(&pref_content_settings_provider,
300 host2,
301 host2,
302 CONTENT_SETTINGS_TYPE_IMAGES,
303 std::string(),
304 false));
306 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
307 GetContentSetting(&pref_content_settings_provider,
308 host3,
309 host3,
310 CONTENT_SETTINGS_TYPE_IMAGES,
311 std::string(),
312 false));
313 pref_content_settings_provider.SetWebsiteSetting(
314 pattern2,
315 pattern2,
316 CONTENT_SETTINGS_TYPE_IMAGES,
317 std::string(),
318 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
319 EXPECT_EQ(CONTENT_SETTING_BLOCK,
320 GetContentSetting(&pref_content_settings_provider,
321 host3,
322 host3,
323 CONTENT_SETTINGS_TYPE_IMAGES,
324 std::string(),
325 false));
327 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
328 GetContentSetting(&pref_content_settings_provider,
329 host4,
330 host4,
331 CONTENT_SETTINGS_TYPE_IMAGES,
332 std::string(),
333 false));
334 pref_content_settings_provider.SetWebsiteSetting(
335 pattern3,
336 pattern3,
337 CONTENT_SETTINGS_TYPE_IMAGES,
338 std::string(),
339 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
340 EXPECT_EQ(CONTENT_SETTING_BLOCK,
341 GetContentSetting(&pref_content_settings_provider,
342 host4,
343 host4,
344 CONTENT_SETTINGS_TYPE_IMAGES,
345 std::string(),
346 false));
348 pref_content_settings_provider.ShutdownOnUIThread();
351 TEST_F(PrefProviderTest, ResourceIdentifier) {
352 TestingProfile testing_profile;
353 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
354 false);
356 GURL host("http://example.com/");
357 ContentSettingsPattern pattern =
358 ContentSettingsPattern::FromString("[*.]example.com");
359 std::string resource1("someplugin");
360 std::string resource2("otherplugin");
362 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
363 GetContentSetting(
364 &pref_content_settings_provider,
365 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
366 resource1, false));
367 pref_content_settings_provider.SetWebsiteSetting(
368 pattern,
369 pattern,
370 CONTENT_SETTINGS_TYPE_PLUGINS,
371 resource1,
372 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
373 EXPECT_EQ(CONTENT_SETTING_BLOCK,
374 GetContentSetting(
375 &pref_content_settings_provider,
376 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
377 resource1, false));
378 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
379 GetContentSetting(
380 &pref_content_settings_provider,
381 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
382 resource2, false));
384 pref_content_settings_provider.ShutdownOnUIThread();
387 TEST_F(PrefProviderTest, AutoSubmitCertificateContentSetting) {
388 TestingProfile profile;
389 TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
390 GURL primary_url("https://www.example.com");
391 GURL secondary_url("https://www.sample.com");
393 PrefProvider provider(prefs, false);
395 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
396 GetContentSetting(
397 &provider,
398 primary_url,
399 primary_url,
400 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
401 std::string(),
402 false));
404 provider.SetWebsiteSetting(ContentSettingsPattern::FromURL(primary_url),
405 ContentSettingsPattern::Wildcard(),
406 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
407 std::string(),
408 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
409 EXPECT_EQ(CONTENT_SETTING_ALLOW,
410 GetContentSetting(
411 &provider,
412 primary_url,
413 secondary_url,
414 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
415 std::string(),
416 false));
417 provider.ShutdownOnUIThread();
420 // http://crosbug.com/17760
421 TEST_F(PrefProviderTest, Deadlock) {
422 TestingPrefServiceSyncable prefs;
423 PrefProvider::RegisterProfilePrefs(prefs.registry());
425 // Chain of events: a preference changes, |PrefProvider| notices it, and reads
426 // and writes the preference. When the preference is written, a notification
427 // is sent, and this used to happen when |PrefProvider| was still holding its
428 // lock.
430 PrefProvider provider(&prefs, false);
431 DeadlockCheckerObserver observer(&prefs, &provider);
433 DictionaryPrefUpdate update(&prefs,
434 prefs::kContentSettingsPatternPairs);
435 base::DictionaryValue* mutable_settings = update.Get();
436 mutable_settings->SetWithoutPathExpansion("www.example.com,*",
437 new base::DictionaryValue());
439 EXPECT_TRUE(observer.notification_received());
441 provider.ShutdownOnUIThread();
444 TEST_F(PrefProviderTest, LastUsage) {
445 TestingProfile testing_profile;
446 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
447 false);
448 base::SimpleTestClock* test_clock = new base::SimpleTestClock;
449 test_clock->SetNow(base::Time::Now());
451 pref_content_settings_provider.SetClockForTesting(
452 scoped_ptr<base::Clock>(test_clock));
453 GURL host("http://example.com/");
454 ContentSettingsPattern pattern =
455 ContentSettingsPattern::FromString("[*.]example.com");
457 base::Time no_usage = pref_content_settings_provider.GetLastUsage(
458 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
459 EXPECT_EQ(no_usage.ToDoubleT(), 0);
461 pref_content_settings_provider.UpdateLastUsage(
462 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
463 base::Time first = pref_content_settings_provider.GetLastUsage(
464 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
466 test_clock->Advance(base::TimeDelta::FromSeconds(10));
468 pref_content_settings_provider.UpdateLastUsage(
469 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
470 base::Time second = pref_content_settings_provider.GetLastUsage(
471 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
473 base::TimeDelta delta = second - first;
474 EXPECT_EQ(delta.InSeconds(), 10);
476 pref_content_settings_provider.ShutdownOnUIThread();
479 } // namespace content_settings