| Index: chrome/browser/permissions/permission_queue_controller.cc
|
| diff --git a/chrome/browser/permissions/permission_queue_controller.cc b/chrome/browser/permissions/permission_queue_controller.cc
|
| deleted file mode 100644
|
| index 9f45d7c3242397bfa57189aede41fcbbc2fd955d..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/permissions/permission_queue_controller.cc
|
| +++ /dev/null
|
| @@ -1,413 +0,0 @@
|
| -// Copyright 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/permissions/permission_queue_controller.h"
|
| -
|
| -#include "base/prefs/pref_service.h"
|
| -#include "chrome/browser/chrome_notification_types.h"
|
| -#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
|
| -#include "chrome/browser/geolocation/geolocation_infobar_delegate_android.h"
|
| -#include "chrome/browser/infobars/infobar_service.h"
|
| -#include "chrome/browser/media/midi_permission_infobar_delegate_android.h"
|
| -#include "chrome/browser/media/protected_media_identifier_infobar_delegate_android.h"
|
| -#include "chrome/browser/notifications/notification_permission_infobar_delegate.h"
|
| -#include "chrome/browser/permissions/permission_context_uma_util.h"
|
| -#include "chrome/browser/permissions/permission_request_id.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/storage/durable_storage_permission_infobar_delegate_android.h"
|
| -#include "chrome/browser/tab_contents/tab_util.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "components/content_settings/core/browser/host_content_settings_map.h"
|
| -#include "components/content_settings/core/common/content_settings.h"
|
| -#include "components/infobars/core/infobar.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/notification_details.h"
|
| -#include "content/public/browser/notification_source.h"
|
| -#include "content/public/browser/notification_types.h"
|
| -#include "content/public/browser/web_contents.h"
|
| -#include "content/public/common/url_constants.h"
|
| -
|
| -namespace {
|
| -
|
| -InfoBarService* GetInfoBarService(const PermissionRequestID& id) {
|
| - content::WebContents* web_contents = tab_util::GetWebContentsByFrameID(
|
| - id.render_process_id(), id.render_frame_id());
|
| - return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL;
|
| -}
|
| -
|
| -bool ArePermissionRequestsForSameTab(
|
| - const PermissionRequestID& request,
|
| - const PermissionRequestID& other_request) {
|
| - content::WebContents* web_contents = tab_util::GetWebContentsByFrameID(
|
| - request.render_process_id(), request.render_frame_id());
|
| - content::WebContents* other_web_contents = tab_util::GetWebContentsByFrameID(
|
| - other_request.render_process_id(), other_request.render_frame_id());
|
| -
|
| - return web_contents == other_web_contents;
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| -class PermissionQueueController::PendingInfobarRequest {
|
| - public:
|
| - PendingInfobarRequest(ContentSettingsType type,
|
| - const PermissionRequestID& id,
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder,
|
| - const PermissionDecidedCallback& callback);
|
| - ~PendingInfobarRequest();
|
| -
|
| - bool IsForPair(const GURL& requesting_frame,
|
| - const GURL& embedder) const;
|
| -
|
| - const PermissionRequestID& id() const { return id_; }
|
| - const GURL& requesting_frame() const { return requesting_frame_; }
|
| - bool has_infobar() const { return !!infobar_; }
|
| - infobars::InfoBar* infobar() { return infobar_; }
|
| -
|
| - void RunCallback(ContentSetting content_setting);
|
| - void CreateInfoBar(PermissionQueueController* controller,
|
| - const std::string& display_languages);
|
| -
|
| - private:
|
| - ContentSettingsType type_;
|
| - PermissionRequestID id_;
|
| - GURL requesting_frame_;
|
| - GURL embedder_;
|
| - PermissionDecidedCallback callback_;
|
| - infobars::InfoBar* infobar_;
|
| -
|
| - // Purposefully do not disable copying, as this is stored in STL containers.
|
| -};
|
| -
|
| -PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest(
|
| - ContentSettingsType type,
|
| - const PermissionRequestID& id,
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder,
|
| - const PermissionDecidedCallback& callback)
|
| - : type_(type),
|
| - id_(id),
|
| - requesting_frame_(requesting_frame),
|
| - embedder_(embedder),
|
| - callback_(callback),
|
| - infobar_(NULL) {
|
| -}
|
| -
|
| -PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() {
|
| -}
|
| -
|
| -bool PermissionQueueController::PendingInfobarRequest::IsForPair(
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder) const {
|
| - return (requesting_frame_ == requesting_frame) && (embedder_ == embedder);
|
| -}
|
| -
|
| -void PermissionQueueController::PendingInfobarRequest::RunCallback(
|
| - ContentSetting content_setting) {
|
| - callback_.Run(content_setting);
|
| -}
|
| -
|
| -void PermissionQueueController::PendingInfobarRequest::CreateInfoBar(
|
| - PermissionQueueController* controller,
|
| - const std::string& display_languages) {
|
| - // Controller can be Unretained because the lifetime of the infobar
|
| - // is tied to that of the queue controller. Before QueueController
|
| - // is destroyed, all requests will be cancelled and so all delegates
|
| - // will be destroyed.
|
| - PermissionInfobarDelegate::PermissionSetCallback callback =
|
| - base::Bind(&PermissionQueueController::OnPermissionSet,
|
| - base::Unretained(controller),
|
| - id_,
|
| - requesting_frame_,
|
| - embedder_);
|
| - switch (type_) {
|
| - case CONTENT_SETTINGS_TYPE_GEOLOCATION:
|
| - infobar_ = GeolocationInfoBarDelegateAndroid::Create(
|
| - GetInfoBarService(id_), requesting_frame_, display_languages,
|
| - callback);
|
| - break;
|
| -#if defined(ENABLE_NOTIFICATIONS)
|
| - case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
|
| - infobar_ = NotificationPermissionInfobarDelegate::Create(
|
| - GetInfoBarService(id_), requesting_frame_,
|
| - display_languages, callback);
|
| - break;
|
| -#endif // ENABLE_NOTIFICATIONS
|
| - case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
|
| - infobar_ = MidiPermissionInfoBarDelegateAndroid::Create(
|
| - GetInfoBarService(id_), requesting_frame_, display_languages, type_,
|
| - callback);
|
| - break;
|
| - case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
|
| - infobar_ = ProtectedMediaIdentifierInfoBarDelegateAndroid::Create(
|
| - GetInfoBarService(id_), requesting_frame_, display_languages,
|
| - callback);
|
| - break;
|
| - case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
|
| - infobar_ = DurableStoragePermissionInfoBarDelegateAndroid::Create(
|
| - GetInfoBarService(id_), requesting_frame_, display_languages, type_,
|
| - callback);
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| -
|
| -PermissionQueueController::PermissionQueueController(Profile* profile,
|
| - ContentSettingsType type)
|
| - : profile_(profile),
|
| - type_(type),
|
| - in_shutdown_(false) {
|
| -}
|
| -
|
| -PermissionQueueController::~PermissionQueueController() {
|
| - // Cancel all outstanding requests.
|
| - in_shutdown_ = true;
|
| - while (!pending_infobar_requests_.empty())
|
| - CancelInfoBarRequest(pending_infobar_requests_.front().id());
|
| -}
|
| -
|
| -void PermissionQueueController::CreateInfoBarRequest(
|
| - const PermissionRequestID& id,
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder,
|
| - const PermissionDecidedCallback& callback) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| -
|
| - if (requesting_frame.SchemeIs(content::kChromeUIScheme) ||
|
| - embedder.SchemeIs(content::kChromeUIScheme))
|
| - return;
|
| -
|
| - pending_infobar_requests_.push_back(PendingInfobarRequest(
|
| - type_, id, requesting_frame, embedder, callback));
|
| - if (!AlreadyShowingInfoBarForTab(id))
|
| - ShowQueuedInfoBarForTab(id);
|
| -}
|
| -
|
| -void PermissionQueueController::CancelInfoBarRequest(
|
| - const PermissionRequestID& id) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| -
|
| - for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin());
|
| - i != pending_infobar_requests_.end(); ++i) {
|
| - if (id != i->id())
|
| - continue;
|
| -
|
| - InfoBarService* infobar_service = GetInfoBarService(id);
|
| - if (infobar_service && i->has_infobar())
|
| - infobar_service->RemoveInfoBar(i->infobar());
|
| - else
|
| - pending_infobar_requests_.erase(i);
|
| - return;
|
| - }
|
| -}
|
| -
|
| -void PermissionQueueController::OnPermissionSet(
|
| - const PermissionRequestID& id,
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder,
|
| - bool update_content_setting,
|
| - bool allowed) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| -
|
| - // TODO(miguelg): move the permission persistence to
|
| - // PermissionContextBase once all the types are moved there.
|
| - if (update_content_setting) {
|
| - UpdateContentSetting(requesting_frame, embedder, allowed);
|
| - if (allowed)
|
| - PermissionContextUmaUtil::PermissionGranted(type_, requesting_frame);
|
| - else
|
| - PermissionContextUmaUtil::PermissionDenied(type_, requesting_frame);
|
| - } else {
|
| - PermissionContextUmaUtil::PermissionDismissed(type_, requesting_frame);
|
| - }
|
| -
|
| - // Cancel this request first, then notify listeners. TODO(pkasting): Why
|
| - // is this order important?
|
| - PendingInfobarRequests requests_to_notify;
|
| - PendingInfobarRequests infobars_to_remove;
|
| - std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove;
|
| - for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
|
| - i != pending_infobar_requests_.end(); ++i) {
|
| - if (!i->IsForPair(requesting_frame, embedder))
|
| - continue;
|
| - requests_to_notify.push_back(*i);
|
| - if (!i->has_infobar()) {
|
| - // We haven't created an infobar yet, just record the pending request
|
| - // index and remove it later.
|
| - pending_requests_to_remove.push_back(i);
|
| - continue;
|
| - }
|
| - if (id == i->id()) {
|
| - // The infobar that called us is i->infobar(), and its delegate is
|
| - // currently in either Accept() or Cancel(). This means that
|
| - // RemoveInfoBar() will be called later on, and that will trigger a
|
| - // notification we're observing.
|
| - continue;
|
| - }
|
| -
|
| - // This infobar is for the same frame/embedder pair, but in a different
|
| - // tab. We should remove it now that we've got an answer for it.
|
| - infobars_to_remove.push_back(*i);
|
| - }
|
| -
|
| - // Remove all infobars for the same |requesting_frame| and |embedder|.
|
| - for (PendingInfobarRequests::iterator i = infobars_to_remove.begin();
|
| - i != infobars_to_remove.end(); ++i)
|
| - GetInfoBarService(i->id())->RemoveInfoBar(i->infobar());
|
| -
|
| - // PermissionContextBase needs to know about the new ContentSetting value,
|
| - // CONTENT_SETTING_DEFAULT being the value for nothing happened. The callers
|
| - // of ::OnPermissionSet passes { true, true } for allow, { true, false } for
|
| - // block and { false, * } for dismissed. The tuple being
|
| - // { update_content_setting, allowed }.
|
| - ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
|
| - if (update_content_setting) {
|
| - content_setting = allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
|
| - }
|
| -
|
| - // Send out the permission notifications.
|
| - for (PendingInfobarRequests::iterator i = requests_to_notify.begin();
|
| - i != requests_to_notify.end(); ++i)
|
| - i->RunCallback(content_setting);
|
| -
|
| - // Remove the pending requests in reverse order.
|
| - for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i)
|
| - pending_infobar_requests_.erase(pending_requests_to_remove[i]);
|
| -}
|
| -
|
| -void PermissionQueueController::Observe(
|
| - int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
|
| - // We will receive this notification for all infobar closures, so we need to
|
| - // check whether this is the geolocation infobar we're tracking. Note that the
|
| - // InfoBarContainer (if any) may have received this notification before us and
|
| - // caused the infobar to be deleted, so it's not safe to dereference the
|
| - // contents of the infobar. The address of the infobar, however, is OK to
|
| - // use to find the PendingInfobarRequest to remove because
|
| - // pending_infobar_requests_ will not have received any new entries between
|
| - // the NotificationService's call to InfoBarContainer::Observe and this
|
| - // method.
|
| - infobars::InfoBar* infobar =
|
| - content::Details<infobars::InfoBar::RemovedDetails>(details)->first;
|
| - for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
|
| - i != pending_infobar_requests_.end(); ++i) {
|
| - if (i->infobar() == infobar) {
|
| - PermissionRequestID id(i->id());
|
| - pending_infobar_requests_.erase(i);
|
| - ShowQueuedInfoBarForTab(id);
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool PermissionQueueController::AlreadyShowingInfoBarForTab(
|
| - const PermissionRequestID& id) const {
|
| - for (PendingInfobarRequests::const_iterator i(
|
| - pending_infobar_requests_.begin());
|
| - i != pending_infobar_requests_.end(); ++i) {
|
| - if (ArePermissionRequestsForSameTab(i->id(), id) && i->has_infobar())
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void PermissionQueueController::ShowQueuedInfoBarForTab(
|
| - const PermissionRequestID& id) {
|
| - DCHECK(!AlreadyShowingInfoBarForTab(id));
|
| -
|
| - // We can get here for example during tab shutdown, when the InfoBarService is
|
| - // removing all existing infobars, thus calling back to Observe(). In this
|
| - // case the service still exists, and is supplied as the source of the
|
| - // notification we observed, but is no longer accessible from its WebContents.
|
| - // In this case we should just go ahead and cancel further infobars for this
|
| - // tab instead of trying to access the service.
|
| - //
|
| - // Similarly, if we're being destroyed, we should also avoid showing further
|
| - // infobars.
|
| - InfoBarService* infobar_service = GetInfoBarService(id);
|
| - if (!infobar_service || in_shutdown_) {
|
| - ClearPendingInfobarRequestsForTab(id);
|
| - return;
|
| - }
|
| -
|
| - for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
|
| - i != pending_infobar_requests_.end(); ++i) {
|
| - if (ArePermissionRequestsForSameTab(i->id(), id) && !i->has_infobar()) {
|
| - RegisterForInfoBarNotifications(infobar_service);
|
| - i->CreateInfoBar(
|
| - this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
|
| - return;
|
| - }
|
| - }
|
| -
|
| - UnregisterForInfoBarNotifications(infobar_service);
|
| -}
|
| -
|
| -void PermissionQueueController::ClearPendingInfobarRequestsForTab(
|
| - const PermissionRequestID& id) {
|
| - for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
|
| - i != pending_infobar_requests_.end(); ) {
|
| - if (ArePermissionRequestsForSameTab(i->id(), id)) {
|
| - DCHECK(!i->has_infobar());
|
| - i = pending_infobar_requests_.erase(i);
|
| - } else {
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void PermissionQueueController::RegisterForInfoBarNotifications(
|
| - InfoBarService* infobar_service) {
|
| - if (!registrar_.IsRegistered(
|
| - this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
|
| - content::Source<InfoBarService>(infobar_service))) {
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
|
| - content::Source<InfoBarService>(infobar_service));
|
| - }
|
| -}
|
| -
|
| -void PermissionQueueController::UnregisterForInfoBarNotifications(
|
| - InfoBarService* infobar_service) {
|
| - if (registrar_.IsRegistered(
|
| - this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
|
| - content::Source<InfoBarService>(infobar_service))) {
|
| - registrar_.Remove(this,
|
| - chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
|
| - content::Source<InfoBarService>(infobar_service));
|
| - }
|
| -}
|
| -
|
| -void PermissionQueueController::UpdateContentSetting(
|
| - const GURL& requesting_frame,
|
| - const GURL& embedder,
|
| - bool allowed) {
|
| - if (requesting_frame.GetOrigin().SchemeIsFile()) {
|
| - // Chrome can be launched with --disable-web-security which allows
|
| - // geolocation requests from file:// URLs. We don't want to store these
|
| - // in the host content settings map.
|
| - return;
|
| - }
|
| -
|
| - ContentSetting content_setting =
|
| - allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
|
| -
|
| - ContentSettingsPattern embedder_pattern =
|
| - (type_ == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) ?
|
| - ContentSettingsPattern::Wildcard() :
|
| - ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin());
|
| -
|
| - HostContentSettingsMapFactory::GetForProfile(profile_)->SetContentSetting(
|
| - ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()),
|
| - embedder_pattern,
|
| - type_,
|
| - std::string(),
|
| - content_setting);
|
| -}
|
|
|