Chromium Code Reviews| 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..7e688eafc3033681282d8094182e8a203f230d4d |
| --- /dev/null |
| +++ b/chrome/browser/permissions/permission_infobar_request.cc |
| @@ -0,0 +1,252 @@ |
| +// 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.h" |
| +#include "chrome/browser/infobars/infobar_service.h" |
| +#include "chrome/browser/media/midi_permission_infobar_delegate.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.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" |
| + |
| +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| +#include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" |
| +#endif |
| + |
| +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() { |
| + OnManualClose(); |
| + OnPermissionsSet(true, |
| + std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_ALLOW)); |
| +} |
| + |
| +void PermissionInfoBarRequest::ClosingForTests() { |
| + OnManualClose(); |
| + OnPermissionsSet(false, |
| + std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_DEFAULT)); |
| +} |
| + |
| +void PermissionInfoBarRequest::Cancel() { |
| + OnManualClose(); |
| + callback_.Run(); |
| +} |
| + |
| +void PermissionInfoBarRequest::OnManualClose() { |
| + 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>& allowed) { |
|
mlamouri (slow - plz ping)
2015/10/02 15:51:07
nit: allowed isn't a great named
Lalit Maganti
2015/10/02 16:06:43
Done.
|
| + 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) { |
| + requests_[i].callback() |
| + .Run(update_content_setting, |
| + update_content_setting ? allowed[i] : CONTENT_SETTING_DEFAULT); |
|
mlamouri (slow - plz ping)
2015/10/02 15:51:07
Shouldn't that be a DCHECK()? that if !update_cont
Lalit Maganti
2015/10/02 16:06:43
Done.
|
| + } |
| + 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_ = GeolocationInfoBarDelegate::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_ = MidiPermissionInfoBarDelegate::Create( |
| + infobar_service, requesting_origin_, |
| + display_languages, request.type(), callback); |
| + break; |
| +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| + case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: |
| + infobar_ = ProtectedMediaIdentifierInfoBarDelegate::Create( |
| + infobar_service, requesting_origin_, |
| + display_languages, callback); |
| + break; |
| +#endif |
| + case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE: |
| + infobar_ = DurableStoragePermissionInfoBarDelegate::Create( |
| + infobar_service, requesting_origin_, |
| + display_languages, request.type(), callback); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |