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/auto_reset.h" 6 #include "base/command_line.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "chrome/browser/content_settings/host_content_settings_map.h" 9 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 10 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" 11 #include "chrome/browser/infobars/infobar_delegate.h" 12 #include "chrome/browser/infobars/infobar_service.h" 13 #include "chrome/browser/media/media_capture_devices_dispatcher.h" 14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 16 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/content_settings.h" 18 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 19 #include "chrome/test/base/testing_profile.h" 20 #include "content/public/browser/web_contents.h" 21 #include "content/public/test/web_contents_tester.h" 22 #include "grit/generated_resources.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "ui/base/l10n/l10n_util.h" 25 26 using content::WebContentsTester; 27 28 class ContentSettingBubbleModelTest : public ChromeRenderViewHostTestHarness { 29 protected: 30 virtual void SetUp() OVERRIDE { 31 ChromeRenderViewHostTestHarness::SetUp(); 32 TabSpecificContentSettings::CreateForWebContents(web_contents()); 33 InfoBarService::CreateForWebContents(web_contents()); 34 } 35 36 void CheckGeolocationBubble(size_t expected_domains, 37 bool expect_clear_link, 38 bool expect_reload_hint) { 39 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 40 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 41 NULL, web_contents(), profile(), 42 CONTENT_SETTINGS_TYPE_GEOLOCATION)); 43 const ContentSettingBubbleModel::BubbleContent& bubble_content = 44 content_setting_bubble_model->bubble_content(); 45 EXPECT_TRUE(bubble_content.title.empty()); 46 EXPECT_TRUE(bubble_content.radio_group.radio_items.empty()); 47 EXPECT_TRUE(bubble_content.popup_items.empty()); 48 EXPECT_EQ(expected_domains, bubble_content.domain_lists.size()); 49 EXPECT_NE(expect_clear_link || expect_reload_hint, 50 bubble_content.custom_link.empty()); 51 EXPECT_EQ(expect_clear_link, bubble_content.custom_link_enabled); 52 EXPECT_FALSE(bubble_content.manage_link.empty()); 53 } 54 }; 55 56 TEST_F(ContentSettingBubbleModelTest, ImageRadios) { 57 TabSpecificContentSettings* content_settings = 58 TabSpecificContentSettings::FromWebContents(web_contents()); 59 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, 60 std::string()); 61 62 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 63 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 64 NULL, web_contents(), profile(), 65 CONTENT_SETTINGS_TYPE_IMAGES)); 66 const ContentSettingBubbleModel::BubbleContent& bubble_content = 67 content_setting_bubble_model->bubble_content(); 68 EXPECT_FALSE(bubble_content.title.empty()); 69 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 70 EXPECT_EQ(0, bubble_content.radio_group.default_item); 71 EXPECT_TRUE(bubble_content.custom_link.empty()); 72 EXPECT_FALSE(bubble_content.manage_link.empty()); 73 } 74 75 TEST_F(ContentSettingBubbleModelTest, Cookies) { 76 TabSpecificContentSettings* content_settings = 77 TabSpecificContentSettings::FromWebContents(web_contents()); 78 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, 79 std::string()); 80 81 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 82 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 83 NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES)); 84 const ContentSettingBubbleModel::BubbleContent& bubble_content = 85 content_setting_bubble_model->bubble_content(); 86 std::string title = bubble_content.title; 87 EXPECT_FALSE(title.empty()); 88 ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size()); 89 std::string radio1 = bubble_content.radio_group.radio_items[0]; 90 std::string radio2 = bubble_content.radio_group.radio_items[1]; 91 EXPECT_FALSE(bubble_content.custom_link.empty()); 92 EXPECT_TRUE(bubble_content.custom_link_enabled); 93 EXPECT_FALSE(bubble_content.manage_link.empty()); 94 95 content_settings->ClearCookieSpecificContentSettings(); 96 content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); 97 content_setting_bubble_model.reset( 98 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 99 NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES)); 100 const ContentSettingBubbleModel::BubbleContent& bubble_content_2 = 101 content_setting_bubble_model->bubble_content(); 102 103 EXPECT_FALSE(bubble_content_2.title.empty()); 104 EXPECT_NE(title, bubble_content_2.title); 105 ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size()); 106 // TODO(bauerb): Update this once the strings have been updated. 107 EXPECT_EQ(radio1, bubble_content_2.radio_group.radio_items[0]); 108 EXPECT_EQ(radio2, bubble_content_2.radio_group.radio_items[1]); 109 EXPECT_FALSE(bubble_content_2.custom_link.empty()); 110 EXPECT_TRUE(bubble_content_2.custom_link_enabled); 111 EXPECT_FALSE(bubble_content_2.manage_link.empty()); 112 } 113 114 TEST_F(ContentSettingBubbleModelTest, MediastreamMicAndCamera) { 115 // Required to break dependency on BrowserMainLoop. 116 MediaCaptureDevicesDispatcher::GetInstance()-> 117 DisableDeviceEnumerationForTesting(); 118 119 TabSpecificContentSettings* content_settings = 120 TabSpecificContentSettings::FromWebContents(web_contents()); 121 content_settings->OnMicrophoneAccessed(); 122 content_settings->OnCameraAccessed(); 123 124 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 125 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 126 NULL, web_contents(), profile(), 127 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 128 const ContentSettingBubbleModel::BubbleContent& bubble_content = 129 content_setting_bubble_model->bubble_content(); 130 EXPECT_EQ(bubble_content.title, 131 l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED)); 132 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 133 EXPECT_EQ(bubble_content.radio_group.radio_items[0], 134 l10n_util::GetStringFUTF8( 135 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, 136 UTF8ToUTF16(web_contents()->GetURL().spec()))); 137 EXPECT_EQ(bubble_content.radio_group.radio_items[1], 138 l10n_util::GetStringUTF8( 139 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); 140 EXPECT_EQ(0, bubble_content.radio_group.default_item); 141 EXPECT_TRUE(bubble_content.custom_link.empty()); 142 EXPECT_FALSE(bubble_content.custom_link_enabled); 143 EXPECT_FALSE(bubble_content.manage_link.empty()); 144 EXPECT_EQ(2U, bubble_content.media_menus.size()); 145 } 146 147 TEST_F(ContentSettingBubbleModelTest, BlockedMediastreamMicAndCamera) { 148 // Required to break dependency on BrowserMainLoop. 149 MediaCaptureDevicesDispatcher::GetInstance()-> 150 DisableDeviceEnumerationForTesting(); 151 152 WebContentsTester::For(web_contents())-> 153 NavigateAndCommit(GURL("https://www.example.com")); 154 GURL url = web_contents()->GetURL(); 155 156 HostContentSettingsMap* host_content_settings_map = 157 profile()->GetHostContentSettingsMap(); 158 ContentSettingsPattern primary_pattern = 159 ContentSettingsPattern::FromURL(url); 160 ContentSetting setting = CONTENT_SETTING_BLOCK; 161 host_content_settings_map->SetContentSetting( 162 primary_pattern, 163 ContentSettingsPattern::Wildcard(), 164 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 165 std::string(), 166 setting); 167 host_content_settings_map->SetContentSetting( 168 primary_pattern, 169 ContentSettingsPattern::Wildcard(), 170 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 171 std::string(), 172 setting); 173 174 TabSpecificContentSettings* content_settings = 175 TabSpecificContentSettings::FromWebContents(web_contents()); 176 content_settings->OnMicrophoneAccessBlocked(); 177 content_settings->OnCameraAccessBlocked(); 178 { 179 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 180 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 181 NULL, web_contents(), profile(), 182 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 183 const ContentSettingBubbleModel::BubbleContent& bubble_content = 184 content_setting_bubble_model->bubble_content(); 185 // Test if the correct radio item is selected for the blocked mediastream 186 // setting. 187 EXPECT_EQ(1, bubble_content.radio_group.default_item); 188 } 189 190 // Test that the media settings where not changed. 191 EXPECT_EQ(CONTENT_SETTING_BLOCK, 192 host_content_settings_map->GetContentSetting( 193 url, 194 url, 195 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 196 std::string())); 197 EXPECT_EQ(CONTENT_SETTING_BLOCK, 198 host_content_settings_map->GetContentSetting( 199 url, 200 url, 201 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 202 std::string())); 203 204 { 205 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 206 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 207 NULL, web_contents(), profile(), 208 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 209 // Change the radio setting. 210 content_setting_bubble_model->OnRadioClicked(0); 211 } 212 // Test that the media setting were change correctly. 213 EXPECT_EQ(CONTENT_SETTING_ALLOW, 214 host_content_settings_map->GetContentSetting( 215 url, 216 url, 217 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 218 std::string())); 219 EXPECT_EQ(CONTENT_SETTING_ALLOW, 220 host_content_settings_map->GetContentSetting( 221 url, 222 url, 223 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 224 std::string())); 225 226 // Removing an |InfoBarDelegate| from the |InfoBarService| does not delete 227 // it. Hence the |delegate| must be cleaned up after it was removed from the 228 // |infobar_service|. 229 InfoBarService* infobar_service = 230 InfoBarService::FromWebContents(web_contents()); 231 scoped_ptr<InfoBarDelegate> delegate(infobar_service->infobar_at(0)); 232 infobar_service->RemoveInfoBar(delegate.get()); 233 } 234 235 TEST_F(ContentSettingBubbleModelTest, MediastreamMic) { 236 // Required to break dependency on BrowserMainLoop. 237 MediaCaptureDevicesDispatcher::GetInstance()-> 238 DisableDeviceEnumerationForTesting(); 239 240 TabSpecificContentSettings* content_settings = 241 TabSpecificContentSettings::FromWebContents(web_contents()); 242 content_settings->OnMicrophoneAccessed(); 243 244 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 245 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 246 NULL, web_contents(), profile(), 247 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 248 const ContentSettingBubbleModel::BubbleContent& bubble_content = 249 content_setting_bubble_model->bubble_content(); 250 EXPECT_EQ(bubble_content.title, 251 l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED)); 252 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 253 EXPECT_EQ(bubble_content.radio_group.radio_items[0], 254 l10n_util::GetStringFUTF8( 255 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, 256 UTF8ToUTF16(web_contents()->GetURL().spec()))); 257 EXPECT_EQ(bubble_content.radio_group.radio_items[1], 258 l10n_util::GetStringUTF8( 259 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); 260 EXPECT_EQ(0, bubble_content.radio_group.default_item); 261 EXPECT_TRUE(bubble_content.custom_link.empty()); 262 EXPECT_FALSE(bubble_content.custom_link_enabled); 263 EXPECT_FALSE(bubble_content.manage_link.empty()); 264 EXPECT_EQ(1U, bubble_content.media_menus.size()); 265 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE, 266 bubble_content.media_menus.begin()->first); 267 268 // Change the microphone access. 269 content_settings->OnMicrophoneAccessBlocked(); 270 content_setting_bubble_model.reset( 271 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 272 NULL, web_contents(), profile(), 273 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 274 const ContentSettingBubbleModel::BubbleContent& new_bubble_content = 275 content_setting_bubble_model->bubble_content(); 276 EXPECT_EQ(new_bubble_content.title, 277 l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED)); 278 EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); 279 EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], 280 l10n_util::GetStringFUTF8( 281 IDS_BLOCKED_MEDIASTREAM_MIC_ASK, 282 UTF8ToUTF16(web_contents()->GetURL().spec()))); 283 EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], 284 l10n_util::GetStringUTF8( 285 IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION)); 286 EXPECT_EQ(1, new_bubble_content.radio_group.default_item); 287 EXPECT_TRUE(new_bubble_content.custom_link.empty()); 288 EXPECT_FALSE(new_bubble_content.custom_link_enabled); 289 EXPECT_FALSE(new_bubble_content.manage_link.empty()); 290 EXPECT_EQ(1U, new_bubble_content.media_menus.size()); 291 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE, 292 new_bubble_content.media_menus.begin()->first); 293 } 294 295 TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) { 296 // Required to break dependency on BrowserMainLoop. 297 MediaCaptureDevicesDispatcher::GetInstance()-> 298 DisableDeviceEnumerationForTesting(); 299 300 TabSpecificContentSettings* content_settings = 301 TabSpecificContentSettings::FromWebContents(web_contents()); 302 content_settings->OnCameraAccessed(); 303 304 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 305 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 306 NULL, web_contents(), profile(), 307 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 308 const ContentSettingBubbleModel::BubbleContent& bubble_content = 309 content_setting_bubble_model->bubble_content(); 310 EXPECT_EQ(bubble_content.title, 311 l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED)); 312 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 313 EXPECT_EQ(bubble_content.radio_group.radio_items[0], 314 l10n_util::GetStringFUTF8( 315 IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION, 316 UTF8ToUTF16(web_contents()->GetURL().spec()))); 317 EXPECT_EQ(bubble_content.radio_group.radio_items[1], 318 l10n_util::GetStringUTF8( 319 IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK)); 320 EXPECT_EQ(0, bubble_content.radio_group.default_item); 321 EXPECT_TRUE(bubble_content.custom_link.empty()); 322 EXPECT_FALSE(bubble_content.custom_link_enabled); 323 EXPECT_FALSE(bubble_content.manage_link.empty()); 324 EXPECT_EQ(1U, bubble_content.media_menus.size()); 325 EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE, 326 bubble_content.media_menus.begin()->first); 327 328 // Change the camera access. 329 content_settings->OnCameraAccessBlocked(); 330 content_setting_bubble_model.reset( 331 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 332 NULL, web_contents(), profile(), 333 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 334 const ContentSettingBubbleModel::BubbleContent& new_bubble_content = 335 content_setting_bubble_model->bubble_content(); 336 EXPECT_EQ(new_bubble_content.title, 337 l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED)); 338 EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); 339 EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], 340 l10n_util::GetStringFUTF8( 341 IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK, 342 UTF8ToUTF16(web_contents()->GetURL().spec()))); 343 EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], 344 l10n_util::GetStringUTF8( 345 IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION)); 346 EXPECT_EQ(1, new_bubble_content.radio_group.default_item); 347 EXPECT_TRUE(new_bubble_content.custom_link.empty()); 348 EXPECT_FALSE(new_bubble_content.custom_link_enabled); 349 EXPECT_FALSE(new_bubble_content.manage_link.empty()); 350 EXPECT_EQ(1U, new_bubble_content.media_menus.size()); 351 EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE, 352 new_bubble_content.media_menus.begin()->first); 353 } 354 355 TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) { 356 // Required to break dependency on BrowserMainLoop. 357 MediaCaptureDevicesDispatcher::GetInstance()-> 358 DisableDeviceEnumerationForTesting(); 359 360 TabSpecificContentSettings* content_settings = 361 TabSpecificContentSettings::FromWebContents(web_contents()); 362 363 // Firstly, add microphone access. 364 content_settings->OnMicrophoneAccessed(); 365 366 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 367 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 368 NULL, web_contents(), profile(), 369 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 370 const ContentSettingBubbleModel::BubbleContent& bubble_content = 371 content_setting_bubble_model->bubble_content(); 372 EXPECT_EQ(bubble_content.title, 373 l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED)); 374 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 375 EXPECT_EQ(bubble_content.radio_group.radio_items[0], 376 l10n_util::GetStringFUTF8( 377 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, 378 UTF8ToUTF16(web_contents()->GetURL().spec()))); 379 EXPECT_EQ(bubble_content.radio_group.radio_items[1], 380 l10n_util::GetStringUTF8( 381 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); 382 EXPECT_EQ(0, bubble_content.radio_group.default_item); 383 EXPECT_EQ(1U, bubble_content.media_menus.size()); 384 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE, 385 bubble_content.media_menus.begin()->first); 386 387 // Then add camera access. 388 content_settings->OnCameraAccessed(); 389 390 content_setting_bubble_model.reset( 391 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 392 NULL, web_contents(), profile(), 393 CONTENT_SETTINGS_TYPE_MEDIASTREAM)); 394 const ContentSettingBubbleModel::BubbleContent& new_bubble_content = 395 content_setting_bubble_model->bubble_content(); 396 EXPECT_EQ(new_bubble_content.title, 397 l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED)); 398 EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); 399 EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], 400 l10n_util::GetStringFUTF8( 401 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, 402 UTF8ToUTF16(web_contents()->GetURL().spec()))); 403 EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], 404 l10n_util::GetStringUTF8( 405 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); 406 EXPECT_EQ(0, new_bubble_content.radio_group.default_item); 407 EXPECT_EQ(2U, new_bubble_content.media_menus.size()); 408 } 409 410 TEST_F(ContentSettingBubbleModelTest, Plugins) { 411 TabSpecificContentSettings* content_settings = 412 TabSpecificContentSettings::FromWebContents(web_contents()); 413 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS, 414 std::string()); 415 416 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 417 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 418 NULL, web_contents(), profile(), 419 CONTENT_SETTINGS_TYPE_PLUGINS)); 420 const ContentSettingBubbleModel::BubbleContent& bubble_content = 421 content_setting_bubble_model->bubble_content(); 422 EXPECT_FALSE(bubble_content.title.empty()); 423 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 424 EXPECT_FALSE(bubble_content.custom_link.empty()); 425 EXPECT_TRUE(bubble_content.custom_link_enabled); 426 EXPECT_FALSE(bubble_content.manage_link.empty()); 427 } 428 429 TEST_F(ContentSettingBubbleModelTest, MultiplePlugins) { 430 CommandLine* cmd = CommandLine::ForCurrentProcess(); 431 base::AutoReset<CommandLine> auto_reset(cmd, *cmd); 432 cmd->AppendSwitch(switches::kEnableResourceContentSettings); 433 434 HostContentSettingsMap* map = profile()->GetHostContentSettingsMap(); 435 std::string fooPlugin = "foo"; 436 std::string barPlugin = "bar"; 437 438 // Navigating to some sample url prevents the GetURL method from returning an 439 // invalid empty URL. 440 WebContentsTester::For(web_contents())-> 441 NavigateAndCommit(GURL("http://www.example.com")); 442 GURL url = web_contents()->GetURL(); 443 map->AddExceptionForURL(url, 444 url, 445 CONTENT_SETTINGS_TYPE_PLUGINS, 446 fooPlugin, 447 CONTENT_SETTING_ALLOW); 448 map->AddExceptionForURL(url, 449 url, 450 CONTENT_SETTINGS_TYPE_PLUGINS, 451 barPlugin, 452 CONTENT_SETTING_ASK); 453 454 TabSpecificContentSettings* content_settings = 455 TabSpecificContentSettings::FromWebContents(web_contents()); 456 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS, 457 fooPlugin); 458 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS, 459 barPlugin); 460 461 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 462 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 463 NULL, web_contents(), profile(), 464 CONTENT_SETTINGS_TYPE_PLUGINS)); 465 const ContentSettingBubbleModel::BubbleContent& bubble_content = 466 content_setting_bubble_model->bubble_content(); 467 EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); 468 EXPECT_EQ(1, bubble_content.radio_group.default_item); 469 470 content_setting_bubble_model->OnRadioClicked(0); 471 // Nothing should have changed. 472 EXPECT_EQ(CONTENT_SETTING_ALLOW, 473 map->GetContentSetting(url, 474 url, 475 CONTENT_SETTINGS_TYPE_PLUGINS, 476 fooPlugin)); 477 EXPECT_EQ(CONTENT_SETTING_ASK, 478 map->GetContentSetting(url, 479 url, 480 CONTENT_SETTINGS_TYPE_PLUGINS, 481 barPlugin)); 482 483 content_setting_bubble_model.reset(); 484 // Both plug-ins should be click-to-play now. 485 EXPECT_EQ(CONTENT_SETTING_ALLOW, 486 map->GetContentSetting(url, 487 url, 488 CONTENT_SETTINGS_TYPE_PLUGINS, 489 fooPlugin)); 490 EXPECT_EQ(CONTENT_SETTING_ALLOW, 491 map->GetContentSetting(url, 492 url, 493 CONTENT_SETTINGS_TYPE_PLUGINS, 494 barPlugin)); 495 } 496 497 TEST_F(ContentSettingBubbleModelTest, PepperBroker) { 498 TabSpecificContentSettings* content_settings = 499 TabSpecificContentSettings::FromWebContents(web_contents()); 500 content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER, 501 std::string()); 502 503 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 504 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 505 NULL, web_contents(), profile(), 506 CONTENT_SETTINGS_TYPE_PPAPI_BROKER)); 507 const ContentSettingBubbleModel::BubbleContent& bubble_content = 508 content_setting_bubble_model->bubble_content(); 509 510 std::string title = bubble_content.title; 511 EXPECT_FALSE(title.empty()); 512 ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size()); 513 std::string radio1 = bubble_content.radio_group.radio_items[0]; 514 std::string radio2 = bubble_content.radio_group.radio_items[1]; 515 EXPECT_FALSE(bubble_content.custom_link_enabled); 516 EXPECT_FALSE(bubble_content.manage_link.empty()); 517 518 content_settings->ClearBlockedContentSettingsExceptForCookies(); 519 content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER); 520 content_setting_bubble_model.reset( 521 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 522 NULL, web_contents(), profile(), 523 CONTENT_SETTINGS_TYPE_PPAPI_BROKER)); 524 const ContentSettingBubbleModel::BubbleContent& bubble_content_2 = 525 content_setting_bubble_model->bubble_content(); 526 527 EXPECT_FALSE(bubble_content_2.title.empty()); 528 EXPECT_NE(title, bubble_content_2.title); 529 ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size()); 530 EXPECT_NE(radio1, bubble_content_2.radio_group.radio_items[0]); 531 EXPECT_NE(radio2, bubble_content_2.radio_group.radio_items[1]); 532 EXPECT_FALSE(bubble_content_2.custom_link_enabled); 533 EXPECT_FALSE(bubble_content_2.manage_link.empty()); 534 } 535 536 TEST_F(ContentSettingBubbleModelTest, Geolocation) { 537 const GURL page_url("http://toplevel.example/"); 538 const GURL frame1_url("http://host1.example/"); 539 const GURL frame2_url("http://host2.example:999/"); 540 541 NavigateAndCommit(page_url); 542 TabSpecificContentSettings* content_settings = 543 TabSpecificContentSettings::FromWebContents(web_contents()); 544 545 // One permitted frame, but not in the content map: requires reload. 546 content_settings->OnGeolocationPermissionSet(frame1_url, true); 547 CheckGeolocationBubble(1, false, true); 548 549 // Add it to the content map, should now have a clear link. 550 HostContentSettingsMap* setting_map = 551 profile()->GetHostContentSettingsMap(); 552 setting_map->SetContentSetting( 553 ContentSettingsPattern::FromURLNoWildcard(frame1_url), 554 ContentSettingsPattern::FromURLNoWildcard(page_url), 555 CONTENT_SETTINGS_TYPE_GEOLOCATION, 556 std::string(), 557 CONTENT_SETTING_ALLOW); 558 CheckGeolocationBubble(1, true, false); 559 560 // Change the default to allow: no message needed. 561 profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 562 CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ALLOW); 563 CheckGeolocationBubble(1, false, false); 564 565 // Second frame denied, but not stored in the content map: requires reload. 566 content_settings->OnGeolocationPermissionSet(frame2_url, false); 567 CheckGeolocationBubble(2, false, true); 568 569 // Change the default to block: offer a clear link for the persisted frame 1. 570 profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 571 CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_BLOCK); 572 CheckGeolocationBubble(2, true, false); 573 } 574 575 TEST_F(ContentSettingBubbleModelTest, FileURL) { 576 std::string file_url("file:///tmp/test.html"); 577 NavigateAndCommit(GURL(file_url)); 578 TabSpecificContentSettings::FromWebContents(web_contents())->OnContentBlocked( 579 CONTENT_SETTINGS_TYPE_IMAGES, std::string()); 580 scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( 581 ContentSettingBubbleModel::CreateContentSettingBubbleModel( 582 NULL, web_contents(), profile(), 583 CONTENT_SETTINGS_TYPE_IMAGES)); 584 std::string title = 585 content_setting_bubble_model->bubble_content().radio_group.radio_items[0]; 586 ASSERT_NE(std::string::npos, title.find(file_url)); 587 } 588 589 TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) { 590 const GURL page_url("http://toplevel.example/"); 591 NavigateAndCommit(page_url); 592 TabSpecificContentSettings* content_settings = 593 TabSpecificContentSettings::FromWebContents(web_contents()); 594 content_settings->set_pending_protocol_handler( 595 ProtocolHandler::CreateProtocolHandler("mailto", 596 GURL("http://www.toplevel.example/"), ASCIIToUTF16("Handler"))); 597 598 ContentSettingRPHBubbleModel content_setting_bubble_model( 599 NULL, web_contents(), profile(), NULL, 600 CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS); 601 602 const ContentSettingBubbleModel::BubbleContent& bubble_content = 603 content_setting_bubble_model.bubble_content(); 604 EXPECT_FALSE(bubble_content.title.empty()); 605 EXPECT_FALSE(bubble_content.radio_group.radio_items.empty()); 606 EXPECT_TRUE(bubble_content.popup_items.empty()); 607 EXPECT_TRUE(bubble_content.domain_lists.empty()); 608 EXPECT_TRUE(bubble_content.custom_link.empty()); 609 EXPECT_FALSE(bubble_content.custom_link_enabled); 610 EXPECT_FALSE(bubble_content.manage_link.empty()); 611 } 612 613 class FakeDelegate : public ProtocolHandlerRegistry::Delegate { 614 public: 615 virtual void RegisterExternalHandler(const std::string& protocol) OVERRIDE { 616 // Overrides in order to not register the handler with the 617 // ChildProcessSecurityPolicy. That has persistent and unalterable 618 // side effects on other tests. 619 } 620 621 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( 622 ShellIntegration::DefaultWebClientObserver* observer, 623 const std::string& protocol) OVERRIDE { 624 VLOG(1) << "CreateShellWorker"; 625 return NULL; 626 } 627 628 virtual ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver( 629 ProtocolHandlerRegistry* registry) OVERRIDE { 630 return NULL; 631 } 632 633 virtual void RegisterWithOSAsDefaultClient( 634 const std::string& protocol, 635 ProtocolHandlerRegistry* registry) OVERRIDE { 636 VLOG(1) << "Register With OS"; 637 } 638 }; 639 640 TEST_F(ContentSettingBubbleModelTest, RPHAllow) { 641 ProtocolHandlerRegistry registry(profile(), new FakeDelegate()); 642 registry.InitProtocolSettings(); 643 644 const GURL page_url("http://toplevel.example/"); 645 NavigateAndCommit(page_url); 646 TabSpecificContentSettings* content_settings = 647 TabSpecificContentSettings::FromWebContents(web_contents()); 648 ProtocolHandler test_handler = ProtocolHandler::CreateProtocolHandler( 649 "mailto", GURL("http://www.toplevel.example/"), 650 ASCIIToUTF16("Handler")); 651 content_settings->set_pending_protocol_handler(test_handler); 652 653 ContentSettingRPHBubbleModel content_setting_bubble_model( 654 NULL, web_contents(), profile(), ®istry, 655 CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS); 656 657 { 658 ProtocolHandler handler = registry.GetHandlerFor("mailto"); 659 EXPECT_TRUE(handler.IsEmpty()); 660 EXPECT_EQ(CONTENT_SETTING_DEFAULT, 661 content_settings->pending_protocol_handler_setting()); 662 } 663 664 // "0" is the "Allow" radio button. 665 content_setting_bubble_model.OnRadioClicked(0); 666 { 667 ProtocolHandler handler = registry.GetHandlerFor("mailto"); 668 ASSERT_FALSE(handler.IsEmpty()); 669 EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title()); 670 EXPECT_EQ(CONTENT_SETTING_ALLOW, 671 content_settings->pending_protocol_handler_setting()); 672 } 673 674 // "1" is the "Deny" radio button. 675 content_setting_bubble_model.OnRadioClicked(1); 676 { 677 ProtocolHandler handler = registry.GetHandlerFor("mailto"); 678 EXPECT_TRUE(handler.IsEmpty()); 679 EXPECT_EQ(CONTENT_SETTING_BLOCK, 680 content_settings->pending_protocol_handler_setting()); 681 } 682 683 // "2" is the "Ignore button. 684 content_setting_bubble_model.OnRadioClicked(2); 685 { 686 ProtocolHandler handler = registry.GetHandlerFor("mailto"); 687 EXPECT_TRUE(handler.IsEmpty()); 688 EXPECT_EQ(CONTENT_SETTING_DEFAULT, 689 content_settings->pending_protocol_handler_setting()); 690 EXPECT_TRUE(registry.IsIgnored(test_handler)); 691 } 692 693 // "0" is the "Allow" radio button. 694 content_setting_bubble_model.OnRadioClicked(0); 695 { 696 ProtocolHandler handler = registry.GetHandlerFor("mailto"); 697 ASSERT_FALSE(handler.IsEmpty()); 698 EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title()); 699 EXPECT_EQ(CONTENT_SETTING_ALLOW, 700 content_settings->pending_protocol_handler_setting()); 701 EXPECT_FALSE(registry.IsIgnored(test_handler)); 702 } 703 704 registry.Shutdown(); 705 } 706