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..c84d92c0104e5409a53024fa44e3ecab19dff36b |
--- /dev/null |
+++ b/chrome/browser/permissions/permission_infobar_request.cc |
@@ -0,0 +1,199 @@ |
+// 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/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/web_contents.h" |
+ |
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
+#include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" |
+#endif |
+ |
+PermissionInfoBarRequest::PermissionRequest::PermissionRequest( |
+ ContentSettingsType type, |
+ const PermissionDecidedCallback& response_callback) |
+ : type_(type), |
+ response_callback_(response_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& response_callback) { |
+ requests_.push_back(PermissionRequest(type, response_callback)); |
mlamouri (slow - plz ping)
2015/10/02 11:49:39
What if ::AddPermission() is called while the info
Lalit Maganti
2015/10/02 13:37:45
Done.
|
+} |
+ |
+bool PermissionInfoBarRequest::ShowInfobar( |
+ content::WebContents* web_contents) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ 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].response_callback().Run(false, CONTENT_SETTING_DEFAULT); |
+ return false; |
+} |
+ |
+void PermissionInfoBarRequest::Accept() { |
+ OnManualClose(); |
+ OnPermissionsSet(true, |
+ std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_ALLOW)); |
+} |
+ |
+void PermissionInfoBarRequest::Closing() { |
+ 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) { |
+ 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].response_callback() |
+ .Run(update_content_setting, |
+ update_content_setting ? allowed[i] : CONTENT_SETTING_DEFAULT); |
+ } |
+ callback_.Run(); |
+} |
+ |
+void PermissionInfoBarRequest::PruneAnsweredPermissions( |
+ Profile* profile) { |
+ for (auto it = requests_.begin(); it != requests_.end();) { |
+ ContentSetting content_setting = |
+ HostContentSettingsMapFactory::GetForProfile(profile) |
+ ->GetContentSettingAndMaybeUpdateLastUsage(requesting_origin_, |
+ embedding_origin_, it->type(), std::string()); |
mlamouri (slow - plz ping)
2015/10/02 11:49:39
Could you use PermissionManager here.
Lalit Maganti
2015/10/02 13:37:45
Done.
|
+ if (content_setting == CONTENT_SETTING_ALLOW || |
+ content_setting == CONTENT_SETTING_BLOCK) { |
+ it->response_callback().Run(true, content_setting); |
+ 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; |
+ } |
+} |