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" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_infobar_delegate.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/services/gcm/push_messaging_infobar_delegate.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/content_settings/core/common/content_settings.h" 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/common/url_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34a3f7b4e666c476898878fa745f637129375cd889Ben MurdochInfoBarService* GetInfoBarService(const PermissionRequestID& id) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents = 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id()); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PermissionQueueController::PendingInfobarRequest { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequest(ContentSettingsType type, 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const PermissionRequestID& id, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 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_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback_; 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch infobars::InfoBar* infobar_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Purposefully do not disable copying, as this is stored in STL containers. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ContentSettingsType type, 77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : type_(type), 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) id_(id), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requesting_frame_(requesting_frame), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) embedder_(embedder), 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) switch (type_) { 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_GEOLOCATION: 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) infobar_ = GeolocationInfoBarDelegate::Create( 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) display_languages); 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(ENABLE_NOTIFICATIONS) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) infobar_ = DesktopNotificationInfoBarDelegate::Create( 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) display_languages); 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // ENABLE_NOTIFICATIONS 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) infobar_ = MidiPermissionInfoBarDelegate::Create( 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch display_languages, type_); 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING: 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch infobar_ = gcm::PushMessagingInfoBarDelegate::Create( 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetInfoBarService(id_), controller, id_, requesting_frame_, 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch display_languages, type_); 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID) 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) infobar_ = ProtectedMediaIdentifierInfoBarDelegate::Create( 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetInfoBarService(id_), controller, id_, requesting_frame_, 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_languages); 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) default: 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPermissionQueueController::PermissionQueueController(Profile* profile, 144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ContentSettingsType type) 145a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch : profile_(profile), 146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch type_(type), 147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_(false) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPermissionQueueController::~PermissionQueueController() { 151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Cancel all outstanding requests. 152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch in_shutdown_ = true; 153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch while (!pending_infobar_requests_.empty()) 154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CancelInfoBarRequest(pending_infobar_requests_.front().id()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CreateInfoBarRequest( 158a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionDecidedCallback callback) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (requesting_frame.SchemeIs(content::kChromeUIScheme) || 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch embedder.SchemeIs(content::kChromeUIScheme)) 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_infobar_requests_.push_back(PendingInfobarRequest( 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_, id, requesting_frame, embedder, callback)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AlreadyShowingInfoBarForTab(id)) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::CancelInfoBarRequest( 175a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->id().Equals(id)) { 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->has_infobar()) 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(id)->RemoveInfoBar(i->infobar()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::OnPermissionSet( 191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& requesting_frame, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& embedder, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool update_content_setting, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allowed) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(miguelg): move the permission persistence to 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // PermissionContextBase once all the types are moved there. 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (update_content_setting) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateContentSetting(requesting_frame, embedder, allowed); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (allowed) 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionGranted(type_); 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionDenied(type_); 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionContextUmaUtil::PermissionDismissed(type_); 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel this request first, then notify listeners. TODO(pkasting): Why 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is this order important? 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests requests_to_notify; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PendingInfobarRequests infobars_to_remove; 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!i->IsForPair(requesting_frame, embedder)) 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) requests_to_notify.push_back(*i); 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!i->has_infobar()) { 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We haven't created an infobar yet, just record the pending request 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // index and remove it later. 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_requests_to_remove.push_back(i); 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (i->id().Equals(id)) { 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The infobar that called us is i->infobar(), and its delegate is 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // currently in either Accept() or Cancel(). This means that 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // RemoveInfoBar() will be called later on, and that will trigger a 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // notification we're observing. 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This infobar is for the same frame/embedder pair, but in a different 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // tab. We should remove it now that we've got an answer for it. 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) infobars_to_remove.push_back(*i); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Remove all infobars for the same |requesting_frame| and |embedder|. 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = infobars_to_remove.begin(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != infobars_to_remove.end(); ++i) 242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoBarService(i->id())->RemoveInfoBar(i->infobar()); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send out the permission notifications. 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != requests_to_notify.end(); ++i) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->RunCallback(allowed); 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Remove the pending requests in reverse order. 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i) 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) pending_infobar_requests_.erase(pending_requests_to_remove[i]); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 254a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::Observe( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We will receive this notification for all infobar closures, so we need to 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check whether this is the geolocation infobar we're tracking. Note that the 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InfoBarContainer (if any) may have received this notification before us and 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // caused the infobar to be deleted, so it's not safe to dereference the 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // contents of the infobar. The address of the infobar, however, is OK to 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // use to find the PendingInfobarRequest to remove because 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending_infobar_requests_ will not have received any new entries between 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the NotificationService's call to InfoBarContainer::Observe and this 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method. 2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch infobars::InfoBar* infobar = 2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::Details<infobars::InfoBar::RemovedDetails>(details)->first; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->infobar() == infobar) { 273a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PermissionRequestID id(i->id()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.erase(i); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowQueuedInfoBarForTab(id); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 281a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool PermissionQueueController::AlreadyShowingInfoBarForTab( 282a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) const { 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::const_iterator i( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_infobar_requests_.begin()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && i->has_infobar()) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::ShowQueuedInfoBarForTab( 293a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!AlreadyShowingInfoBarForTab(id)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 296558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // We can get here for example during tab shutdown, when the InfoBarService is 2972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // removing all existing infobars, thus calling back to Observe(). In this 298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // case the service still exists, and is supplied as the source of the 299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // notification we observed, but is no longer accessible from its WebContents. 300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // In this case we should just go ahead and cancel further infobars for this 301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // tab instead of trying to access the service. 302558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Similarly, if we're being destroyed, we should also avoid showing further 304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // infobars. 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service = GetInfoBarService(id); 306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!infobar_service || in_shutdown_) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearPendingInfobarRequestsForTab(id); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ++i) { 313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (i->id().IsForSameTabAs(id) && !i->has_infobar()) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterForInfoBarNotifications(infobar_service); 315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch i->CreateInfoBar( 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnregisterForInfoBarNotifications(infobar_service); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionQueueController::ClearPendingInfobarRequestsForTab( 325a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const PermissionRequestID& id) { 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_infobar_requests_.end(); ) { 3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (i->id().IsForSameTabAs(id)) { 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!i->has_infobar()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = pending_infobar_requests_.erase(i); 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 337a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::RegisterForInfoBarNotifications( 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!registrar_.IsRegistered( 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 348a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UnregisterForInfoBarNotifications( 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InfoBarService* infobar_service) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (registrar_.IsRegistered( 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service))) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<InfoBarService>(infobar_service)); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 359a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PermissionQueueController::UpdateContentSetting( 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& requesting_frame, 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& embedder, 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool allowed) { 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (requesting_frame.GetOrigin().SchemeIsFile()) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Chrome can be launched with --disable-web-security which allows 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // geolocation requests from file:// URLs. We don't want to store these 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the host content settings map. 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSetting content_setting = 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ContentSettingsPattern embedder_pattern = 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (type_ == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) ? 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ContentSettingsPattern::Wildcard() : 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()); 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci embedder_pattern, 381a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch type_, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_setting); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385