diff --git a/components/cast_receiver/renderer/content_renderer_client_mixins_impl.cc b/components/cast_receiver/renderer/content_renderer_client_mixins_impl.cc index 3ca9c4a106fc1..0f05752e6e188 100644 --- a/components/cast_receiver/renderer/content_renderer_client_mixins_impl.cc +++ b/components/cast_receiver/renderer/content_renderer_client_mixins_impl.cc @@ -39,12 +39,13 @@ void ContentRendererClientMixinsImpl::RenderFrameCreated( new media_control::MediaPlaybackOptions(&render_frame); // Create the new UrlRewriteRulesProvider. + auto provider = std::make_unique( + &render_frame, + base::BindOnce(&ContentRendererClientMixinsImpl::OnRenderFrameRemoved, + weak_factory_.GetWeakPtr())); + base::AutoLock lock(providers_lock_); url_rewrite_rules_providers_.emplace( - render_frame.GetWebFrame()->GetLocalFrameToken(), - std::make_unique( - &render_frame, - base::BindOnce(&ContentRendererClientMixinsImpl::OnRenderFrameRemoved, - weak_factory_.GetWeakPtr()))); + render_frame.GetWebFrame()->GetLocalFrameToken(), std::move(provider)); } bool ContentRendererClientMixinsImpl::DeferMediaLoad( @@ -79,6 +80,7 @@ ContentRendererClientMixinsImpl::ExtendURLLoaderThrottleProvider( void ContentRendererClientMixinsImpl::OnRenderFrameRemoved( const blink::LocalFrameToken& frame_token) { + base::AutoLock lock(providers_lock_); size_t result = url_rewrite_rules_providers_.erase(frame_token); if (result != 1U) { LOG(WARNING) @@ -87,13 +89,17 @@ void ContentRendererClientMixinsImpl::OnRenderFrameRemoved( } } -UrlRewriteRulesProvider* -ContentRendererClientMixinsImpl::GetUrlRewriteRulesProvider( +scoped_refptr +ContentRendererClientMixinsImpl::GetRewriteRulesForFrame( const blink::LocalFrameToken& frame_token) { + base::AutoLock lock(providers_lock_); auto rules_it = url_rewrite_rules_providers_.find(frame_token); - return rules_it == url_rewrite_rules_providers_.end() - ? nullptr - : rules_it->second.get(); + if (rules_it == url_rewrite_rules_providers_.end()) { + return nullptr; + } + // GetCachedRules() takes its own internal lock and returns a scoped_refptr, + // so it is safe to drop providers_lock_ after this returns. + return rules_it->second->GetCachedRules(); } bool ContentRendererClientMixinsImpl::IsCorsExemptHeader( diff --git a/components/cast_receiver/renderer/content_renderer_client_mixins_impl.h b/components/cast_receiver/renderer/content_renderer_client_mixins_impl.h index 6e2be978eaf3d..a69ad5d7c28a1 100644 --- a/components/cast_receiver/renderer/content_renderer_client_mixins_impl.h +++ b/components/cast_receiver/renderer/content_renderer_client_mixins_impl.h @@ -11,6 +11,8 @@ #include "base/containers/flat_map.h" #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" +#include "base/thread_annotations.h" #include "components/cast_receiver/renderer/public/content_renderer_client_mixins.h" #include "components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.h" @@ -62,15 +64,20 @@ class ContentRendererClientMixinsImpl void OnRenderFrameRemoved(const blink::LocalFrameToken& frame_token); // WrappingURLLoaderThrottleProvider::Client implementation. - UrlRewriteRulesProvider* GetUrlRewriteRulesProvider( + scoped_refptr GetRewriteRulesForFrame( const blink::LocalFrameToken& frame_token) override; bool IsCorsExemptHeader(std::string_view header) override; IsCorsExemptHeadersCallback is_cors_exempt_header_callback_; + // GetRewriteRulesForFrame() is called from worker / background-fetch + // threads via WrappingURLLoaderThrottleProvider::CreateThrottles(), while + // RenderFrameCreated()/OnRenderFrameRemoved() mutate the map on the render + // main thread, so the container must be guarded by a lock. + mutable base::Lock providers_lock_; base::flat_map> - url_rewrite_rules_providers_; + url_rewrite_rules_providers_ GUARDED_BY(providers_lock_); base::WeakPtrFactory weak_factory_{this}; }; diff --git a/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.cc b/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.cc index ed03f1b95ca1b..4804c2002e099 100644 --- a/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.cc +++ b/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.cc @@ -54,17 +54,13 @@ WrappingURLLoaderThrottleProvider::CreateThrottles( if (!local_frame_token.has_value()) { return throttles; } - auto* provider = - client_->GetUrlRewriteRulesProvider(local_frame_token.value()); - if (provider) { - auto rules = provider->GetCachedRules(); - if (rules) { - throttles.emplace_back(std::make_unique( - rules, - base::BindRepeating( - &WrappingURLLoaderThrottleProvider::Client::IsCorsExemptHeader, - base::Unretained(client_)))); - } + auto rules = client_->GetRewriteRulesForFrame(local_frame_token.value()); + if (rules) { + throttles.emplace_back(std::make_unique( + rules, + base::BindRepeating( + &WrappingURLLoaderThrottleProvider::Client::IsCorsExemptHeader, + base::Unretained(client_)))); } return throttles; diff --git a/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.h b/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.h index f2499f34687f0..d8501079ebfa5 100644 --- a/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.h +++ b/components/cast_receiver/renderer/wrapping_url_loader_throttle_provider.h @@ -13,6 +13,7 @@ #include "base/functional/callback_forward.h" #include "base/memory/raw_ref.h" #include "base/sequence_checker.h" +#include "components/url_rewrite/common/url_request_rewrite_rules.h" #include "third_party/blink/public/platform/url_loader_throttle_provider.h" namespace network { @@ -31,10 +32,11 @@ class WrappingURLLoaderThrottleProvider public: virtual ~Client(); - // Returns the UrlRewriteRulesProvider associated with RenderFrame with id - // `frame_token`, or nullptr if no such provider exists. - virtual UrlRewriteRulesProvider* GetUrlRewriteRulesProvider( - const blink::LocalFrameToken& frame_token) = 0; + // Returns the URL rewrite rules associated with RenderFrame with id + // `frame_token`, or nullptr if no such provider exists. May be called + // from any thread. + virtual scoped_refptr + GetRewriteRulesForFrame(const blink::LocalFrameToken& frame_token) = 0; // Returns whether |header| is a cors exempt header. virtual bool IsCorsExemptHeader(std::string_view header) = 0;