permission_queue_controller.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Copyright 2013 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) 5a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/browser/content_settings/permission_queue_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/permission_context_uma_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/geolocation/geolocation_infobar_delegate.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/media/midi_permission_infobar_delegate.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/services/gcm/push_messaging_infobar_delegate.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/common/url_constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33a3f7b4e666c476898878fa745f637129375cd889Ben MurdochInfoBarService* GetInfoBarService(const PermissionRequestID& id) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents = 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PermissionQueueController::PendingInfobarRequest { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequest(ContentSettingsType type, 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const PermissionRequestID& id, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback); 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~PendingInfobarRequest(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsForPair(const GURL& requesting_frame, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder) const; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id() const { return id_; } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame() const { return requesting_frame_; } 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool has_infobar() const { return !!infobar_; } 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch infobars::InfoBar* infobar() { return infobar_; } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunCallback(bool allowed); 61a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch void CreateInfoBar(PermissionQueueController* controller, 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& display_languages); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ContentSettingsType type_; 66a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionRequestID id_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL requesting_frame_; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL embedder_; 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string accept_button_label_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback_; 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch infobars::InfoBar* infobar_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Purposefully do not disable copying, as this is stored in STL containers. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ContentSettingsType type, 78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : type_(type), 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) id_(id), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requesting_frame_(requesting_frame), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) embedder_(embedder), 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) accept_button_label_(accept_button_label), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch infobar_(NULL) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PermissionQueueController::PendingInfobarRequest::IsForPair( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder) const { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::PendingInfobarRequest::RunCallback( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allowed) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(allowed); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( 107a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionQueueController* controller, 108a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& display_languages) { 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) switch (type_) { 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_GEOLOCATION: 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) infobar_ = GeolocationInfoBarDelegate::Create( 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) display_languages, accept_button_label_); 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) infobar_ = MidiPermissionInfoBarDelegate::Create( 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch display_languages, type_); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING: 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch infobar_ = gcm::PushMessagingInfoBarDelegate::Create( 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetInfoBarService(id_), controller, id_, requesting_frame_, 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch display_languages, type_); 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) infobar_ = ProtectedMediaIdentifierInfoBarDelegate::Create( 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_languages); 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) default: 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPermissionQueueController::PermissionQueueController(Profile* profile, 140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ContentSettingsType type) 141a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch : profile_(profile), 142558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch type_(type), 143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_(false) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPermissionQueueController::~PermissionQueueController() { 147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Cancel all outstanding requests. 148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_ = true; 149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch while (!pending_infobar_requests_.empty()) 150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CancelInfoBarRequest(pending_infobar_requests_.front().id()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 153a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CreateInfoBarRequest( 154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (requesting_frame.SchemeIs(content::kChromeUIScheme) || 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch embedder.SchemeIs(content::kChromeUIScheme)) 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_infobar_requests_.push_back(PendingInfobarRequest( 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) type_, id, requesting_frame, embedder, 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) accept_button_label, callback)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AlreadyShowingInfoBarForTab(id)) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CancelInfoBarRequest( 173a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->id().Equals(id)) { 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->has_infobar()) 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(id)->RemoveInfoBar(i->infobar()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 188a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::OnPermissionSet( 189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool update_content_setting, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allowed) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(miguelg): move the permission persistence to 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // PermissionContextBase once all the types are moved there. 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (update_content_setting) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateContentSetting(requesting_frame, embedder, allowed); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (allowed) 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionGranted(type_); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionDenied(type_); 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionDismissed(type_); 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel this request first, then notify listeners. TODO(pkasting): Why 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is this order important? 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests requests_to_notify; 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests infobars_to_remove; 212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!i->IsForPair(requesting_frame, embedder)) 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) requests_to_notify.push_back(*i); 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!i->has_infobar()) { 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We haven't created an infobar yet, just record the pending request 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // index and remove it later. 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_requests_to_remove.push_back(i); 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (i->id().Equals(id)) { 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The infobar that called us is i->infobar(), and its delegate is 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // currently in either Accept() or Cancel(). This means that 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // RemoveInfoBar() will be called later on, and that will trigger a 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // notification we're observing. 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This infobar is for the same frame/embedder pair, but in a different 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // tab. We should remove it now that we've got an answer for it. 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) infobars_to_remove.push_back(*i); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Remove all infobars for the same |requesting_frame| and |embedder|. 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = infobars_to_remove.begin(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != infobars_to_remove.end(); ++i) 240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(i->id())->RemoveInfoBar(i->infobar()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send out the permission notifications. 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != requests_to_notify.end(); ++i) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->RunCallback(allowed); 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Remove the pending requests in reverse order. 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i) 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_infobar_requests_.erase(pending_requests_to_remove[i]); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::Observe( 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We will receive this notification for all infobar closures, so we need to 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check whether this is the geolocation infobar we're tracking. Note that the 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InfoBarContainer (if any) may have received this notification before us and 260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // caused the infobar to be deleted, so it's not safe to dereference the 261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // contents of the infobar. The address of the infobar, however, is OK to 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // use to find the PendingInfobarRequest to remove because 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending_infobar_requests_ will not have received any new entries between 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the NotificationService's call to InfoBarContainer::Observe and this 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method. 2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch infobars::InfoBar* infobar = 2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::Details<infobars::InfoBar::RemovedDetails>(details)->first; 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->infobar() == infobar) { 271a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionRequestID id(i->id()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 279a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool PermissionQueueController::AlreadyShowingInfoBarForTab( 280a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) const { 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::const_iterator i( 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.begin()); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && i->has_infobar()) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 290a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::ShowQueuedInfoBarForTab( 291a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!AlreadyShowingInfoBarForTab(id)); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // We can get here for example during tab shutdown, when the InfoBarService is 2952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // removing all existing infobars, thus calling back to Observe(). In this 296558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // case the service still exists, and is supplied as the source of the 297558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // notification we observed, but is no longer accessible from its WebContents. 298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // In this case we should just go ahead and cancel further infobars for this 299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // tab instead of trying to access the service. 300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Similarly, if we're being destroyed, we should also avoid showing further 302558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // infobars. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service = GetInfoBarService(id); 304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!infobar_service || in_shutdown_) { 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPendingInfobarRequestsForTab(id); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && !i->has_infobar()) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterForInfoBarNotifications(infobar_service); 313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch i->CreateInfoBar( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnregisterForInfoBarNotifications(infobar_service); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::ClearPendingInfobarRequestsForTab( 323a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ) { 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (i->id().IsForSameTabAs(id)) { 327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!i->has_infobar()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = pending_infobar_requests_.erase(i); 3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::RegisterForInfoBarNotifications( 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!registrar_.IsRegistered( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 346a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UnregisterForInfoBarNotifications( 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (registrar_.IsRegistered( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 357a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UpdateContentSetting( 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& requesting_frame, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& embedder, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool allowed) { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (requesting_frame.GetOrigin().SchemeIsFile()) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Chrome can be launched with --disable-web-security which allows 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // geolocation requests from file:// URLs. We don't want to store these 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the host content settings map. 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSetting content_setting = 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), 373a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch type_, 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_setting); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 377