15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/auto_reset.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/tab_specific_content_settings.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/blocked_content/blocked_content_container.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(BlockedContentTabHelper); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BlockedContentTabHelper::BlockedContentTabHelper( 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : content::WebContentsObserver(web_contents), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_(new BlockedContentContainer(web_contents)), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_contents_blocked_(false), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(NULL) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BlockedContentTabHelper::~BlockedContentTabHelper() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::DidNavigateMainFrame( 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::LoadCommittedDetails& details, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::FrameNavigateParams& params) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear all page actions, blocked content notifications and browser actions 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for this tab, unless this is an in-page navigation. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!details.is_in_page) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close blocked popups. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_contents_->GetBlockedContentsCount()) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->Clear(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupNotificationVisibilityChanged(false); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::PopupNotificationVisibilityChanged( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool visible) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!web_contents()->IsBeingDestroyed()) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabSpecificContentSettings::FromWebContents(web_contents())-> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPopupsBlocked(visible); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::SendNotification(content::WebContents* contents, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool blocked_state) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_CONTENT_BLOCKED_STATE_CHANGED, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::WebContents>(contents), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const bool>(&blocked_state)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::SetAllContentsBlocked(bool value) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (all_contents_blocked_ == value) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_contents_blocked_ = value; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!all_contents_blocked_ && blocked_contents_->GetBlockedContentsCount()) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<content::WebContents*> blocked; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->GetBlockedContents(&blocked); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < blocked.size(); ++i) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendNotification(blocked[i], false); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->LaunchForContents(blocked[i]); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::AddWebContents(content::WebContents* new_contents, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blocked_contents_->GetBlockedContentsCount()) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupNotificationVisibilityChanged(true); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendNotification(new_contents, true); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->AddWebContents( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_contents, disposition, initial_pos, user_gesture); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::AddPopup(content::WebContents* new_contents, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A page can't spawn popups (or do anything else, either) until its load 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // commits, so when we reach here, the popup was spawned by the 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NavigationController's last committed entry, not the active entry. For 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // example, if a page opens a popup in an onunload() handler, then the active 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entry is the page to be loaded as we navigate away from the unloading 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // page. For this reason, we can't use GetURL() to get the opener URL, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because it returns the active entry. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationEntry* entry = 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents()->GetController().GetLastCommittedEntry(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL creator = entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (creator.is_valid() && 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetHostContentSettingsMap()->GetContentSetting( 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) creator, creator, CONTENT_SETTINGS_TYPE_POPUPS, std::string()) == 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTING_ALLOW) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContentsDelegate* delegate = web_contents()->GetDelegate(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->AddNewContents(web_contents(), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_contents, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disposition, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_pos, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // user_gesture 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call blocked_contents_->AddWebContents with user_gesture == true 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that the contents will not get blocked again. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendNotification(new_contents, true); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->AddWebContents(new_contents, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disposition, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_pos, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); // user_gesture 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabSpecificContentSettings::FromWebContents(web_contents())-> 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS, std::string()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::LaunchForContents( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendNotification(web_contents, false); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->LaunchForContents(web_contents); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blocked_contents_->GetBlockedContentsCount()) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupNotificationVisibilityChanged(false); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t BlockedContentTabHelper::GetBlockedContentsCount() const { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return blocked_contents_->GetBlockedContentsCount(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlockedContentTabHelper::GetBlockedContents( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<content::WebContents*>* blocked_contents) const { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_contents_->GetBlockedContents(blocked_contents); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 153