| Index: chrome/browser/permissions/permission_infobar_request.cc
|
| diff --git a/chrome/browser/permissions/permission_infobar_request.cc b/chrome/browser/permissions/permission_infobar_request.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2bd12933b3ed1d22d32a416fab329a5d926f66cc
|
| --- /dev/null
|
| +++ b/chrome/browser/permissions/permission_infobar_request.cc
|
| @@ -0,0 +1,247 @@
|
| +// 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_request.h"
|
| +
|
| +#include "base/prefs/pref_service.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_manager.h"
|
| +#include "chrome/browser/permissions/permission_manager_factory.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/storage/durable_storage_permission_infobar_delegate_android.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "components/content_settings/core/browser/host_content_settings_map.h"
|
| +#include "components/infobars/core/infobar.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/permission_type.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/common/permission_status.mojom.h"
|
| +
|
| +using content::PermissionStatus;
|
| +using content::PermissionType;
|
| +
|
| +namespace {
|
| +
|
| +PermissionType ContentSettingsTypeToPermissionType(ContentSettingsType type) {
|
| + switch (type) {
|
| + case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
|
| + return PermissionType::MIDI_SYSEX;
|
| + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
|
| + return PermissionType::NOTIFICATIONS;
|
| + case CONTENT_SETTINGS_TYPE_GEOLOCATION:
|
| + return PermissionType::GEOLOCATION;
|
| +#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
|
| + case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
|
| + return PermissionType::PROTECTED_MEDIA_IDENTIFIER;
|
| +#endif
|
| + case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
|
| + return PermissionType::DURABLE_STORAGE;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + return PermissionType::GEOLOCATION;
|
| +}
|
| +
|
| +ContentSetting PermissionStatusToContentSetting(PermissionStatus status) {
|
| + switch (status) {
|
| + case content::PERMISSION_STATUS_GRANTED:
|
| + return CONTENT_SETTING_ALLOW;
|
| + case content::PERMISSION_STATUS_DENIED:
|
| + return CONTENT_SETTING_BLOCK;
|
| + case content::PERMISSION_STATUS_ASK:
|
| + return CONTENT_SETTING_ASK;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + return CONTENT_SETTING_BLOCK;
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| +PermissionInfoBarRequest::PermissionRequest::PermissionRequest(
|
| + ContentSettingsType type,
|
| + const PermissionDecidedCallback& callback)
|
| + : type_(type),
|
| + callback_(callback) {
|
| +}
|
| +
|
| +PermissionInfoBarRequest::PermissionRequest::~PermissionRequest() {
|
| +}
|
| +
|
| +PermissionInfoBarRequest::PermissionInfoBarRequest(
|
| + int request_id,
|
| + const GURL& requesting_origin,
|
| + const GURL& embedding_origin,
|
| + const base::Closure& callback)
|
| + : infobar_(nullptr),
|
| + request_id_(request_id),
|
| + requesting_origin_(requesting_origin),
|
| + embedding_origin_(embedding_origin),
|
| + callback_(callback),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +PermissionInfoBarRequest::~PermissionInfoBarRequest() {
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::AddPermission(
|
| + const ContentSettingsType type,
|
| + const PermissionDecidedCallback& callback) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(!infobar_);
|
| +
|
| + requests_.push_back(PermissionRequest(type, callback));
|
| +}
|
| +
|
| +bool PermissionInfoBarRequest::ShowInfobar(
|
| + content::WebContents* web_contents) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(!infobar_);
|
| +
|
| + Profile* profile =
|
| + Profile::FromBrowserContext(web_contents->GetBrowserContext());
|
| + DCHECK(profile);
|
| +
|
| + // After pruning if there is nothing left then just ignore this request.
|
| + PruneAnsweredPermissions(profile);
|
| + if (requests_.size() == 0)
|
| + return false;
|
| +
|
| + InfoBarService* infobar_service =
|
| + InfoBarService::FromWebContents(web_contents);
|
| + DCHECK(infobar_service);
|
| +
|
| + std::string display_languages =
|
| + profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
|
| + if (requests_.size() == 1) {
|
| + CreateInfoBar(
|
| + infobar_service,
|
| + requests_[0],
|
| + display_languages,
|
| + base::Bind(&PermissionInfoBarRequest::OnPermissionSet,
|
| + weak_factory_.GetWeakPtr()));
|
| + return true;
|
| + }
|
| +
|
| + // TODO(lalitm) once multiple permissions is ready to land, this
|
| + // should be implemented properly.
|
| + NOTIMPLEMENTED();
|
| + for (size_t i = 0; i < requests_.size(); ++i)
|
| + requests_[i].callback().Run(false, CONTENT_SETTING_DEFAULT);
|
| + return false;
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::AcceptForTests() {
|
| + OnCancel();
|
| + OnPermissionsSet(true,
|
| + std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_ALLOW));
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::ClosingForTests() {
|
| + OnCancel();
|
| + OnPermissionsSet(false,
|
| + std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_DEFAULT));
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::Cancel() {
|
| + OnCancel();
|
| + callback_.Run();
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::OnCancel() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(infobar_);
|
| +
|
| + infobar_->RemoveSelf();
|
| + infobar_ = nullptr;
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::OnPermissionSet(
|
| + bool update_content_setting,
|
| + bool allowed) {
|
| + OnPermissionsSet(update_content_setting,
|
| + std::vector<ContentSetting>(1,
|
| + allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK));
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::OnPermissionsSet(
|
| + bool update_content_setting,
|
| + const std::vector<ContentSetting>& result) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + // Set the infobar to nullptr so there is no attempt to remove it later.
|
| + infobar_ = nullptr;
|
| +
|
| + for (size_t i = 0; i < requests_.size(); ++i) {
|
| + if (!update_content_setting)
|
| + DCHECK_EQ(CONTENT_SETTING_DEFAULT, result[i]);
|
| + requests_[i].callback().Run(update_content_setting, result[i]);
|
| + }
|
| + callback_.Run();
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::PruneAnsweredPermissions(
|
| + Profile* profile) {
|
| + for (auto it = requests_.begin(); it != requests_.end();) {
|
| + PermissionStatus status = PermissionManagerFactory::GetForProfile(profile)
|
| + ->GetPermissionStatus(
|
| + ContentSettingsTypeToPermissionType(it->type()),
|
| + requesting_origin_,
|
| + embedding_origin_);
|
| + if (status == content::PERMISSION_STATUS_GRANTED ||
|
| + status == content::PERMISSION_STATUS_DENIED) {
|
| + it->callback().Run(true,
|
| + PermissionStatusToContentSetting(status));
|
| + it = requests_.erase(it);
|
| + } else {
|
| + ++it;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void PermissionInfoBarRequest::CreateInfoBar(
|
| + InfoBarService* infobar_service,
|
| + const PermissionRequest& request,
|
| + const std::string& display_languages,
|
| + const PermissionInfobarDelegate::PermissionSetCallback& callback) {
|
| + switch (request.type()) {
|
| + case CONTENT_SETTINGS_TYPE_GEOLOCATION:
|
| + infobar_ = GeolocationInfoBarDelegateAndroid::Create(
|
| + infobar_service, requesting_origin_,
|
| + display_languages, callback);
|
| + break;
|
| +#if defined(ENABLE_NOTIFICATIONS)
|
| + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
|
| + infobar_ = NotificationPermissionInfobarDelegate::Create(
|
| + infobar_service, requesting_origin_,
|
| + display_languages, callback);
|
| + break;
|
| +#endif // ENABLE_NOTIFICATIONS
|
| + case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
|
| + infobar_ = MidiPermissionInfoBarDelegateAndroid::Create(
|
| + infobar_service, requesting_origin_,
|
| + display_languages, request.type(), callback);
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
|
| + infobar_ = ProtectedMediaIdentifierInfoBarDelegateAndroid::Create(
|
| + infobar_service, requesting_origin_,
|
| + display_languages, callback);
|
| + break;
|
| + case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
|
| + infobar_ = DurableStoragePermissionInfoBarDelegateAndroid::Create(
|
| + infobar_service, requesting_origin_,
|
| + display_languages, request.type(), callback);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
|
|