Home | History | Annotate | Download | only in content_settings
      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/plugin_service.h"
     26 #include "content/public/browser/render_process_host.h"
     27 #include "content/public/browser/render_view_host.h"
     28 #include "content/public/browser/web_contents.h"
     29 #include "content/public/common/content_switches.h"
     30 #include "content/public/test/browser_test_utils.h"
     31 #include "content/public/test/test_utils.h"
     32 #include "content/test/net/url_request_mock_http_job.h"
     33 #include "net/test/spawned_test_server/spawned_test_server.h"
     34 
     35 #include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
     36 
     37 #if defined(OS_MACOSX)
     38 #include "base/mac/scoped_nsautorelease_pool.h"
     39 #endif
     40 
     41 using content::BrowserThread;
     42 using content::URLRequestMockHTTPJob;
     43 
     44 class ContentSettingsTest : public InProcessBrowserTest {
     45  public:
     46   ContentSettingsTest()
     47       : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
     48                       net::SpawnedTestServer::SSLOptions(
     49                           net::SpawnedTestServer::SSLOptions::CERT_OK),
     50                       base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
     51   }
     52 
     53   virtual void SetUpOnMainThread() OVERRIDE {
     54     BrowserThread::PostTask(
     55         BrowserThread::IO, FROM_HERE,
     56         base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
     57   }
     58 
     59   // Check the cookie for the given URL in an incognito window.
     60   void CookieCheckIncognitoWindow(const GURL& url, bool cookies_enabled) {
     61     ASSERT_TRUE(content::GetCookies(browser()->profile(), url).empty());
     62 
     63     Browser* incognito = CreateIncognitoBrowser();
     64     ASSERT_TRUE(content::GetCookies(incognito->profile(), url).empty());
     65     ui_test_utils::NavigateToURL(incognito, url);
     66     ASSERT_EQ(cookies_enabled,
     67               !content::GetCookies(incognito->profile(), url).empty());
     68 
     69     // Ensure incognito cookies don't leak to regular profile.
     70     ASSERT_TRUE(content::GetCookies(browser()->profile(), url).empty());
     71 
     72     // Ensure cookies get wiped after last incognito window closes.
     73     content::WindowedNotificationObserver signal(
     74         chrome::NOTIFICATION_BROWSER_CLOSED,
     75         content::Source<Browser>(incognito));
     76 
     77     chrome::CloseWindow(incognito);
     78 
     79 #if defined(OS_MACOSX)
     80     // BrowserWindowController depends on the auto release pool being recycled
     81     // in the message loop to delete itself, which frees the Browser object
     82     // which fires this event.
     83     AutoreleasePool()->Recycle();
     84 #endif
     85 
     86     signal.Wait();
     87 
     88     incognito = CreateIncognitoBrowser();
     89     ASSERT_TRUE(content::GetCookies(incognito->profile(), url).empty());
     90     chrome::CloseWindow(incognito);
     91   }
     92 
     93   void PreBasic(const GURL& url) {
     94     ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
     95 
     96     CookieCheckIncognitoWindow(url, true);
     97 
     98     ui_test_utils::NavigateToURL(browser(), url);
     99     ASSERT_FALSE(GetCookies(browser()->profile(), url).empty());
    100   }
    101 
    102   void Basic(const GURL& url) {
    103     ASSERT_FALSE(GetCookies(browser()->profile(), url).empty());
    104   }
    105 
    106   net::SpawnedTestServer https_server_;
    107 };
    108 
    109 // Sanity check on cookies before we do other tests. While these can be written
    110 // in content_browsertests, we want to verify Chrome's cookie storage and how it
    111 // handles incognito windows.
    112 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BasicCookies) {
    113   ASSERT_TRUE(test_server()->Start());
    114   GURL http_url = test_server()->GetURL("files/setcookie.html");
    115   PreBasic(http_url);
    116 }
    117 
    118 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BasicCookies) {
    119   ASSERT_TRUE(test_server()->Start());
    120   GURL http_url = test_server()->GetURL("files/setcookie.html");
    121   Basic(http_url);
    122 }
    123 
    124 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BasicCookiesHttps) {
    125   ASSERT_TRUE(https_server_.Start());
    126   GURL https_url = https_server_.GetURL("files/setcookie.html");
    127   PreBasic(https_url);
    128 }
    129 
    130 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BasicCookiesHttps) {
    131   ASSERT_TRUE(https_server_.Start());
    132   GURL https_url = https_server_.GetURL("files/setcookie.html");
    133   Basic(https_url);
    134 }
    135 
    136 // Verify that cookies are being blocked.
    137 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, PRE_BlockCookies) {
    138   ASSERT_TRUE(test_server()->Start());
    139   CookieSettings::Factory::GetForProfile(browser()->profile())->
    140       SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
    141   GURL url = test_server()->GetURL("files/setcookie.html");
    142   ui_test_utils::NavigateToURL(browser(), url);
    143   ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
    144   CookieCheckIncognitoWindow(url, false);
    145 }
    146 
    147 // Ensure that the setting persists.
    148 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BlockCookies) {
    149   ASSERT_EQ(
    150       CONTENT_SETTING_BLOCK,
    151       CookieSettings::Factory::GetForProfile(browser()->profile())->
    152           GetDefaultCookieSetting(NULL));
    153 }
    154 
    155 // Verify that cookies can be allowed and set using exceptions for particular
    156 // website(s) when all others are blocked.
    157 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, AllowCookiesUsingExceptions) {
    158   ASSERT_TRUE(test_server()->Start());
    159   GURL url = test_server()->GetURL("files/setcookie.html");
    160   CookieSettings* settings =
    161       CookieSettings::Factory::GetForProfile(browser()->profile()).get();
    162   settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
    163 
    164   ui_test_utils::NavigateToURL(browser(), url);
    165   ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
    166 
    167   settings->SetCookieSetting(
    168       ContentSettingsPattern::FromURL(url),
    169       ContentSettingsPattern::Wildcard(), CONTENT_SETTING_ALLOW);
    170 
    171   ui_test_utils::NavigateToURL(browser(), url);
    172   ASSERT_FALSE(GetCookies(browser()->profile(), url).empty());
    173 }
    174 
    175 // Verify that cookies can be blocked for a specific website using exceptions.
    176 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, BlockCookiesUsingExceptions) {
    177   ASSERT_TRUE(test_server()->Start());
    178   GURL url = test_server()->GetURL("files/setcookie.html");
    179   CookieSettings* settings =
    180       CookieSettings::Factory::GetForProfile(browser()->profile()).get();
    181   settings->SetCookieSetting(ContentSettingsPattern::FromURL(url),
    182                              ContentSettingsPattern::Wildcard(),
    183                              CONTENT_SETTING_BLOCK);
    184 
    185   ui_test_utils::NavigateToURL(browser(), url);
    186   ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
    187 
    188   ASSERT_TRUE(https_server_.Start());
    189   GURL unblocked_url = https_server_.GetURL("files/cookie1.html");
    190 
    191   ui_test_utils::NavigateToURL(browser(), unblocked_url);
    192   ASSERT_FALSE(GetCookies(browser()->profile(), unblocked_url).empty());
    193 }
    194 
    195 // This fails on ChromeOS because kRestoreOnStartup is ignored and the startup
    196 // preference is always "continue where I left off.
    197 #if !defined(OS_CHROMEOS)
    198 
    199 // Verify that cookies can be allowed and set using exceptions for particular
    200 // website(s) only for a session when all others are blocked.
    201 IN_PROC_BROWSER_TEST_F(ContentSettingsTest,
    202                        PRE_AllowCookiesForASessionUsingExceptions) {
    203   // NOTE: don't use test_server here, since we need the port to be the same
    204   // across the restart.
    205   GURL url = URLRequestMockHTTPJob::GetMockUrl(
    206       base::FilePath(FILE_PATH_LITERAL("setcookie.html")));
    207   CookieSettings* settings =
    208       CookieSettings::Factory::GetForProfile(browser()->profile()).get();
    209   settings->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
    210 
    211   ui_test_utils::NavigateToURL(browser(), url);
    212   ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
    213 
    214   settings->SetCookieSetting(
    215       ContentSettingsPattern::FromURL(url),
    216       ContentSettingsPattern::Wildcard(), CONTENT_SETTING_SESSION_ONLY);
    217   ui_test_utils::NavigateToURL(browser(), url);
    218   ASSERT_FALSE(GetCookies(browser()->profile(), url).empty());
    219 }
    220 
    221 IN_PROC_BROWSER_TEST_F(ContentSettingsTest,
    222                        AllowCookiesForASessionUsingExceptions) {
    223   GURL url = URLRequestMockHTTPJob::GetMockUrl(
    224       base::FilePath(FILE_PATH_LITERAL("setcookie.html")));
    225   ASSERT_TRUE(GetCookies(browser()->profile(), url).empty());
    226 }
    227 
    228 #endif // !CHROME_OS
    229 
    230 // Regression test for http://crbug.com/63649.
    231 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectLoopCookies) {
    232   ASSERT_TRUE(test_server()->Start());
    233 
    234   GURL test_url = test_server()->GetURL("files/redirect-loop.html");
    235 
    236   CookieSettings::Factory::GetForProfile(browser()->profile())->
    237       SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
    238 
    239   ui_test_utils::NavigateToURL(browser(), test_url);
    240 
    241   content::WebContents* web_contents =
    242       browser()->tab_strip_model()->GetActiveWebContents();
    243   ASSERT_EQ(UTF8ToUTF16(test_url.spec() + " failed to load"),
    244             web_contents->GetTitle());
    245 
    246   EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)->
    247       IsContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES));
    248 }
    249 
    250 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, ContentSettingsBlockDataURLs) {
    251   GURL url("data:text/html,<title>Data URL</title><script>alert(1)</script>");
    252 
    253   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    254       CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
    255 
    256   ui_test_utils::NavigateToURL(browser(), url);
    257 
    258   content::WebContents* web_contents =
    259       browser()->tab_strip_model()->GetActiveWebContents();
    260   ASSERT_EQ(UTF8ToUTF16("Data URL"), web_contents->GetTitle());
    261 
    262   EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)->
    263       IsContentBlocked(CONTENT_SETTINGS_TYPE_JAVASCRIPT));
    264 }
    265 
    266 // Tests that if redirect across origins occurs, the new process still gets the
    267 // content settings before the resource headers.
    268 IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectCrossOrigin) {
    269   ASSERT_TRUE(test_server()->Start());
    270 
    271   net::HostPortPair host_port = test_server()->host_port_pair();
    272   DCHECK_EQ(host_port.host(), std::string("127.0.0.1"));
    273 
    274   std::string redirect(base::StringPrintf(
    275       "http://localhost:%d/files/redirect-cross-origin.html",
    276       host_port.port()));
    277   GURL test_url = test_server()->GetURL("server-redirect?" + redirect);
    278 
    279   CookieSettings::Factory::GetForProfile(browser()->profile())->
    280       SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
    281 
    282   ui_test_utils::NavigateToURL(browser(), test_url);
    283 
    284   content::WebContents* web_contents =
    285       browser()->tab_strip_model()->GetActiveWebContents();
    286 
    287   EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)->
    288       IsContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES));
    289 }
    290 
    291 #if !defined(USE_AURA)  // No NPAPI plugins with Aura.
    292 
    293 class ClickToPlayPluginTest : public ContentSettingsTest {
    294  public:
    295   ClickToPlayPluginTest() {}
    296 
    297 #if defined(OS_MACOSX)
    298   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    299     base::FilePath plugin_dir;
    300     PathService::Get(base::DIR_MODULE, &plugin_dir);
    301     plugin_dir = plugin_dir.AppendASCII("plugins");
    302     // The plugins directory isn't read by default on the Mac, so it needs to be
    303     // explicitly registered.
    304     command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
    305   }
    306 #endif
    307 };
    308 
    309 IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, Basic) {
    310   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    311       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
    312 
    313   GURL url = ui_test_utils::GetTestUrl(
    314       base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html"));
    315   ui_test_utils::NavigateToURL(browser(), url);
    316 
    317   string16 expected_title(ASCIIToUTF16("OK"));
    318   content::TitleWatcher title_watcher(
    319       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
    320 
    321   content::RenderViewHost* host =
    322       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
    323   ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
    324   int process_id = host->GetProcess()->GetID();
    325   base::FilePath path(FILE_PATH_LITERAL("blah"));
    326   EXPECT_FALSE(filter->CanLoadPlugin(process_id, path));
    327   filter->AuthorizeAllPlugins(process_id);
    328   EXPECT_TRUE(filter->CanLoadPlugin(process_id, path));
    329   host->Send(new ChromeViewMsg_LoadBlockedPlugins(
    330       host->GetRoutingID(), std::string()));
    331 
    332   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    333 }
    334 
    335 // Verify that plugins can be allowed on a domain by adding an exception
    336 IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, AllowException) {
    337   GURL url = ui_test_utils::GetTestUrl(
    338       base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html"));
    339 
    340   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    341       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
    342   browser()->profile()->GetHostContentSettingsMap()
    343       ->SetContentSetting(ContentSettingsPattern::FromURL(url),
    344                           ContentSettingsPattern::Wildcard(),
    345                           CONTENT_SETTINGS_TYPE_PLUGINS,
    346                           std::string(),
    347                           CONTENT_SETTING_ALLOW);
    348 
    349   string16 expected_title(ASCIIToUTF16("OK"));
    350   content::TitleWatcher title_watcher(
    351       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
    352   ui_test_utils::NavigateToURL(browser(), url);
    353   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    354 }
    355 
    356 // Verify that plugins can be blocked on a domain by adding an exception.
    357 IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, BlockException) {
    358   GURL url = ui_test_utils::GetTestUrl(
    359       base::FilePath(), base::FilePath().AppendASCII("clicktoplay.html"));
    360 
    361   browser()->profile()->GetHostContentSettingsMap()
    362       ->SetContentSetting(ContentSettingsPattern::FromURL(url),
    363                           ContentSettingsPattern::Wildcard(),
    364                           CONTENT_SETTINGS_TYPE_PLUGINS,
    365                           std::string(),
    366                           CONTENT_SETTING_BLOCK);
    367 
    368   string16 expected_title(ASCIIToUTF16("Click To Play"));
    369   content::TitleWatcher title_watcher(
    370       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
    371   ui_test_utils::NavigateToURL(browser(), url);
    372   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    373 }
    374 
    375 // Crashes on Mac Asan.  http://crbug.com/239169
    376 #if defined(OS_MACOSX)
    377 #define MAYBE_LoadAllBlockedPlugins DISABLED_LoadAllBlockedPlugins
    378 // TODO(jschuh): Flaky plugin tests. crbug.com/244653
    379 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
    380 #define MAYBE_LoadAllBlockedPlugins DISABLED_LoadAllBlockedPlugins
    381 #else
    382 #define MAYBE_LoadAllBlockedPlugins LoadAllBlockedPlugins
    383 #endif
    384 IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, MAYBE_LoadAllBlockedPlugins) {
    385   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    386       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
    387 
    388   GURL url = ui_test_utils::GetTestUrl(
    389       base::FilePath(),
    390       base::FilePath().AppendASCII("load_all_blocked_plugins.html"));
    391   ui_test_utils::NavigateToURL(browser(), url);
    392 
    393   string16 expected_title1(ASCIIToUTF16("1"));
    394   content::TitleWatcher title_watcher1(
    395       browser()->tab_strip_model()->GetActiveWebContents(), expected_title1);
    396 
    397   content::RenderViewHost* host =
    398       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
    399   ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
    400       host->GetProcess()->GetID());
    401   host->Send(new ChromeViewMsg_LoadBlockedPlugins(
    402       host->GetRoutingID(), std::string()));
    403   EXPECT_EQ(expected_title1, title_watcher1.WaitAndGetTitle());
    404 
    405   string16 expected_title2(ASCIIToUTF16("2"));
    406   content::TitleWatcher title_watcher2(
    407       browser()->tab_strip_model()->GetActiveWebContents(), expected_title2);
    408 
    409   ASSERT_TRUE(content::ExecuteScript(
    410       browser()->tab_strip_model()->GetActiveWebContents(), "window.inject()"));
    411 
    412   EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle());
    413 }
    414 
    415 // If this flakes, use http://crbug.com/113057.
    416 // TODO(jschuh): Hanging plugin tests. crbug.com/244653
    417 #if !defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
    418 IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, NoCallbackAtLoad) {
    419   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    420       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
    421 
    422   GURL url("data:application/vnd.npapi-test,CallOnStartup();");
    423   ui_test_utils::NavigateToURL(browser(), url);
    424 
    425   // Inject the callback function into the HTML page generated by the browser.
    426   ASSERT_TRUE(content::ExecuteScript(
    427       browser()->tab_strip_model()->GetActiveWebContents(),
    428       "CallOnStartup = function() { document.title = \"OK\"; }"));
    429 
    430   string16 expected_title(ASCIIToUTF16("OK"));
    431   content::TitleWatcher title_watcher(
    432       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
    433 
    434   content::RenderViewHost* host =
    435       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
    436   ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
    437       host->GetProcess()->GetID());
    438   host->Send(new ChromeViewMsg_LoadBlockedPlugins(
    439       host->GetRoutingID(), std::string()));
    440 
    441   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    442 }
    443 #endif
    444 
    445 IN_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   string16 expected_title(ASCIIToUTF16("OK"));
    455   content::TitleWatcher title_watcher(
    456       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
    457 
    458   content::RenderViewHost* host =
    459       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
    460   ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
    461       host->GetProcess()->GetID());
    462   host->Send(new ChromeViewMsg_LoadBlockedPlugins(
    463       host->GetRoutingID(), std::string()));
    464 
    465   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    466 }
    467 
    468 #endif  // !defined(USE_AURA)
    469 
    470 #if defined(ENABLE_PLUGINS)
    471 
    472 class PepperContentSettingsTest : public ContentSettingsTest {
    473  public:
    474   PepperContentSettingsTest() {}
    475 
    476  protected:
    477   static const char* const kExternalClearKeyMimeType;
    478 
    479   // Registers any CDM plugins not registered by default.
    480   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    481 #if defined(ENABLE_PEPPER_CDMS)
    482     // Platform-specific filename relative to the chrome executable.
    483 #if defined(OS_WIN)
    484     const std::wstring external_clear_key_mime_type =
    485         ASCIIToWide(kExternalClearKeyMimeType);
    486     const char kLibraryName[] = "clearkeycdmadapter.dll";
    487 #else  // !defined(OS_WIN)
    488     const char* external_clear_key_mime_type = kExternalClearKeyMimeType;
    489 #if defined(OS_MACOSX)
    490     const char kLibraryName[] = "clearkeycdmadapter.plugin";
    491 #elif defined(OS_POSIX)
    492     const char kLibraryName[] = "libclearkeycdmadapter.so";
    493 #endif  // defined(OS_MACOSX)
    494 #endif  // defined(OS_WIN)
    495 
    496     // Append the switch to register the External Clear Key CDM.
    497     base::FilePath plugin_dir;
    498     EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
    499     base::FilePath plugin_lib = plugin_dir.AppendASCII(kLibraryName);
    500     EXPECT_TRUE(base::PathExists(plugin_lib));
    501     base::FilePath::StringType pepper_plugin = plugin_lib.value();
    502     pepper_plugin.append(FILE_PATH_LITERAL(
    503         "#Clear Key CDM#Clear Key CDM 0.1.0.0#0.1.0.0;"));
    504     pepper_plugin.append(external_clear_key_mime_type);
    505     command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
    506                                      pepper_plugin);
    507 #endif  // defined(ENABLE_PEPPER_CDMS)
    508 
    509 #if !defined(DISABLE_NACL)
    510     // Ensure NaCl can run.
    511     command_line->AppendSwitch(switches::kEnableNaCl);
    512 #endif
    513   }
    514 
    515   void RunLoadPepperPluginTest(const char* mime_type, bool expect_loaded) {
    516     const char* expected_result = expect_loaded ? "Loaded" : "Not Loaded";
    517     content::WebContents* web_contents =
    518         browser()->tab_strip_model()->GetActiveWebContents();
    519 
    520     string16 expected_title(ASCIIToUTF16(expected_result));
    521     content::TitleWatcher title_watcher(web_contents, expected_title);
    522 
    523     // GetTestUrl assumes paths, so we must append query parameters to result.
    524     GURL file_url = ui_test_utils::GetTestUrl(
    525         base::FilePath(),
    526         base::FilePath().AppendASCII("load_pepper_plugin.html"));
    527     GURL url(file_url.spec() +
    528              base::StringPrintf("?mimetype=%s", mime_type));
    529     ui_test_utils::NavigateToURL(browser(), url);
    530 
    531     EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    532     EXPECT_EQ(!expect_loaded,
    533               TabSpecificContentSettings::FromWebContents(web_contents)->
    534                   IsContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS));
    535   }
    536 
    537   void RunJavaScriptBlockedTest(const char* html_file,
    538                                 bool expect_is_javascript_content_blocked) {
    539     // Because JavaScript is disabled, <title> will be the only title set.
    540     // Checking for it ensures that the page loaded.
    541     const char* const kExpectedTitle = "Initial Title";
    542     content::WebContents* web_contents =
    543         browser()->tab_strip_model()->GetActiveWebContents();
    544     TabSpecificContentSettings* tab_settings =
    545         TabSpecificContentSettings::FromWebContents(web_contents);
    546     string16 expected_title(ASCIIToUTF16(kExpectedTitle));
    547     content::TitleWatcher title_watcher(web_contents, expected_title);
    548 
    549     GURL url = ui_test_utils::GetTestUrl(
    550         base::FilePath(), base::FilePath().AppendASCII(html_file));
    551     ui_test_utils::NavigateToURL(browser(), url);
    552 
    553     EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    554 
    555     EXPECT_EQ(expect_is_javascript_content_blocked,
    556               tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_JAVASCRIPT));
    557     EXPECT_FALSE(tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS));
    558   }
    559 };
    560 
    561 const char* const PepperContentSettingsTest::kExternalClearKeyMimeType =
    562     "application/x-ppapi-clearkey-cdm";
    563 
    564 // Tests Pepper plugins that use JavaScript instead of Plug-ins settings.
    565 IN_PROC_BROWSER_TEST_F(PepperContentSettingsTest, PluginSpecialCases) {
    566 #if defined(OS_WIN) && defined(USE_ASH)
    567   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    568   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    569     return;
    570 #endif
    571 
    572   HostContentSettingsMap* content_settings =
    573       browser()->profile()->GetHostContentSettingsMap();
    574 
    575   // First, verify that this plugin can be loaded.
    576   content_settings->SetDefaultContentSetting(
    577       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ALLOW);
    578 
    579 #if defined(ENABLE_PEPPER_CDMS)
    580   RunLoadPepperPluginTest(kExternalClearKeyMimeType, true);
    581 #endif  // defined(ENABLE_PEPPER_CDMS)
    582 
    583   // Next, test behavior when plug-ins are blocked.
    584   content_settings->SetDefaultContentSetting(
    585       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
    586 
    587 #if defined(ENABLE_PEPPER_CDMS)
    588   // The plugin we loaded above does not load now.
    589   RunLoadPepperPluginTest(kExternalClearKeyMimeType, false);
    590 
    591 #if defined(WIDEVINE_CDM_AVAILABLE)
    592   RunLoadPepperPluginTest(kWidevineCdmPluginMimeType, true);
    593 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
    594 #endif  // defined(ENABLE_PEPPER_CDMS)
    595 
    596 #if !defined(DISABLE_NACL)
    597   RunLoadPepperPluginTest("application/x-nacl", true);
    598 #endif  // !defined(DISABLE_NACL)
    599 
    600   // Finally, test behavior when (just) JavaScript is blocked.
    601   content_settings->SetDefaultContentSetting(
    602       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ALLOW);
    603   content_settings->SetDefaultContentSetting(
    604       CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
    605 
    606 #if defined(ENABLE_PEPPER_CDMS)
    607   // This plugin has no special behavior and does not require JavaScript.
    608   RunJavaScriptBlockedTest("load_clearkey_no_js.html", false);
    609 
    610 #if defined(WIDEVINE_CDM_AVAILABLE)
    611   RunJavaScriptBlockedTest("load_widevine_no_js.html", true);
    612 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
    613 #endif  // defined(ENABLE_PEPPER_CDMS)
    614 
    615 #if !defined(DISABLE_NACL)
    616   RunJavaScriptBlockedTest("load_nacl_no_js.html", true);
    617 #endif  // !defined(DISABLE_NACL)
    618 }
    619 
    620 #endif  // defined(ENABLE_PLUGINS)
    621