diff --git a/browser/permissions/permission_manager_browsertest.cc b/browser/permissions/permission_manager_browsertest.cc index e18ea49225b..af85d9b9811 100644 --- a/browser/permissions/permission_manager_browsertest.cc +++ b/browser/permissions/permission_manager_browsertest.cc @@ -118,7 +118,7 @@ class PermissionManagerBrowserTest : public InProcessBrowserTest { BravePermissionManager* permission_manager() { return permission_manager_; } bool IsPendingGroupedRequestsEmpty(ContentSettingsType type) { - ContentSettingPermissionContextBase* context = + PermissionContextBase* context = permission_manager()->GetPermissionContextForTesting(type); return context->IsPendingGroupedRequestsEmptyForTesting(); } diff --git a/chromium_src/components/permissions/content_setting_permission_context_base.cc b/chromium_src/components/permissions/content_setting_permission_context_base.cc deleted file mode 100644 index 49de7d2fb1c..00000000000 --- a/chromium_src/components/permissions/content_setting_permission_context_base.cc +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (c) 2021 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. */ - -#include "components/permissions/content_setting_permission_context_base.h" - -#include "base/check.h" -#include "components/permissions/permissions_client.h" - -#define ContentSettingPermissionContextBase \ - ContentSettingPermissionContextBase_ChromiumImpl -#include -#undef ContentSettingPermissionContextBase - -#include "brave/components/permissions/permission_lifetime_manager.h" - -namespace { - -bool IsGroupedPermissionType(ContentSettingsType type) { - return type == ContentSettingsType::BRAVE_ETHEREUM || - type == ContentSettingsType::BRAVE_SOLANA || - type == ContentSettingsType::BRAVE_CARDANO; -} - -} // namespace - -namespace permissions { - -ContentSettingPermissionContextBase::ContentSettingPermissionContextBase( - content::BrowserContext* browser_context, - ContentSettingsType content_settings_type, - network::mojom::PermissionsPolicyFeature permissions_policy_feature) - : ContentSettingPermissionContextBase_ChromiumImpl( - browser_context, - content_settings_type, - permissions_policy_feature) {} - -ContentSettingPermissionContextBase::~ContentSettingPermissionContextBase() = - default; - -void ContentSettingPermissionContextBase::SetPermissionLifetimeManagerFactory( - const base::RepeatingCallback< - PermissionLifetimeManager*(content::BrowserContext*)>& factory) { - permission_lifetime_manager_factory_ = factory; -} - -void ContentSettingPermissionContextBase::PermissionDecided( - PermissionDecision decision, - bool is_final_decision, - const PermissionRequestData& request_data) { - if (permission_lifetime_manager_factory_) { - const auto request_it = pending_requests_.find(request_data.id.ToString()); - if (request_it != pending_requests_.end()) { - const PermissionRequest* permission_request = - request_it->second.first.get(); - DCHECK(permission_request); - if (auto* permission_lifetime_manager = - permission_lifetime_manager_factory_.Run(browser_context_)) { - permission_lifetime_manager->PermissionDecided( - *permission_request, request_data.requesting_origin, - request_data.embedding_origin, decision); - } - } - const auto group_request_it = - pending_grouped_requests_.find(request_data.id.ToString()); - if (group_request_it != pending_grouped_requests_.end()) { - for (const auto& request : group_request_it->second->Requests()) { - const PermissionRequest* permission_request = request.first.get(); - DCHECK(permission_request); - if (auto* permission_lifetime_manager = - permission_lifetime_manager_factory_.Run(browser_context_)) { - permission_lifetime_manager->PermissionDecided( - *permission_request, request_data.requesting_origin, - request_data.embedding_origin, decision); - } - } - } - } - - if (!IsGroupedPermissionType(content_settings_type())) { - ContentSettingPermissionContextBase_ChromiumImpl::PermissionDecided( - decision, is_final_decision, request_data); - return; - } - - DCHECK(decision == PermissionDecision::kAllow || - decision == PermissionDecision::kDeny || - decision == PermissionDecision::kNone); - UserMadePermissionDecision(request_data.id, request_data.requesting_origin, - request_data.embedding_origin, decision); - - bool persist = (decision == PermissionDecision::kAllow || - decision == PermissionDecision::kDeny); - - auto grouped_request = - pending_grouped_requests_.find(request_data.id.ToString()); - DCHECK(grouped_request != pending_grouped_requests_.end()); - DCHECK(grouped_request->second); - - if (grouped_request->second->IsDone()) { - return; - } - - auto callback = grouped_request->second->GetNextCallback(); - if (callback) { - NotifyPermissionSet(request_data, std::move(callback), persist, decision, - is_final_decision); - } -} - -void ContentSettingPermissionContextBase::DecidePermission( - std::unique_ptr request_data, - BrowserPermissionCallback callback) { - auto id = request_data->id; - ContentSettingPermissionContextBase_ChromiumImpl::DecidePermission( - std::move(request_data), std::move(callback)); - - if (!IsGroupedPermissionType(content_settings_type())) { - return; - } - - // Move added pending request from pending_requests_ to - // pending_grouped_requests_, because otherwise Chromium will replace this - // pending_request with next sub-request because it does not expect multiple - // sub-requests in the same type for one RequestPermissions request. - auto pending_request = pending_requests_.find(id.ToString()); - DCHECK(pending_request != pending_requests_.end()); - - auto it = pending_grouped_requests_.find(id.ToString()); - if (it == pending_grouped_requests_.end()) { - it = pending_grouped_requests_ - .insert(std::make_pair( - id.ToString(), std::make_unique())) - .first; - } - it->second->AddRequest(std::move(pending_request->second)); - - pending_requests_.erase(pending_request); -} - -void ContentSettingPermissionContextBase::CleanUpRequest( - content::WebContents* web_contents, - const PermissionRequestID& id, - bool embedded_permission_element_initiated) { - if (!IsGroupedPermissionType(content_settings_type())) { - ContentSettingPermissionContextBase_ChromiumImpl::CleanUpRequest( - web_contents, id, embedded_permission_element_initiated); - return; - } - - // A sub-request is done, increase finish count. If all sub-requests are - // done, remove all sub-requests. - auto requests = pending_grouped_requests_.find(id.ToString()); - DCHECK(requests != pending_grouped_requests_.end()); - requests->second->RequestFinished(); - if (requests->second->IsDone()) { - pending_grouped_requests_.erase(id.ToString()); - } -} - -ContentSettingPermissionContextBase::GroupedPermissionRequests:: - GroupedPermissionRequests() = default; -ContentSettingPermissionContextBase::GroupedPermissionRequests:: - ~GroupedPermissionRequests() = default; - -bool ContentSettingPermissionContextBase::GroupedPermissionRequests::IsDone() - const { - return finished_request_count_ == requests_.size(); -} - -void ContentSettingPermissionContextBase::GroupedPermissionRequests::AddRequest( - std::pair, BrowserPermissionCallback> - request) { - requests_.push_back(std::move(request)); -} - -BrowserPermissionCallback ContentSettingPermissionContextBase:: - GroupedPermissionRequests::GetNextCallback() { - DCHECK(!IsDone()); - DCHECK(next_callback_index_ < requests_.size()); - return std::move(requests_[next_callback_index_++].second); -} - -void ContentSettingPermissionContextBase::GroupedPermissionRequests:: - RequestFinished() { - finished_request_count_++; -} - -bool ContentSettingPermissionContextBase:: - IsPendingGroupedRequestsEmptyForTesting() { - return pending_grouped_requests_.empty(); -} - -} // namespace permissions diff --git a/chromium_src/components/permissions/content_setting_permission_context_base.h b/chromium_src/components/permissions/content_setting_permission_context_base.h deleted file mode 100644 index 85916234ff4..00000000000 --- a/chromium_src/components/permissions/content_setting_permission_context_base.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2021 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. */ - -#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_H_ -#define BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_H_ - -#include "base/functional/callback.h" -#include "components/permissions/permission_context_base.h" - -namespace permissions { -class ContentSettingPermissionContextBase; -using ContentSettingPermissionContextBase_BraveImpl = - ContentSettingPermissionContextBase; -class PermissionLifetimeManager; -} // namespace permissions - -#define ContentSettingPermissionContextBase \ - ContentSettingPermissionContextBase_ChromiumImpl -#define BRAVE_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_ \ - friend ContentSettingPermissionContextBase_BraveImpl; -#include // IWYU pragma: export - -#undef BRAVE_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_ -#undef ContentSettingPermissionContextBase - -#include - -namespace permissions { - -class ContentSettingPermissionContextBase - : public ContentSettingPermissionContextBase_ChromiumImpl { - public: - ContentSettingPermissionContextBase( - content::BrowserContext* browser_context, - ContentSettingsType content_settings_type, - network::mojom::PermissionsPolicyFeature permissions_policy_feature); - - ~ContentSettingPermissionContextBase() override; - - void SetPermissionLifetimeManagerFactory( - const base::RepeatingCallback< - PermissionLifetimeManager*(content::BrowserContext*)>& factory); - - void DecidePermission( - std::unique_ptr request_data, - BrowserPermissionCallback callback) override; - - bool IsPendingGroupedRequestsEmptyForTesting(); - - private: - /** - * This class is map to one PermissionManager::RequestPermissions request, - * sub-requests will be kept in requests_. - * Chromium does not expect multiple sub-requests for a same permission type, - * this class is created to support tracking multiple sub-requests - * for each RequestPermissions request. It will clear all pending - * sub-requests for one RequestPermissions request after all of its - * sub-requests are finished. - */ - class GroupedPermissionRequests { - public: - GroupedPermissionRequests(); - ~GroupedPermissionRequests(); - - using GroupedRequests = std::vector< - std::pair, BrowserPermissionCallback>>; - - bool IsDone() const; - void AddRequest(std::pair, - BrowserPermissionCallback> request); - BrowserPermissionCallback GetNextCallback(); - void RequestFinished(); - - const GroupedRequests& Requests() const { return requests_; } - - private: - GroupedRequests requests_; - size_t finished_request_count_ = 0; - size_t next_callback_index_ = 0; - }; - - void PermissionDecided(PermissionDecision decision, - bool is_final_decision, - const PermissionRequestData& request_data) override; - void CleanUpRequest(content::WebContents* web_contents, - const PermissionRequestID& id, - bool embedded_permission_element_initiated) override; - - base::RepeatingCallback - permission_lifetime_manager_factory_; - - std::map> - pending_grouped_requests_; -}; - -} // namespace permissions - -#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_H_ diff --git a/chromium_src/components/permissions/permission_context_base.cc b/chromium_src/components/permissions/permission_context_base.cc index ba8ea1fc50a..8a0ba57e07d 100644 --- a/chromium_src/components/permissions/permission_context_base.cc +++ b/chromium_src/components/permissions/permission_context_base.cc @@ -5,11 +5,188 @@ #include "components/permissions/permission_context_base.h" +#include "base/check.h" +#include "brave/components/permissions/permission_lifetime_manager.h" #include "components/permissions/permissions_client.h" #define CanBypassEmbeddingOriginCheck(REQUESTING_ORIGIN, EMBEDDING_ORIGIN) \ BraveCanBypassEmbeddingOriginCheck(REQUESTING_ORIGIN, EMBEDDING_ORIGIN, \ content_settings_type_) - +#define PermissionContextBase PermissionContextBase_ChromiumImpl #include #undef CanBypassEmbeddingOriginCheck +#undef PermissionContextBase + +namespace { + +bool IsGroupedPermissionType(ContentSettingsType type) { + return type == ContentSettingsType::BRAVE_ETHEREUM || + type == ContentSettingsType::BRAVE_SOLANA || + type == ContentSettingsType::BRAVE_CARDANO; +} + +} // namespace + +namespace permissions { + +PermissionContextBase::PermissionContextBase( + content::BrowserContext* browser_context, + ContentSettingsType content_settings_type, + network::mojom::PermissionsPolicyFeature permissions_policy_feature) + : PermissionContextBase_ChromiumImpl(browser_context, + content_settings_type, + permissions_policy_feature) {} + +PermissionContextBase::~PermissionContextBase() = default; + +void PermissionContextBase::SetPermissionLifetimeManagerFactory( + const base::RepeatingCallback< + PermissionLifetimeManager*(content::BrowserContext*)>& factory) { + permission_lifetime_manager_factory_ = factory; +} + +void PermissionContextBase::PermissionDecided( + PermissionDecision decision, + bool is_final_decision, + const PermissionRequestData& request_data) { + if (permission_lifetime_manager_factory_) { + const auto request_it = pending_requests_.find(request_data.id.ToString()); + if (request_it != pending_requests_.end()) { + const PermissionRequest* permission_request = + request_it->second.first.get(); + DCHECK(permission_request); + if (auto* permission_lifetime_manager = + permission_lifetime_manager_factory_.Run(browser_context_)) { + permission_lifetime_manager->PermissionDecided( + *permission_request, request_data.requesting_origin, + request_data.embedding_origin, decision); + } + } + const auto group_request_it = + pending_grouped_requests_.find(request_data.id.ToString()); + if (group_request_it != pending_grouped_requests_.end()) { + for (const auto& request : group_request_it->second->Requests()) { + const PermissionRequest* permission_request = request.first.get(); + DCHECK(permission_request); + if (auto* permission_lifetime_manager = + permission_lifetime_manager_factory_.Run(browser_context_)) { + permission_lifetime_manager->PermissionDecided( + *permission_request, request_data.requesting_origin, + request_data.embedding_origin, decision); + } + } + } + } + + if (!IsGroupedPermissionType(content_settings_type())) { + PermissionContextBase_ChromiumImpl::PermissionDecided( + decision, is_final_decision, request_data); + return; + } + + DCHECK(decision == PermissionDecision::kAllow || + decision == PermissionDecision::kDeny || + decision == PermissionDecision::kNone); + UserMadePermissionDecision(request_data.id, request_data.requesting_origin, + request_data.embedding_origin, decision); + + bool persist = (decision == PermissionDecision::kAllow || + decision == PermissionDecision::kDeny); + + auto grouped_request = + pending_grouped_requests_.find(request_data.id.ToString()); + DCHECK(grouped_request != pending_grouped_requests_.end()); + DCHECK(grouped_request->second); + + if (grouped_request->second->IsDone()) { + return; + } + + auto callback = grouped_request->second->GetNextCallback(); + if (callback) { + NotifyPermissionSet(request_data, std::move(callback), persist, decision, + is_final_decision); + } +} + +void PermissionContextBase::DecidePermission( + std::unique_ptr request_data, + BrowserPermissionCallback callback) { + auto id = request_data->id; + PermissionContextBase_ChromiumImpl::DecidePermission(std::move(request_data), + std::move(callback)); + + if (!IsGroupedPermissionType(content_settings_type())) { + return; + } + + // Move added pending request from pending_requests_ to + // pending_grouped_requests_, because otherwise Chromium will replace this + // pending_request with next sub-request because it does not expect multiple + // sub-requests in the same type for one RequestPermissions request. + auto pending_request = pending_requests_.find(id.ToString()); + DCHECK(pending_request != pending_requests_.end()); + + auto it = pending_grouped_requests_.find(id.ToString()); + if (it == pending_grouped_requests_.end()) { + it = pending_grouped_requests_ + .insert(std::make_pair( + id.ToString(), std::make_unique())) + .first; + } + it->second->AddRequest(std::move(pending_request->second)); + + pending_requests_.erase(pending_request); +} + +void PermissionContextBase::CleanUpRequest( + content::WebContents* web_contents, + const PermissionRequestID& id, + bool embedded_permission_element_initiated) { + if (!IsGroupedPermissionType(content_settings_type())) { + PermissionContextBase_ChromiumImpl::CleanUpRequest( + web_contents, id, embedded_permission_element_initiated); + return; + } + + // A sub-request is done, increase finish count. If all sub-requests are + // done, remove all sub-requests. + auto requests = pending_grouped_requests_.find(id.ToString()); + DCHECK(requests != pending_grouped_requests_.end()); + requests->second->RequestFinished(); + if (requests->second->IsDone()) { + pending_grouped_requests_.erase(id.ToString()); + } +} + +PermissionContextBase::GroupedPermissionRequests::GroupedPermissionRequests() = + default; +PermissionContextBase::GroupedPermissionRequests::~GroupedPermissionRequests() = + default; + +bool PermissionContextBase::GroupedPermissionRequests::IsDone() const { + return finished_request_count_ == requests_.size(); +} + +void PermissionContextBase::GroupedPermissionRequests::AddRequest( + std::pair, BrowserPermissionCallback> + request) { + requests_.push_back(std::move(request)); +} + +BrowserPermissionCallback +PermissionContextBase::GroupedPermissionRequests::GetNextCallback() { + DCHECK(!IsDone()); + DCHECK(next_callback_index_ < requests_.size()); + return std::move(requests_[next_callback_index_++].second); +} + +void PermissionContextBase::GroupedPermissionRequests::RequestFinished() { + finished_request_count_++; +} + +bool PermissionContextBase::IsPendingGroupedRequestsEmptyForTesting() { + return pending_grouped_requests_.empty(); +} + +} // namespace permissions diff --git a/chromium_src/components/permissions/permission_context_base.h b/chromium_src/components/permissions/permission_context_base.h index 2b70e0b0071..9e9b1c3c92f 100644 --- a/chromium_src/components/permissions/permission_context_base.h +++ b/chromium_src/components/permissions/permission_context_base.h @@ -6,21 +6,98 @@ #ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_PERMISSION_CONTEXT_BASE_H_ #define BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_PERMISSION_CONTEXT_BASE_H_ +#include + +#include "components/permissions/permission_request_data.h" + namespace permissions { -class ContentSettingPermissionContextBase; +class PermissionContextBase; +using PermissionContextBase_BraveImpl = PermissionContextBase; +class PermissionLifetimeManager; } // namespace permissions #define PermissionContextBaseTests \ PermissionContextBaseTests; \ - friend ContentSettingPermissionContextBase + friend PermissionContextBase_BraveImpl +#define PermissionContextBase PermissionContextBase_ChromiumImpl #define PermissionDecided virtual PermissionDecided #define CleanUpRequest virtual CleanUpRequest #include // IWYU pragma: export #undef PermissionContextBaseTests +#undef PermissionContextBase #undef PermissionDecided #undef CleanUpRequest +namespace permissions { + +class PermissionContextBase : public PermissionContextBase_ChromiumImpl { + public: + PermissionContextBase( + content::BrowserContext* browser_context, + ContentSettingsType content_settings_type, + network::mojom::PermissionsPolicyFeature permissions_policy_feature); + + ~PermissionContextBase() override; + + void SetPermissionLifetimeManagerFactory( + const base::RepeatingCallback< + PermissionLifetimeManager*(content::BrowserContext*)>& factory); + + void DecidePermission( + std::unique_ptr request_data, + BrowserPermissionCallback callback) override; + + bool IsPendingGroupedRequestsEmptyForTesting(); + + private: + /** + * This class is map to one PermissionManager::RequestPermissions request, + * sub-requests will be kept in requests_. + * Chromium does not expect multiple sub-requests for a same permission type, + * this class is created to support tracking multiple sub-requests + * for each RequestPermissions request. It will clear all pending + * sub-requests for one RequestPermissions request after all of its + * sub-requests are finished. + */ + class GroupedPermissionRequests { + public: + GroupedPermissionRequests(); + ~GroupedPermissionRequests(); + + using GroupedRequests = std::vector< + std::pair, BrowserPermissionCallback>>; + + bool IsDone() const; + void AddRequest(std::pair, + BrowserPermissionCallback> request); + BrowserPermissionCallback GetNextCallback(); + void RequestFinished(); + + const GroupedRequests& Requests() const { return requests_; } + + private: + GroupedRequests requests_; + size_t finished_request_count_ = 0; + size_t next_callback_index_ = 0; + }; + + void PermissionDecided(PermissionDecision decision, + bool is_final_decision, + const PermissionRequestData& request_data) override; + void CleanUpRequest(content::WebContents* web_contents, + const PermissionRequestID& id, + bool embedded_permission_element_initiated) override; + + base::RepeatingCallback + permission_lifetime_manager_factory_; + + std::map> + pending_grouped_requests_; +}; + +} // namespace permissions + #endif // BRAVE_CHROMIUM_SRC_COMPONENTS_PERMISSIONS_PERMISSION_CONTEXT_BASE_H_ diff --git a/patches/components-permissions-content_setting_permission_context_base.h.patch b/patches/components-permissions-content_setting_permission_context_base.h.patch deleted file mode 100644 index 82dff85afcf..00000000000 --- a/patches/components-permissions-content_setting_permission_context_base.h.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/components/permissions/content_setting_permission_context_base.h b/components/permissions/content_setting_permission_context_base.h -index 30bb4bcc559864fd253ab77c11808e3a6ba65fa5..ba3c24fec8e13bcc35541fc9511c310e9df72ce3 100644 ---- a/components/permissions/content_setting_permission_context_base.h -+++ b/components/permissions/content_setting_permission_context_base.h -@@ -26,6 +26,7 @@ class ContentSettingPermissionContextBase : public PermissionContextBase { - void ResetPermission(const GURL& requesting_origin, - const GURL& embedding_origin) override; - -+ BRAVE_CONTENT_SETTING_PERMISSION_CONTEXT_BASE_ - protected: - // Store the decided permission state. Virtual since the permission might be - // stored with different restrictions (for example for desktop notifications).