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. 4 5#include "base/command_line.h" 6#include "base/path_service.h" 7#include "base/strings/stringprintf.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/chrome_notification_types.h" 10#include "chrome/browser/content_settings/cookie_settings.h" 11#include "chrome/browser/content_settings/host_content_settings_map.h" 12#include "chrome/browser/content_settings/tab_specific_content_settings.h" 13#include "chrome/browser/net/url_request_mock_util.h" 14#include "chrome/browser/plugins/chrome_plugin_service_filter.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/ui/browser.h" 17#include "chrome/browser/ui/browser_commands.h" 18#include "chrome/browser/ui/tabs/tab_strip_model.h" 19#include "chrome/common/chrome_switches.h" 20#include "chrome/common/render_messages.h" 21#include "chrome/test/base/in_process_browser_test.h" 22#include "chrome/test/base/test_switches.h" 23#include "chrome/test/base/ui_test_utils.h" 24#include "content/public/browser/browser_thread.h" 25#include "content/public/browser/notification_observer.h" 26#include "content/public/browser/notification_service.h" 27#include "content/public/browser/plugin_service.h" 28#include "content/public/browser/render_frame_host.h" 29#include "content/public/browser/render_process_host.h" 30#include "content/public/browser/render_view_host.h" 31#include "content/public/browser/web_contents.h" 32#include "content/public/common/content_switches.h" 33#include "content/public/test/browser_test_utils.h" 34#include "content/public/test/test_utils.h" 35#include "net/test/spawned_test_server/spawned_test_server.h" 36#include "net/test/url_request/url_request_mock_http_job.h" 37 38#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 39 40#if defined(OS_MACOSX) 41#include "base/mac/scoped_nsautorelease_pool.h" 42#endif 43 44using content::BrowserThread; 45using net::URLRequestMockHTTPJob; 46 47class ContentSettingsTest : public InProcessBrowserTest { 48 public: 49 ContentSettingsTest() 50 : https_server_(net::SpawnedTestServer::TYPE_HTTPS, 51 net::SpawnedTestServer::SSLOptions( 52 net::SpawnedTestServer::SSLOptions::CERT_OK), 53 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) { 54 } 55 56 virtual void SetUpOnMainThread() OVERRIDE { 57 BrowserThread::PostTask( 58 BrowserThread::IO, FROM_HERE, 59 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); 60 } 61 62 // Check the cookie for the given URL in an incognito window. 63 void CookieCheckIncognitoWindow(const GURL& url, bool cookies_enabled) { 64 ASSERT_TRUE(content::GetCookies(browser()->profile(), url).empty()); 65 66 Browser* incognito = CreateIncognitoBrowser(); 67 ASSERT_TRUE(content::GetCookies(incognito->profile(), url).empty()); 68 ui_test_utils::NavigateToURL(incognito, url); 69 ASSERT_EQ(cookies_enabled, 70 !content::GetCookies(incognito->profile(), url).empty()); 71 72 // Ensure incognito cookies don't leak to regular profile. 73 ASSERT_TRUE(content::GetCookies(browser()->profile(), url).empty()); 74 75 // Ensure cookies get wiped after last incognito window closes. 76 content::WindowedNotificationObserver signal( 77 chrome::NOTIFICATION_BROWSER_CLOSED, 78 content::Source<Browser>(incognito)); 79 80 chrome::CloseWindow(incognito); 81 82#if defined(OS_MACOSX) 83 // BrowserWindowController depends on the auto release pool being recycled 84 // in the message loop to delete itself, which frees the Browser object 85 // which fires this event. 86 AutoreleasePool()->Recycle(); 87#endif 88 89 signal.Wait(); 90 91 incognito = CreateIncognitoBrowser(); 92 ASSERT_TRUE(content::GetCookies(incognito->profile(), url).empty()); 93 chrome::CloseWindow(incognito); 94 } 95 96 void PreBasic(const GURL& url) { 97 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 98 99 CookieCheckIncognitoWindow(url, true); 100 101 ui_test_utils::NavigateToURL(browser(), url); 102 ASSERT_FALSE(GetCookies(browser()->profile(), url).empty()); 103 } 104 105 void Basic(const GURL& url) { 106 ASSERT_FALSE(GetCookies(browser()->profile(), url).empty()); 107 } 108 109 net::SpawnedTestServer https_server_; 110}; 111 112// Sanity check on cookies before we do other tests. While these can be written 113// in content_browsertests, we want to verify Chrome's cookie storage and how it 114// handles incognito windows. 115IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BasicCookies) { 116 ASSERT_TRUE(test_server()->Start()); 117 GURL http_url = test_server()->GetURL("files/setcookie.html"); 118 PreBasic(http_url); 119} 120 121IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BasicCookies) { 122 ASSERT_TRUE(test_server()->Start()); 123 GURL http_url = test_server()->GetURL("files/setcookie.html"); 124 Basic(http_url); 125} 126 127IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BasicCookiesHttps) { 128 ASSERT_TRUE(https_server_.Start()); 129 GURL https_url = https_server_.GetURL("files/setcookie.html"); 130 PreBasic(https_url); 131} 132 133IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BasicCookiesHttps) { 134 ASSERT_TRUE(https_server_.Start()); 135 GURL https_url = https_server_.GetURL("files/setcookie.html"); 136 Basic(https_url); 137} 138 139// Verify that cookies are being blocked. 140IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BlockCookies) { 141 ASSERT_TRUE(test_server()->Start()); 142 CookieSettings::Factory::GetForProfile(browser()->profile())-> 143 SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); 144 GURL url = test_server()->GetURL("files/setcookie.html"); 145 ui_test_utils::NavigateToURL(browser(), url); 146 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 147 CookieCheckIncognitoWindow(url, false); 148} 149 150// Ensure that the setting persists. 151IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BlockCookies) { 152 ASSERT_EQ( 153 CONTENT_SETTING_BLOCK, 154 CookieSettings::Factory::GetForProfile(browser()->profile())-> 155 GetDefaultCookieSetting(NULL)); 156} 157 158// Verify that cookies can be allowed and set using exceptions for particular 159// website(s) when all others are blocked. 160IN_PROC_BROWSER_TEST_F(ContentSettingsTest, AllowCookiesUsingExceptions) { 161 ASSERT_TRUE(test_server()->Start()); 162 GURL url = test_server()->GetURL("files/setcookie.html"); 163 CookieSettings* settings = 164 CookieSettings::Factory::GetForProfile(browser()->profile()).get(); 165 settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); 166 167 ui_test_utils::NavigateToURL(browser(), url); 168 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 169 170 settings->SetCookieSetting( 171 ContentSettingsPattern::FromURL(url), 172 ContentSettingsPattern::Wildcard(), CONTENT_SETTING_ALLOW); 173 174 ui_test_utils::NavigateToURL(browser(), url); 175 ASSERT_FALSE(GetCookies(browser()->profile(), url).empty()); 176} 177 178// Verify that cookies can be blocked for a specific website using exceptions. 179IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BlockCookiesUsingExceptions) { 180 ASSERT_TRUE(test_server()->Start()); 181 GURL url = test_server()->GetURL("files/setcookie.html"); 182 CookieSettings* settings = 183 CookieSettings::Factory::GetForProfile(browser()->profile()).get(); 184 settings->SetCookieSetting(ContentSettingsPattern::FromURL(url), 185 ContentSettingsPattern::Wildcard(), 186 CONTENT_SETTING_BLOCK); 187 188 ui_test_utils::NavigateToURL(browser(), url); 189 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 190 191 ASSERT_TRUE(https_server_.Start()); 192 GURL unblocked_url = https_server_.GetURL("files/cookie1.html"); 193 194 ui_test_utils::NavigateToURL(browser(), unblocked_url); 195 ASSERT_FALSE(GetCookies(browser()->profile(), unblocked_url).empty()); 196} 197 198// This fails on ChromeOS because kRestoreOnStartup is ignored and the startup 199// preference is always "continue where I left off. 200#if !defined(OS_CHROMEOS) 201 202// Verify that cookies can be allowed and set using exceptions for particular 203// website(s) only for a session when all others are blocked. 204IN_PROC_BROWSER_TEST_F(ContentSettingsTest, 205 PRE_AllowCookiesForASessionUsingExceptions) { 206 // NOTE: don't use test_server here, since we need the port to be the same 207 // across the restart. 208 GURL url = URLRequestMockHTTPJob::GetMockUrl( 209 base::FilePath(FILE_PATH_LITERAL("setcookie.html"))); 210 CookieSettings* settings = 211 CookieSettings::Factory::GetForProfile(browser()->profile()).get(); 212 settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); 213 214 ui_test_utils::NavigateToURL(browser(), url); 215 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 216 217 settings->SetCookieSetting( 218 ContentSettingsPattern::FromURL(url), 219 ContentSettingsPattern::Wildcard(), CONTENT_SETTING_SESSION_ONLY); 220 ui_test_utils::NavigateToURL(browser(), url); 221 ASSERT_FALSE(GetCookies(browser()->profile(), url).empty()); 222} 223 224IN_PROC_BROWSER_TEST_F(ContentSettingsTest, 225 AllowCookiesForASessionUsingExceptions) { 226 GURL url = URLRequestMockHTTPJob::GetMockUrl( 227 base::FilePath(FILE_PATH_LITERAL("setcookie.html"))); 228 ASSERT_TRUE(GetCookies(browser()->profile(), url).empty()); 229} 230 231#endif // !CHROME_OS 232 233// Regression test for http://crbug.com/63649. 234IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectLoopCookies) { 235 ASSERT_TRUE(test_server()->Start()); 236 237 GURL test_url = test_server()->GetURL("files/redirect-loop.html"); 238 239 CookieSettings::Factory::GetForProfile(browser()->profile())-> 240 SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); 241 242 ui_test_utils::NavigateToURL(browser(), test_url); 243 244 content::WebContents* web_contents = 245 browser()->tab_strip_model()->GetActiveWebContents(); 246 ASSERT_EQ(base::UTF8ToUTF16(test_url.spec() + " failed to load"), 247 web_contents->GetTitle()); 248 249 EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)-> 250 IsContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES)); 251} 252 253IN_PROC_BROWSER_TEST_F(ContentSettingsTest, ContentSettingsBlockDataURLs) { 254 GURL url("data:text/html,<title>Data URL</title><script>alert(1)</script>"); 255 256 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 257 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 258 259 ui_test_utils::NavigateToURL(browser(), url); 260 261 content::WebContents* web_contents = 262 browser()->tab_strip_model()->GetActiveWebContents(); 263 ASSERT_EQ(base::UTF8ToUTF16("Data URL"), web_contents->GetTitle()); 264 265 EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)-> 266 IsContentBlocked(CONTENT_SETTINGS_TYPE_JAVASCRIPT)); 267} 268 269// Tests that if redirect across origins occurs, the new process still gets the 270// content settings before the resource headers. 271IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectCrossOrigin) { 272 ASSERT_TRUE(test_server()->Start()); 273 274 net::HostPortPair host_port = test_server()->host_port_pair(); 275 DCHECK_EQ(host_port.host(), std::string("127.0.0.1")); 276 277 std::string redirect(base::StringPrintf( 278 "http://localhost:%d/files/redirect-cross-origin.html", 279 host_port.port())); 280 GURL test_url = test_server()->GetURL("server-redirect?" + redirect); 281 282 CookieSettings::Factory::GetForProfile(browser()->profile())-> 283 SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); 284 285 ui_test_utils::NavigateToURL(browser(), test_url); 286 287 content::WebContents* web_contents = 288 browser()->tab_strip_model()->GetActiveWebContents(); 289 290 EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)-> 291 IsContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES)); 292} 293 294// On Aura NPAPI only works on Windows. 295#if !defined(USE_AURA) || defined(OS_WIN) 296 297class ClickToPlayPluginTest : public ContentSettingsTest { 298 public: 299 ClickToPlayPluginTest() {} 300 301#if defined(OS_MACOSX) 302 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 303 base::FilePath plugin_dir; 304 PathService::Get(base::DIR_MODULE, &plugin_dir); 305 plugin_dir = plugin_dir.AppendASCII("plugins"); 306 // The plugins directory isn't read by default on the Mac, so it needs to be 307 // explicitly registered. 308 command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir); 309 } 310#endif 311}; 312 313IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, Basic) { 314 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 315 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 316 317 GURL url = ui_test_utils::GetTestUrl( 318 base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html")); 319 ui_test_utils::NavigateToURL(browser(), url); 320 321 base::string16 expected_title(base::ASCIIToUTF16("OK")); 322 content::TitleWatcher title_watcher( 323 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 324 325 content::WebContents* web_contents = 326 browser()->tab_strip_model()->GetActiveWebContents(); 327 ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance(); 328 int process_id = web_contents->GetMainFrame()->GetProcess()->GetID(); 329 base::FilePath path(FILE_PATH_LITERAL("blah")); 330 EXPECT_FALSE(filter->CanLoadPlugin(process_id, path)); 331 filter->AuthorizeAllPlugins(web_contents, true, std::string()); 332 EXPECT_TRUE(filter->CanLoadPlugin(process_id, path)); 333 334 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 335} 336 337// Verify that plugins can be allowed on a domain by adding an exception 338IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, AllowException) { 339 GURL url = ui_test_utils::GetTestUrl( 340 base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html")); 341 342 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 343 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 344 browser()->profile()->GetHostContentSettingsMap() 345 ->SetContentSetting(ContentSettingsPattern::FromURL(url), 346 ContentSettingsPattern::Wildcard(), 347 CONTENT_SETTINGS_TYPE_PLUGINS, 348 std::string(), 349 CONTENT_SETTING_ALLOW); 350 351 base::string16 expected_title(base::ASCIIToUTF16("OK")); 352 content::TitleWatcher title_watcher( 353 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 354 ui_test_utils::NavigateToURL(browser(), url); 355 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 356} 357 358// Verify that plugins can be blocked on a domain by adding an exception. 359IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, BlockException) { 360 GURL url = ui_test_utils::GetTestUrl( 361 base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html")); 362 363 browser()->profile()->GetHostContentSettingsMap() 364 ->SetContentSetting(ContentSettingsPattern::FromURL(url), 365 ContentSettingsPattern::Wildcard(), 366 CONTENT_SETTINGS_TYPE_PLUGINS, 367 std::string(), 368 CONTENT_SETTING_BLOCK); 369 370 base::string16 expected_title(base::ASCIIToUTF16("Click To Play")); 371 content::TitleWatcher title_watcher( 372 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 373 ui_test_utils::NavigateToURL(browser(), url); 374 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 375} 376 377// Crashes on Mac Asan. http://crbug.com/239169 378#if defined(OS_MACOSX) 379#define MAYBE_LoadAllBlockedPlugins DISABLED_LoadAllBlockedPlugins 380// TODO(jschuh): Flaky plugin tests. crbug.com/244653 381#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64) 382#define MAYBE_LoadAllBlockedPlugins DISABLED_LoadAllBlockedPlugins 383#else 384#define MAYBE_LoadAllBlockedPlugins LoadAllBlockedPlugins 385#endif 386IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, MAYBE_LoadAllBlockedPlugins) { 387 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 388 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 389 390 GURL url = ui_test_utils::GetTestUrl( 391 base::FilePath(), 392 base::FilePath().AppendASCII("load_all_blocked_plugins.html")); 393 ui_test_utils::NavigateToURL(browser(), url); 394 395 base::string16 expected_title1(base::ASCIIToUTF16("1")); 396 content::TitleWatcher title_watcher1( 397 browser()->tab_strip_model()->GetActiveWebContents(), expected_title1); 398 399 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( 400 browser()->tab_strip_model()->GetActiveWebContents(), true, 401 std::string()); 402 EXPECT_EQ(expected_title1, title_watcher1.WaitAndGetTitle()); 403 404 base::string16 expected_title2(base::ASCIIToUTF16("2")); 405 content::TitleWatcher title_watcher2( 406 browser()->tab_strip_model()->GetActiveWebContents(), expected_title2); 407 408 ASSERT_TRUE(content::ExecuteScript( 409 browser()->tab_strip_model()->GetActiveWebContents(), "window.inject()")); 410 411 EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle()); 412} 413 414// If this flakes, use http://crbug.com/113057. 415// TODO(jschuh): Hanging plugin tests. crbug.com/244653 416#if !defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 417IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, NoCallbackAtLoad) { 418 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 419 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 420 421 GURL url("data:application/vnd.npapi-test,CallOnStartup();"); 422 ui_test_utils::NavigateToURL(browser(), url); 423 424 std::string script("CallOnStartup = function() { "); 425 script.append("document.documentElement.appendChild"); 426 script.append("(document.createElement(\"head\")); "); 427 script.append("document.title = \"OK\"; }"); 428 429 // Inject the callback function into the HTML page generated by the browser. 430 ASSERT_TRUE(content::ExecuteScript( 431 browser()->tab_strip_model()->GetActiveWebContents(), script)); 432 433 base::string16 expected_title(base::ASCIIToUTF16("OK")); 434 content::TitleWatcher title_watcher( 435 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 436 437 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( 438 browser()->tab_strip_model()->GetActiveWebContents(), true, 439 std::string()); 440 441 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 442} 443#endif 444 445IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, DeleteSelfAtLoad) { 446 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 447 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 448 449 GURL url = ui_test_utils::GetTestUrl( 450 base::FilePath(), 451 base::FilePath().AppendASCII("plugin_delete_self_at_load.html")); 452 ui_test_utils::NavigateToURL(browser(), url); 453 454 base::string16 expected_title(base::ASCIIToUTF16("OK")); 455 content::TitleWatcher title_watcher( 456 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 457 458 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( 459 browser()->tab_strip_model()->GetActiveWebContents(), true, 460 std::string()); 461 462 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 463} 464 465#endif // !defined(USE_AURA) || defined(OS_WIN) 466 467#if defined(ENABLE_PLUGINS) 468class PepperContentSettingsSpecialCasesTest : public ContentSettingsTest { 469 protected: 470 static const char* const kExternalClearKeyMimeType; 471 472 // Registers any CDM plugins not registered by default. 473 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 474#if defined(ENABLE_PEPPER_CDMS) 475 // Platform-specific filename relative to the chrome executable. 476#if defined(OS_WIN) 477 const char kLibraryName[] = "clearkeycdmadapter.dll"; 478#else // !defined(OS_WIN) 479#if defined(OS_MACOSX) 480 const char kLibraryName[] = "clearkeycdmadapter.plugin"; 481#elif defined(OS_POSIX) 482 const char kLibraryName[] = "libclearkeycdmadapter.so"; 483#endif // defined(OS_MACOSX) 484#endif // defined(OS_WIN) 485 486 // Append the switch to register the External Clear Key CDM. 487 base::FilePath::StringType pepper_plugins = BuildPepperPluginRegistration( 488 kLibraryName, "Clear Key CDM", kExternalClearKeyMimeType); 489#if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) 490 // The CDM must be registered when it is a component. 491 pepper_plugins.append(FILE_PATH_LITERAL(",")); 492 pepper_plugins.append( 493 BuildPepperPluginRegistration(kWidevineCdmAdapterFileName, 494 kWidevineCdmDisplayName, 495 kWidevineCdmPluginMimeType)); 496#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) 497 command_line->AppendSwitchNative(switches::kRegisterPepperPlugins, 498 pepper_plugins); 499#endif // defined(ENABLE_PEPPER_CDMS) 500 501#if !defined(DISABLE_NACL) 502 // Ensure NaCl can run. 503 command_line->AppendSwitch(switches::kEnableNaCl); 504#endif 505 } 506 507 void RunLoadPepperPluginTest(const char* mime_type, bool expect_loaded) { 508 const char* expected_result = expect_loaded ? "Loaded" : "Not Loaded"; 509 content::WebContents* web_contents = 510 browser()->tab_strip_model()->GetActiveWebContents(); 511 512 base::string16 expected_title(base::ASCIIToUTF16(expected_result)); 513 content::TitleWatcher title_watcher(web_contents, expected_title); 514 515 // GetTestUrl assumes paths, so we must append query parameters to result. 516 GURL file_url = ui_test_utils::GetTestUrl( 517 base::FilePath(), 518 base::FilePath().AppendASCII("load_pepper_plugin.html")); 519 GURL url(file_url.spec() + 520 base::StringPrintf("?mimetype=%s", mime_type)); 521 ui_test_utils::NavigateToURL(browser(), url); 522 523 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 524 EXPECT_EQ(!expect_loaded, 525 TabSpecificContentSettings::FromWebContents(web_contents)-> 526 IsContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS)); 527 } 528 529 void RunJavaScriptBlockedTest(const char* html_file, 530 bool expect_is_javascript_content_blocked) { 531 // Because JavaScript is blocked, <title> will be the only title set. 532 // Checking for it ensures that the page loaded, though that is not always 533 // sufficient - see below. 534 const char* const kExpectedTitle = "Initial Title"; 535 content::WebContents* web_contents = 536 browser()->tab_strip_model()->GetActiveWebContents(); 537 TabSpecificContentSettings* tab_settings = 538 TabSpecificContentSettings::FromWebContents(web_contents); 539 base::string16 expected_title(base::ASCIIToUTF16(kExpectedTitle)); 540 content::TitleWatcher title_watcher(web_contents, expected_title); 541 542 // Because JavaScript is blocked, we cannot rely on JavaScript to set a 543 // title, telling us the test is complete. 544 // As a result, it is possible to reach the IsContentBlocked() checks below 545 // before the blocked content can be reported to the browser process. 546 // See http://crbug.com/306702. 547 // Therefore, when expecting blocked content, we must wait until it has been 548 // reported by checking IsContentBlocked() when notified that 549 // NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED. (It is not sufficient to wait 550 // for just the notification because the same notification is reported for 551 // other reasons and the notification contains no indication of what 552 // caused it.) 553 content::WindowedNotificationObserver javascript_content_blocked_observer( 554 chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, 555 base::Bind(&TabSpecificContentSettings::IsContentBlocked, 556 base::Unretained(tab_settings), 557 CONTENT_SETTINGS_TYPE_JAVASCRIPT)); 558 559 GURL url = ui_test_utils::GetTestUrl( 560 base::FilePath(), base::FilePath().AppendASCII(html_file)); 561 ui_test_utils::NavigateToURL(browser(), url); 562 563 // Always wait for the page to load. 564 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 565 566 if (expect_is_javascript_content_blocked) { 567 javascript_content_blocked_observer.Wait(); 568 } else { 569 // Since there is no notification that content is not blocked and no 570 // content is blocked when |expect_is_javascript_content_blocked| is 571 // false, javascript_content_blocked_observer would never succeed. 572 // There is no way to ensure blocked content would not have been reported 573 // after the check below. For coverage of this scenario, we must rely on 574 // the TitleWatcher adding sufficient delay most of the time. 575 } 576 577 EXPECT_EQ(expect_is_javascript_content_blocked, 578 tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_JAVASCRIPT)); 579 EXPECT_FALSE(tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS)); 580 } 581 582 private: 583 // Builds the string to pass to kRegisterPepperPlugins for a single 584 // plugin using the provided parameters and a dummy version. 585 // Multiple results may be passed to kRegisterPepperPlugins, separated by ",". 586 base::FilePath::StringType BuildPepperPluginRegistration( 587 const char* library_name, 588 const char* display_name, 589 const char* mime_type) { 590 base::FilePath plugin_dir; 591 EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir)); 592 593 base::FilePath plugin_lib = plugin_dir.AppendASCII(library_name); 594 EXPECT_TRUE(base::PathExists(plugin_lib)); 595 596 base::FilePath::StringType pepper_plugin = plugin_lib.value(); 597 pepper_plugin.append(FILE_PATH_LITERAL("#")); 598#if defined(OS_WIN) 599 pepper_plugin.append(base::ASCIIToWide(display_name)); 600#else 601 pepper_plugin.append(display_name); 602#endif 603 pepper_plugin.append(FILE_PATH_LITERAL("#A CDM#0.1.0.0;")); 604#if defined(OS_WIN) 605 pepper_plugin.append(base::ASCIIToWide(mime_type)); 606#else 607 pepper_plugin.append(mime_type); 608#endif 609 610 return pepper_plugin; 611 } 612}; 613 614const char* const 615PepperContentSettingsSpecialCasesTest::kExternalClearKeyMimeType = 616 "application/x-ppapi-clearkey-cdm"; 617 618class PepperContentSettingsSpecialCasesPluginsBlockedTest 619 : public PepperContentSettingsSpecialCasesTest { 620 public: 621 virtual void SetUpOnMainThread() OVERRIDE { 622 PepperContentSettingsSpecialCasesTest::SetUpOnMainThread(); 623 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 624 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK); 625 } 626}; 627 628class PepperContentSettingsSpecialCasesJavaScriptBlockedTest 629 : public PepperContentSettingsSpecialCasesTest { 630 public: 631 virtual void SetUpOnMainThread() OVERRIDE { 632 PepperContentSettingsSpecialCasesTest::SetUpOnMainThread(); 633 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 634 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ALLOW); 635 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 636 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 637 } 638}; 639 640#if defined(ENABLE_PEPPER_CDMS) 641// A sanity check to verify that the plugin that is used as a baseline below 642// can be loaded. 643IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesTest, Baseline) { 644#if defined(OS_WIN) && defined(USE_ASH) 645 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 646 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 647 return; 648#endif 649 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 650 CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ALLOW); 651 652 RunLoadPepperPluginTest(kExternalClearKeyMimeType, true); 653} 654#endif // defined(ENABLE_PEPPER_CDMS) 655 656// The following tests verify that Pepper plugins that use JavaScript settings 657// instead of Plug-ins settings still work when Plug-ins are blocked. 658 659#if defined(ENABLE_PEPPER_CDMS) 660// The plugin successfully loaded above is blocked. 661IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesPluginsBlockedTest, 662 Normal) { 663#if defined(OS_WIN) && defined(USE_ASH) 664 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 665 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 666 return; 667#endif 668 RunLoadPepperPluginTest(kExternalClearKeyMimeType, false); 669} 670 671#if defined(WIDEVINE_CDM_AVAILABLE) 672IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesPluginsBlockedTest, 673 WidevineCdm) { 674#if defined(OS_WIN) && defined(USE_ASH) 675 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 676 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 677 return; 678#endif 679 RunLoadPepperPluginTest(kWidevineCdmPluginMimeType, true); 680} 681#endif // defined(WIDEVINE_CDM_AVAILABLE) 682#endif // defined(ENABLE_PEPPER_CDMS) 683 684#if !defined(DISABLE_NACL) 685IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesPluginsBlockedTest, 686 NaCl) { 687#if defined(OS_WIN) && defined(USE_ASH) 688 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 689 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 690 return; 691#endif 692 RunLoadPepperPluginTest("application/x-nacl", true); 693} 694#endif // !defined(DISABLE_NACL) 695 696// The following tests verify that those same Pepper plugins do not work when 697// JavaScript is blocked. 698 699#if defined(ENABLE_PEPPER_CDMS) 700// A plugin with no special behavior is not blocked when JavaScript is blocked. 701IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesJavaScriptBlockedTest, 702 Normal) { 703#if defined(OS_WIN) && defined(USE_ASH) 704 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 705 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 706 return; 707#endif 708 RunJavaScriptBlockedTest("load_clearkey_no_js.html", false); 709} 710 711#if defined(WIDEVINE_CDM_AVAILABLE) 712IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesJavaScriptBlockedTest, 713 WidevineCdm) { 714#if defined(OS_WIN) && defined(USE_ASH) 715 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 716 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 717 return; 718#endif 719 RunJavaScriptBlockedTest("load_widevine_no_js.html", true); 720} 721#endif // defined(WIDEVINE_CDM_AVAILABLE) 722#endif // defined(ENABLE_PEPPER_CDMS) 723 724#if !defined(DISABLE_NACL) 725IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesJavaScriptBlockedTest, 726 NaCl) { 727#if defined(OS_WIN) && defined(USE_ASH) 728 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 729 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 730 return; 731#endif 732 RunJavaScriptBlockedTest("load_nacl_no_js.html", true); 733} 734#endif // !defined(DISABLE_NACL) 735 736#endif // defined(ENABLE_PLUGINS) 737