permission_queue_controller.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/geolocation/geolocation_infobar_delegate.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/infobars/infobar.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" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30a3f7b4e666c476898878fa745f637129375cd889Ben MurdochInfoBarService* GetInfoBarService(const PermissionRequestID& id) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents = 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id()); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PermissionQueueController::PendingInfobarRequest { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequest(ContentSettingsType type, 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const PermissionRequestID& id, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~PendingInfobarRequest(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsForPair(const GURL& requesting_frame, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder) const; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id() const { return id_; } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame() const { return requesting_frame_; } 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool has_infobar() const { return !!infobar_; } 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InfoBar* infobar() { return infobar_; } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunCallback(bool allowed); 58a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch void CreateInfoBar(PermissionQueueController* controller, 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& display_languages); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ContentSettingsType type_; 63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionRequestID id_; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL requesting_frame_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL embedder_; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string accept_button_label_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback_; 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InfoBar* infobar_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Purposefully do not disable copying, as this is stored in STL containers. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ContentSettingsType type, 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : type_(type), 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) id_(id), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requesting_frame_(requesting_frame), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) embedder_(embedder), 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) accept_button_label_(accept_button_label), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch infobar_(NULL) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PermissionQueueController::PendingInfobarRequest::IsForPair( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder) const { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::PendingInfobarRequest::RunCallback( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allowed) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(allowed); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( 104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionQueueController* controller, 105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& display_languages) { 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // TODO(toyoshim): Remove following ContentType dependent code. 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Also these InfoBarDelegate can share much more code each other. 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // http://crbug.com/266743 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_, 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) display_languages); 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) infobar_ = ProtectedMediaIdentifierInfoBarDelegate::Create( 12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_languages); 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) default: 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPermissionQueueController::PermissionQueueController(Profile* profile, 135558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ContentSettingsType type) 136a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch : profile_(profile), 137558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch type_(type), 138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_(false) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 141a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPermissionQueueController::~PermissionQueueController() { 142558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Cancel all outstanding requests. 143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_ = true; 144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch while (!pending_infobar_requests_.empty()) 145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CancelInfoBarRequest(pending_infobar_requests_.front().id()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CreateInfoBarRequest( 149a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& accept_button_label, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't get duplicate requests. 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::const_iterator i( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.begin()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!i->id().Equals(id)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_infobar_requests_.push_back(PendingInfobarRequest( 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) type_, id, requesting_frame, embedder, 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) accept_button_label, callback)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AlreadyShowingInfoBarForTab(id)) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 169a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CancelInfoBarRequest( 170a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->id().Equals(id)) { 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->has_infobar()) 177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(id)->RemoveInfoBar(i->infobar()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::CancelInfoBarRequests(int group_id) { 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we remove an infobar in the following loop, the next pending infobar 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will be shown. Therefore, we erase all the pending infobars first and 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // remove an infobar later. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests infobar_requests_to_cancel; 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i != pending_infobar_requests_.end();) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i->id().group_id() == group_id) { 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i->has_infobar()) { 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |i| will be erased from |pending_infobar_requests_| 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // in |PermissionQueueController::Observe| when the infobar is removed. 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) infobar_requests_to_cancel.push_back(*i); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++i; 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i = pending_infobar_requests_.erase(i); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++i; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = infobar_requests_to_cancel.begin(); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i != infobar_requests_to_cancel.end(); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++i) { 211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(i->id())->RemoveInfoBar(i->infobar()); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::OnPermissionSet( 216a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool update_content_setting, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allowed) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update_content_setting) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateContentSetting(requesting_frame, embedder, allowed); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel this request first, then notify listeners. TODO(pkasting): Why 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is this order important? 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests requests_to_notify; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests infobars_to_remove; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->IsForPair(requesting_frame, embedder)) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requests_to_notify.push_back(*i); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->id().Equals(id)) { 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The infobar that called us is i->infobar(), and its delegate is 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // currently in either Accept() or Cancel(). This means that 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // RemoveInfoBar() will be called later on, and that will trigger a 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // notification we're observing. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else if (i->has_infobar()) { 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // This infobar is for the same frame/embedder pair, but in a different 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tab. We should remove it now that we've got an answer for it. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobars_to_remove.push_back(*i); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We haven't created an infobar yet, just remove the pending request. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = pending_infobar_requests_.erase(i); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Remove all infobars for the same |requesting_frame| and |embedder|. 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = infobars_to_remove.begin(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != infobars_to_remove.end(); ++i) 257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(i->id())->RemoveInfoBar(i->infobar()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send out the permission notifications. 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != requests_to_notify.end(); ++i) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->RunCallback(allowed); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::Observe( 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We will receive this notification for all infobar closures, so we need to 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check whether this is the geolocation infobar we're tracking. Note that the 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InfoBarContainer (if any) may have received this notification before us and 273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // caused the infobar to be deleted, so it's not safe to dereference the 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // contents of the infobar. The address of the infobar, however, is OK to 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // use to find the PendingInfobarRequest to remove because 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending_infobar_requests_ will not have received any new entries between 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the NotificationService's call to InfoBarContainer::Observe and this 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method. 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InfoBar* infobar = content::Details<InfoBar::RemovedDetails>(details)->first; 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->infobar() == infobar) { 283a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionRequestID id(i->id()); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool PermissionQueueController::AlreadyShowingInfoBarForTab( 292a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) const { 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::const_iterator i( 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.begin()); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && i->has_infobar()) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::ShowQueuedInfoBarForTab( 303a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!AlreadyShowingInfoBarForTab(id)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // We can get here for example during tab shutdown, when the InfoBarService is 3072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // removing all existing infobars, thus calling back to Observe(). In this 308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // case the service still exists, and is supplied as the source of the 309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // notification we observed, but is no longer accessible from its WebContents. 310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // In this case we should just go ahead and cancel further infobars for this 311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // tab instead of trying to access the service. 312558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Similarly, if we're being destroyed, we should also avoid showing further 314558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // infobars. 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service = GetInfoBarService(id); 316558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!infobar_service || in_shutdown_) { 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPendingInfobarRequestsForTab(id); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && !i->has_infobar()) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterForInfoBarNotifications(infobar_service); 325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch i->CreateInfoBar( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnregisterForInfoBarNotifications(infobar_service); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::ClearPendingInfobarRequestsForTab( 335a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ) { 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (i->id().IsForSameTabAs(id)) { 339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!i->has_infobar()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = pending_infobar_requests_.erase(i); 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 347a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::RegisterForInfoBarNotifications( 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!registrar_.IsRegistered( 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 358a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UnregisterForInfoBarNotifications( 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (registrar_.IsRegistered( 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 369a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UpdateContentSetting( 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& requesting_frame, 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& embedder, 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool allowed) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (requesting_frame.GetOrigin().SchemeIsFile()) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Chrome can be launched with --disable-web-security which allows 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // geolocation requests from file:// URLs. We don't want to store these 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the host content settings map. 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSetting content_setting = 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), 385a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch type_, 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_setting); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 389