| Index: chrome/browser/permissions/permission_infobar_manager.cc
|
| diff --git a/chrome/browser/permissions/permission_infobar_manager.cc b/chrome/browser/permissions/permission_infobar_manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d23c0c57f9539c12cae07143091867fd82ca5261
|
| --- /dev/null
|
| +++ b/chrome/browser/permissions/permission_infobar_manager.cc
|
| @@ -0,0 +1,119 @@
|
| +// Copyright 2015 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_infobar_manager.h"
|
| +
|
| +#include "chrome/browser/chrome_notification_types.h"
|
| +#include "chrome/browser/infobars/infobar_service.h"
|
| +#include "chrome/browser/permissions/permission_infobar_request.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/tab_contents/tab_util.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/web_contents.h"
|
| +#include "content/public/common/url_constants.h"
|
| +
|
| +DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionInfoBarManager);
|
| +
|
| +PermissionInfoBarManager::PermissionInfoBarManager(
|
| + content::WebContents* web_contents)
|
| + : content::WebContentsObserver(web_contents),
|
| + is_show_pending_(false),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +PermissionInfoBarManager::~PermissionInfoBarManager() {
|
| +}
|
| +
|
| +void PermissionInfoBarManager::CreateRequest(
|
| + const ContentSettingsType type,
|
| + const PermissionRequestID& request_id,
|
| + const GURL& requesting_frame,
|
| + const GURL& embedder,
|
| + const PermissionDecidedCallback& callback) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(!current_request_.get() ||
|
| + current_request_->request_id() != request_id.request_id());
|
| +
|
| + if (requesting_frame.SchemeIs(content::kChromeUIScheme) ||
|
| + embedder.SchemeIs(content::kChromeUIScheme)) {
|
| + return;
|
| + }
|
| +
|
| + auto it = queued_requests_.find(request_id.request_id());
|
| + PermissionInfoBarRequest* request = nullptr;
|
| + if (it == queued_requests_.end()) {
|
| + request = new PermissionInfoBarRequest(request_id.request_id(),
|
| + requesting_frame, embedder,
|
| + base::Bind(&PermissionInfoBarManager::OnInfoBarClosed,
|
| + base::Unretained(this)));
|
| + queued_requests_.add(request_id.request_id(), make_scoped_ptr(request));
|
| +
|
| + // Try to trigger a show for this infobar.
|
| + TriggerShowNextQueuedRequest();
|
| + } else {
|
| + request = it->second;
|
| + }
|
| + request->AddPermission(type, callback);
|
| +}
|
| +
|
| +void PermissionInfoBarManager::CancelRequest(
|
| + const PermissionRequestID& request_id) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + if (current_request_.get() &&
|
| + current_request_->request_id() == request_id.request_id()) {
|
| + current_request_->Cancel();
|
| + return;
|
| + }
|
| +
|
| + // No-op if the request does not exist.
|
| + queued_requests_.erase(request_id.request_id());
|
| +}
|
| +
|
| +void PermissionInfoBarManager::TriggerShowNextQueuedRequest() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + if (is_show_pending_ || ShouldIgnoreQueuedRequests())
|
| + return;
|
| +
|
| + is_show_pending_ = true;
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&PermissionInfoBarManager::ShowNextQueuedRequest,
|
| + weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void PermissionInfoBarManager::ShowNextQueuedRequest() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + is_show_pending_ = false;
|
| + if (ShouldIgnoreQueuedRequests())
|
| + return;
|
| +
|
| + for (auto it = queued_requests_.begin(); it != queued_requests_.end();) {
|
| + // Increment the iterator as it will be invalidated.
|
| + scoped_ptr<PermissionInfoBarRequest> infobar_request =
|
| + queued_requests_.take_and_erase(it++);
|
| +
|
| + // If |ShowInfobar| return false then no infobar was shown and thus we
|
| + // should go to the next queued request.
|
| + if (infobar_request->ShowInfobar(web_contents())) {
|
| + current_request_.reset(infobar_request.release());
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void PermissionInfoBarManager::OnInfoBarClosed() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + current_request_.reset();
|
| + TriggerShowNextQueuedRequest();
|
| +}
|
| +
|
| +bool PermissionInfoBarManager::ShouldIgnoreQueuedRequests() {
|
| + return current_request_.get() || queued_requests_.empty();
|
| +}
|
|
|