1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/renderer/renderer_blink_platform_impl.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/files/file_path.h"
16 #include "base/guid.h"
17 #include "base/lazy_instance.h"
18 #include "base/location.h"
19 #include "base/logging.h"
20 #include "base/metrics/histogram_macros.h"
21 #include "base/numerics/safe_conversions.h"
22 #include "base/single_thread_task_runner.h"
23 #include "base/strings/pattern.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/sys_string_conversions.h"
26 #include "base/strings/utf_string_conversions.h"
27 #include "base/task/post_task.h"
28 #include "base/task/thread_pool.h"
29 #include "base/threading/thread_task_runner_handle.h"
30 #include "base/time/time.h"
31 #include "build/build_config.h"
32 #include "components/url_formatter/url_formatter.h"
33 #include "content/child/child_process.h"
34 #include "content/common/android/sync_compositor_statics.h"
35 #include "content/common/content_constants_internal.h"
36 #include "content/common/frame_messages.h"
37 #include "content/public/common/content_features.h"
38 #include "content/public/common/content_switches.h"
39 #include "content/public/common/gpu_stream_constants.h"
40 #include "content/public/common/service_names.mojom.h"
41 #include "content/public/common/webplugininfo.h"
42 #include "content/public/renderer/content_renderer_client.h"
43 #include "content/public/renderer/render_frame.h"
44 #include "content/renderer/loader/resource_dispatcher.h"
45 #include "content/renderer/loader/web_url_loader_impl.h"
46 #include "content/renderer/media/audio_decoder.h"
47 #include "content/renderer/media/batching_media_log.h"
48 #include "content/renderer/media/inspector_media_event_handler.h"
49 #include "content/renderer/media/render_media_event_handler.h"
50 #include "content/renderer/media/renderer_webaudiodevice_impl.h"
51 #include "content/renderer/render_frame_impl.h"
52 #include "content/renderer/render_thread_impl.h"
53 #include "content/renderer/storage_util.h"
54 #include "content/renderer/webgraphicscontext3d_provider_impl.h"
55 #include "content/renderer/worker/dedicated_worker_host_factory_client.h"
56 #include "content/renderer/worker/worker_thread_registry.h"
57 #include "device/gamepad/public/cpp/gamepads.h"
58 #include "gpu/command_buffer/client/gles2_interface.h"
59 #include "gpu/config/gpu_info.h"
60 #include "gpu/ipc/client/gpu_channel_host.h"
61 #include "media/audio/audio_output_device.h"
62 #include "media/base/media_permission.h"
63 #include "media/base/media_switches.h"
64 #include "media/blink/webcontentdecryptionmodule_impl.h"
65 #include "media/filters/stream_parser_factory.h"
66 #include "media/video/gpu_video_accelerator_factories.h"
67 #include "media/webrtc/webrtc_switches.h"
68 #include "mojo/public/cpp/base/big_buffer.h"
69 #include "mojo/public/cpp/system/platform_handle.h"
70 #include "ppapi/buildflags/buildflags.h"
71 #include "services/network/public/cpp/features.h"
72 #include "services/network/public/cpp/shared_url_loader_factory.h"
73 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
74 #include "services/service_manager/public/cpp/interface_provider.h"
75 #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
76 #include "storage/common/database/database_identifier.h"
77 #include "third_party/blink/public/common/features.h"
78 #include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
79 #include "third_party/blink/public/common/security/protocol_handler_security_level.h"
80 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
81 #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
82 #include "third_party/blink/public/platform/blame_context.h"
83 #include "third_party/blink/public/platform/file_path_conversion.h"
84 #include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
85 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
86 #include "third_party/blink/public/platform/url_conversion.h"
87 #include "third_party/blink/public/platform/web_audio_latency_hint.h"
88 #include "third_party/blink/public/platform/web_code_cache_loader.h"
89 #include "third_party/blink/public/platform/web_security_origin.h"
90 #include "third_party/blink/public/platform/web_theme_engine.h"
91 #include "third_party/blink/public/platform/web_url.h"
92 #include "third_party/blink/public/platform/web_url_loader_factory.h"
93 #include "third_party/blink/public/platform/web_url_request.h"
94 #include "third_party/blink/public/platform/web_vector.h"
95 #include "third_party/blink/public/web/modules/media/audio/web_audio_device_factory.h"
96 #include "third_party/blink/public/web/web_local_frame.h"
97 #include "third_party/blink/public/web/web_media_inspector.h"
98 #include "third_party/sqlite/sqlite3.h"
99 #include "ui/base/ui_base_switches.h"
100 #include "ui/gl/buildflags.h"
101 #include "url/gurl.h"
102 
103 #if defined(OS_MAC)
104 #include "content/child/child_process_sandbox_support_impl_mac.h"
105 #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
106 #include "content/child/child_process_sandbox_support_impl_linux.h"
107 #endif
108 
109 #if defined(OS_POSIX)
110 #include "base/file_descriptor_posix.h"
111 #endif
112 
113 #if defined(OS_WIN)
114 #include "base/win/windows_version.h"
115 #endif
116 
117 using blink::Platform;
118 using blink::WebAudioDevice;
119 using blink::WebAudioLatencyHint;
120 using blink::WebMediaStreamTrack;
121 using blink::WebSize;
122 using blink::WebString;
123 using blink::WebURL;
124 using blink::WebVector;
125 
126 namespace content {
127 
128 namespace {
129 
130 // TODO(https://crbug.com/787252): Move this method and its callers to Blink.
GetAudioHardwareParams()131 media::AudioParameters GetAudioHardwareParams() {
132   blink::WebLocalFrame* const web_frame =
133       blink::WebLocalFrame::FrameForCurrentContext();
134   RenderFrame* const render_frame = RenderFrame::FromWebFrame(web_frame);
135   if (!render_frame)
136     return media::AudioParameters::UnavailableDeviceParams();
137 
138   return blink::WebAudioDeviceFactory::GetOutputDeviceInfo(
139              render_frame->GetWebFrame()->GetLocalFrameToken(),
140              media::AudioSinkParameters())
141       .output_params();
142 }
143 
ToGpuContextType(blink::Platform::ContextType type)144 gpu::ContextType ToGpuContextType(blink::Platform::ContextType type) {
145   switch (type) {
146     case blink::Platform::kWebGL1ContextType:
147       return gpu::CONTEXT_TYPE_WEBGL1;
148     case blink::Platform::kWebGL2ContextType:
149       return gpu::CONTEXT_TYPE_WEBGL2;
150     case blink::Platform::kGLES2ContextType:
151       return gpu::CONTEXT_TYPE_OPENGLES2;
152     case blink::Platform::kGLES3ContextType:
153       return gpu::CONTEXT_TYPE_OPENGLES3;
154     case blink::Platform::kWebGPUContextType:
155       return gpu::CONTEXT_TYPE_WEBGPU;
156   }
157   NOTREACHED();
158   return gpu::CONTEXT_TYPE_OPENGLES2;
159 }
160 
161 }  // namespace
162 
163 //------------------------------------------------------------------------------
164 
RendererBlinkPlatformImpl(blink::scheduler::WebThreadScheduler * main_thread_scheduler)165 RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
166     blink::scheduler::WebThreadScheduler* main_thread_scheduler)
167     : BlinkPlatformImpl(RenderThreadImpl::current()
168                             ? RenderThreadImpl::current()->GetIOTaskRunner()
169                             : nullptr),
170       sudden_termination_disables_(0),
171       is_locked_to_site_(false),
172       main_thread_scheduler_(main_thread_scheduler) {
173   // RenderThread may not exist in some tests.
174   if (RenderThreadImpl::current()) {
175 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
176     mojo::PendingRemote<font_service::mojom::FontService> font_service;
177     RenderThreadImpl::current()->BindHostReceiver(
178         font_service.InitWithNewPipeAndPassReceiver());
179     font_loader_ =
180         sk_make_sp<font_service::FontLoader>(std::move(font_service));
181     SkFontConfigInterface::SetGlobal(font_loader_);
182 #endif
183   }
184 
185 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
186   if (sandboxEnabled()) {
187 #if defined(OS_MAC)
188     sandbox_support_ = std::make_unique<WebSandboxSupportMac>();
189 #else
190     sandbox_support_.reset(new WebSandboxSupportLinux(font_loader_));
191 #endif
192   } else {
193     DVLOG(1) << "Disabling sandbox support for testing.";
194   }
195 #endif
196 
197   top_level_blame_context_.Initialize();
198   main_thread_scheduler_->SetTopLevelBlameContext(&top_level_blame_context_);
199 
200   GetBrowserInterfaceBroker()->GetInterface(
201       code_cache_host_remote_.InitWithNewPipeAndPassReceiver());
202 }
203 
~RendererBlinkPlatformImpl()204 RendererBlinkPlatformImpl::~RendererBlinkPlatformImpl() {
205   main_thread_scheduler_->SetTopLevelBlameContext(nullptr);
206 }
207 
Shutdown()208 void RendererBlinkPlatformImpl::Shutdown() {}
209 
210 //------------------------------------------------------------------------------
211 
212 std::unique_ptr<blink::WebCodeCacheLoader>
CreateCodeCacheLoader()213 RendererBlinkPlatformImpl::CreateCodeCacheLoader() {
214   return blink::WebCodeCacheLoader::Create();
215 }
216 
217 std::unique_ptr<blink::WebURLLoaderFactory>
WrapURLLoaderFactory(blink::CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase> url_loader_factory)218 RendererBlinkPlatformImpl::WrapURLLoaderFactory(
219     blink::CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase>
220         url_loader_factory) {
221   return std::make_unique<WebURLLoaderFactoryImpl>(
222       RenderThreadImpl::current()->resource_dispatcher()->GetWeakPtr(),
223       base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
224           mojo::PendingRemote<network::mojom::URLLoaderFactory>(
225               std::move(url_loader_factory))));
226 }
227 
228 std::unique_ptr<blink::WebURLLoaderFactory>
WrapSharedURLLoaderFactory(scoped_refptr<network::SharedURLLoaderFactory> factory)229 RendererBlinkPlatformImpl::WrapSharedURLLoaderFactory(
230     scoped_refptr<network::SharedURLLoaderFactory> factory) {
231   return std::make_unique<WebURLLoaderFactoryImpl>(
232       RenderThreadImpl::current()->resource_dispatcher()->GetWeakPtr(),
233       std::move(factory));
234 }
235 
SetDisplayThreadPriority(base::PlatformThreadId thread_id)236 void RendererBlinkPlatformImpl::SetDisplayThreadPriority(
237     base::PlatformThreadId thread_id) {
238 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
239   if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
240     render_thread->render_message_filter()->SetThreadPriority(
241         thread_id, base::ThreadPriority::DISPLAY);
242   }
243 #endif
244 }
245 
GetTopLevelBlameContext()246 blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() {
247   return &top_level_blame_context_;
248 }
249 
GetSandboxSupport()250 blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
251 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
252   return sandbox_support_.get();
253 #else
254   // These platforms do not require sandbox support.
255   return nullptr;
256 #endif
257 }
258 
ThemeEngine()259 blink::WebThemeEngine* RendererBlinkPlatformImpl::ThemeEngine() {
260   blink::WebThemeEngine* theme_engine =
261       GetContentClient()->renderer()->OverrideThemeEngine();
262   if (!theme_engine)
263     theme_engine = BlinkPlatformImpl::ThemeEngine();
264   return theme_engine;
265 }
266 
sandboxEnabled()267 bool RendererBlinkPlatformImpl::sandboxEnabled() {
268   // As explained in Platform.h, this function is used to decide
269   // whether to allow file system operations to come out of WebKit or not.
270   // Even if the sandbox is disabled, there's no reason why the code should
271   // act any differently...unless we're in single process mode.  In which
272   // case, we have no other choice.  Platform.h discourages using
273   // this switch unless absolutely necessary, so hopefully we won't end up
274   // with too many code paths being different in single-process mode.
275   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
276       switches::kSingleProcess);
277 }
278 
VisitedLinkHash(const char * canonical_url,size_t length)279 uint64_t RendererBlinkPlatformImpl::VisitedLinkHash(const char* canonical_url,
280                                                     size_t length) {
281   return GetContentClient()->renderer()->VisitedLinkHash(canonical_url, length);
282 }
283 
IsLinkVisited(uint64_t link_hash)284 bool RendererBlinkPlatformImpl::IsLinkVisited(uint64_t link_hash) {
285   return GetContentClient()->renderer()->IsLinkVisited(link_hash);
286 }
287 
UserAgent()288 blink::WebString RendererBlinkPlatformImpl::UserAgent() {
289   auto* render_thread = RenderThreadImpl::current();
290   // RenderThreadImpl is null in some tests.
291   if (!render_thread)
292     return WebString();
293   return render_thread->GetUserAgent();
294 }
295 
UserAgentMetadata()296 blink::UserAgentMetadata RendererBlinkPlatformImpl::UserAgentMetadata() {
297   auto* render_thread = RenderThreadImpl::current();
298   // RenderThreadImpl is null in some tests.
299   if (!render_thread)
300     return blink::UserAgentMetadata();
301   return render_thread->GetUserAgentMetadata();
302 }
303 
CacheMetadata(blink::mojom::CodeCacheType cache_type,const blink::WebURL & url,base::Time response_time,const uint8_t * data,size_t size)304 void RendererBlinkPlatformImpl::CacheMetadata(
305     blink::mojom::CodeCacheType cache_type,
306     const blink::WebURL& url,
307     base::Time response_time,
308     const uint8_t* data,
309     size_t size) {
310   // Let the browser know we generated cacheable metadata for this resource.
311   // The browser may cache it and return it on subsequent responses to speed
312   // the processing of this resource.
313   GetCodeCacheHost().DidGenerateCacheableMetadata(
314       cache_type, url, response_time,
315       mojo_base::BigBuffer(base::make_span(data, size)));
316 }
317 
FetchCachedCode(blink::mojom::CodeCacheType cache_type,const blink::WebURL & url,FetchCachedCodeCallback callback)318 void RendererBlinkPlatformImpl::FetchCachedCode(
319     blink::mojom::CodeCacheType cache_type,
320     const blink::WebURL& url,
321     FetchCachedCodeCallback callback) {
322   GetCodeCacheHost().FetchCachedCode(
323       cache_type, url,
324       base::BindOnce(
325           [](FetchCachedCodeCallback callback, base::Time time,
326              mojo_base::BigBuffer data) {
327             std::move(callback).Run(time, std::move(data));
328           },
329           std::move(callback)));
330 }
331 
ClearCodeCacheEntry(blink::mojom::CodeCacheType cache_type,const GURL & url)332 void RendererBlinkPlatformImpl::ClearCodeCacheEntry(
333     blink::mojom::CodeCacheType cache_type,
334     const GURL& url) {
335   GetCodeCacheHost().ClearCodeCacheEntry(cache_type, url);
336 }
337 
PopulateURLResponse(const WebURL & url,const network::mojom::URLResponseHead & head,blink::WebURLResponse * response,bool report_security_info,int request_id)338 void RendererBlinkPlatformImpl::PopulateURLResponse(
339     const WebURL& url,
340     const network::mojom::URLResponseHead& head,
341     blink::WebURLResponse* response,
342     bool report_security_info,
343     int request_id) {
344   WebURLLoaderImpl::PopulateURLResponse(url, head, response,
345                                         report_security_info, request_id);
346 }
347 
CacheMetadataInCacheStorage(const blink::WebURL & url,base::Time response_time,const uint8_t * data,size_t size,const blink::WebSecurityOrigin & cacheStorageOrigin,const blink::WebString & cacheStorageCacheName)348 void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage(
349     const blink::WebURL& url,
350     base::Time response_time,
351     const uint8_t* data,
352     size_t size,
353     const blink::WebSecurityOrigin& cacheStorageOrigin,
354     const blink::WebString& cacheStorageCacheName) {
355   // Let the browser know we generated cacheable metadata for this resource in
356   // CacheStorage. The browser may cache it and return it on subsequent
357   // responses to speed the processing of this resource.
358   GetCodeCacheHost().DidGenerateCacheableMetadataInCacheStorage(
359       url, response_time, mojo_base::BigBuffer(base::make_span(data, size)),
360       cacheStorageOrigin, cacheStorageCacheName.Utf8());
361 }
362 
DefaultLocale()363 WebString RendererBlinkPlatformImpl::DefaultLocale() {
364   return WebString::FromASCII(RenderThread::Get()->GetLocale());
365 }
366 
SuddenTerminationChanged(bool enabled)367 void RendererBlinkPlatformImpl::SuddenTerminationChanged(bool enabled) {
368   if (enabled) {
369     // We should not get more enables than disables, but we want it to be a
370     // non-fatal error if it does happen.
371     DCHECK_GT(sudden_termination_disables_, 0);
372     sudden_termination_disables_ =
373         std::max(sudden_termination_disables_ - 1, 0);
374     if (sudden_termination_disables_ != 0)
375       return;
376   } else {
377     sudden_termination_disables_++;
378     if (sudden_termination_disables_ != 1)
379       return;
380   }
381 
382   RenderThreadImpl* thread = RenderThreadImpl::current();
383   if (thread)  // NULL in unittests.
384     thread->GetRendererHost()->SuddenTerminationChanged(enabled);
385 }
386 
387 //------------------------------------------------------------------------------
388 
FileSystemCreateOriginIdentifier(const blink::WebSecurityOrigin & origin)389 WebString RendererBlinkPlatformImpl::FileSystemCreateOriginIdentifier(
390     const blink::WebSecurityOrigin& origin) {
391   return WebString::FromUTF8(
392       storage::GetIdentifierFromOrigin(WebSecurityOriginToGURL(origin)));
393 }
394 
395 //------------------------------------------------------------------------------
396 
DatabaseCreateOriginIdentifier(const blink::WebSecurityOrigin & origin)397 WebString RendererBlinkPlatformImpl::DatabaseCreateOriginIdentifier(
398     const blink::WebSecurityOrigin& origin) {
399   return WebString::FromUTF8(
400       storage::GetIdentifierFromOrigin(WebSecurityOriginToGURL(origin)));
401 }
402 
GenerateFrameSinkId()403 viz::FrameSinkId RendererBlinkPlatformImpl::GenerateFrameSinkId() {
404   return viz::FrameSinkId(RenderThread::Get()->GetClientId(),
405                           RenderThread::Get()->GenerateRoutingID());
406 }
407 
IsLockedToSite() const408 bool RendererBlinkPlatformImpl::IsLockedToSite() const {
409   return is_locked_to_site_;
410 }
411 
SetIsLockedToSite()412 void RendererBlinkPlatformImpl::SetIsLockedToSite() {
413   is_locked_to_site_ = true;
414 }
415 
IsGpuCompositingDisabled()416 bool RendererBlinkPlatformImpl::IsGpuCompositingDisabled() {
417   DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
418   RenderThreadImpl* thread = RenderThreadImpl::current();
419   // |thread| can be NULL in tests.
420   return !thread || thread->IsGpuCompositingDisabled();
421 }
422 
423 #if defined(OS_ANDROID)
424 bool RendererBlinkPlatformImpl::
IsSynchronousCompositingEnabledForAndroidWebView()425     IsSynchronousCompositingEnabledForAndroidWebView() {
426   return GetContentClient()->UsingSynchronousCompositing();
427 }
428 
429 bool RendererBlinkPlatformImpl::
IsZeroCopySynchronousSwDrawEnabledForAndroidWebView()430     IsZeroCopySynchronousSwDrawEnabledForAndroidWebView() {
431   return base::CommandLine::ForCurrentProcess()->HasSwitch(
432       switches::kSingleProcess);
433 }
434 
435 SkCanvas*
SynchronousCompositorGetSkCanvasForAndroidWebView()436 RendererBlinkPlatformImpl::SynchronousCompositorGetSkCanvasForAndroidWebView() {
437   return content::SynchronousCompositorGetSkCanvas();
438 }
439 #endif
440 
IsUseZoomForDSFEnabled()441 bool RendererBlinkPlatformImpl::IsUseZoomForDSFEnabled() {
442   RenderThread* thread = RenderThread::Get();
443   return thread ? thread->IsUseZoomForDSF() : true;
444 }
445 
IsLcdTextEnabled()446 bool RendererBlinkPlatformImpl::IsLcdTextEnabled() {
447   RenderThreadImpl* thread = RenderThreadImpl::current();
448   return thread ? thread->IsLcdTextEnabled() : false;
449 }
450 
IsElasticOverscrollEnabled()451 bool RendererBlinkPlatformImpl::IsElasticOverscrollEnabled() {
452   RenderThreadImpl* thread = RenderThreadImpl::current();
453   return thread ? thread->IsElasticOverscrollEnabled() : false;
454 }
455 
IsScrollAnimatorEnabled()456 bool RendererBlinkPlatformImpl::IsScrollAnimatorEnabled() {
457   RenderThreadImpl* thread = RenderThreadImpl::current();
458   return thread ? thread->IsScrollAnimatorEnabled() : false;
459 }
460 
IsThreadedAnimationEnabled()461 bool RendererBlinkPlatformImpl::IsThreadedAnimationEnabled() {
462   RenderThreadImpl* thread = RenderThreadImpl::current();
463   return thread ? thread->IsThreadedAnimationEnabled() : true;
464 }
465 
AudioHardwareSampleRate()466 double RendererBlinkPlatformImpl::AudioHardwareSampleRate() {
467   return GetAudioHardwareParams().sample_rate();
468 }
469 
AudioHardwareBufferSize()470 size_t RendererBlinkPlatformImpl::AudioHardwareBufferSize() {
471   return GetAudioHardwareParams().frames_per_buffer();
472 }
473 
AudioHardwareOutputChannels()474 unsigned RendererBlinkPlatformImpl::AudioHardwareOutputChannels() {
475   return GetAudioHardwareParams().channels();
476 }
477 
GetHungRendererDelay()478 base::TimeDelta RendererBlinkPlatformImpl::GetHungRendererDelay() {
479   return kHungRendererDelay;
480 }
481 
CreateAudioDevice(unsigned input_channels,unsigned channels,const blink::WebAudioLatencyHint & latency_hint,WebAudioDevice::RenderCallback * callback,const blink::WebString & input_device_id)482 std::unique_ptr<WebAudioDevice> RendererBlinkPlatformImpl::CreateAudioDevice(
483     unsigned input_channels,
484     unsigned channels,
485     const blink::WebAudioLatencyHint& latency_hint,
486     WebAudioDevice::RenderCallback* callback,
487     const blink::WebString& input_device_id) {
488   // The |channels| does not exactly identify the channel layout of the
489   // device. The switch statement below assigns a best guess to the channel
490   // layout based on number of channels.
491   media::ChannelLayout layout = media::GuessChannelLayout(channels);
492   if (layout == media::CHANNEL_LAYOUT_UNSUPPORTED)
493     layout = media::CHANNEL_LAYOUT_DISCRETE;
494 
495   return RendererWebAudioDeviceImpl::Create(
496       layout, channels, latency_hint, callback,
497       /*session_id=*/base::UnguessableToken());
498 }
499 
DecodeAudioFileData(blink::WebAudioBus * destination_bus,const char * audio_file_data,size_t data_size)500 bool RendererBlinkPlatformImpl::DecodeAudioFileData(
501     blink::WebAudioBus* destination_bus,
502     const char* audio_file_data,
503     size_t data_size) {
504   return content::DecodeAudioFileData(destination_bus, audio_file_data,
505                                       data_size);
506 }
507 
508 //------------------------------------------------------------------------------
509 
510 scoped_refptr<media::AudioCapturerSource>
NewAudioCapturerSource(blink::WebLocalFrame * web_frame,const media::AudioSourceParameters & params)511 RendererBlinkPlatformImpl::NewAudioCapturerSource(
512     blink::WebLocalFrame* web_frame,
513     const media::AudioSourceParameters& params) {
514   return blink::WebAudioDeviceFactory::NewAudioCapturerSource(
515       web_frame->GetLocalFrameToken(), params);
516 }
517 
518 scoped_refptr<viz::RasterContextProvider>
SharedMainThreadContextProvider()519 RendererBlinkPlatformImpl::SharedMainThreadContextProvider() {
520   return RenderThreadImpl::current()->SharedMainThreadContextProvider();
521 }
522 
523 scoped_refptr<viz::RasterContextProvider>
SharedCompositorWorkerContextProvider()524 RendererBlinkPlatformImpl::SharedCompositorWorkerContextProvider() {
525   return RenderThreadImpl::current()->SharedCompositorWorkerContextProvider(
526       /*try_gpu_rasterization=*/true);
527 }
528 
529 scoped_refptr<gpu::GpuChannelHost>
EstablishGpuChannelSync()530 RendererBlinkPlatformImpl::EstablishGpuChannelSync() {
531   return RenderThreadImpl::current()->EstablishGpuChannelSync();
532 }
533 
RTCSmoothnessAlgorithmEnabled()534 bool RendererBlinkPlatformImpl::RTCSmoothnessAlgorithmEnabled() {
535   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
536       switches::kDisableRTCSmoothnessAlgorithm);
537 }
538 
539 //------------------------------------------------------------------------------
540 
541 base::Optional<double>
GetWebRtcMaxCaptureFrameRate()542 RendererBlinkPlatformImpl::GetWebRtcMaxCaptureFrameRate() {
543   const std::string max_fps_str =
544       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
545           switches::kWebRtcMaxCaptureFramerate);
546   if (!max_fps_str.empty()) {
547     double value;
548     if (base::StringToDouble(max_fps_str, &value) && value >= 0.0)
549       return value;
550   }
551   return base::nullopt;
552 }
553 
554 scoped_refptr<media::AudioRendererSink>
NewAudioRendererSink(blink::WebAudioDeviceSourceType source_type,blink::WebLocalFrame * web_frame,const media::AudioSinkParameters & params)555 RendererBlinkPlatformImpl::NewAudioRendererSink(
556     blink::WebAudioDeviceSourceType source_type,
557     blink::WebLocalFrame* web_frame,
558     const media::AudioSinkParameters& params) {
559   return blink::WebAudioDeviceFactory::NewAudioRendererSink(
560       source_type, web_frame->GetLocalFrameToken(), params);
561 }
562 
563 media::AudioLatency::LatencyType
GetAudioSourceLatencyType(blink::WebAudioDeviceSourceType source_type)564 RendererBlinkPlatformImpl::GetAudioSourceLatencyType(
565     blink::WebAudioDeviceSourceType source_type) {
566   return blink::WebAudioDeviceFactory::GetSourceLatencyType(source_type);
567 }
568 
569 base::Optional<std::string>
GetWebRTCAudioProcessingConfiguration()570 RendererBlinkPlatformImpl::GetWebRTCAudioProcessingConfiguration() {
571   return GetContentClient()
572       ->renderer()
573       ->WebRTCPlatformSpecificAudioProcessingConfiguration();
574 }
575 
ShouldEnforceWebRTCRoutingPreferences()576 bool RendererBlinkPlatformImpl::ShouldEnforceWebRTCRoutingPreferences() {
577   return GetContentClient()
578       ->renderer()
579       ->ShouldEnforceWebRTCRoutingPreferences();
580 }
581 
UsesFakeCodecForPeerConnection()582 bool RendererBlinkPlatformImpl::UsesFakeCodecForPeerConnection() {
583   return base::CommandLine::ForCurrentProcess()->HasSwitch(
584       switches::kUseFakeCodecForPeerConnection);
585 }
586 
IsWebRtcEncryptionEnabled()587 bool RendererBlinkPlatformImpl::IsWebRtcEncryptionEnabled() {
588   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
589       switches::kDisableWebRtcEncryption);
590 }
591 
IsWebRtcStunOriginEnabled()592 bool RendererBlinkPlatformImpl::IsWebRtcStunOriginEnabled() {
593   return base::CommandLine::ForCurrentProcess()->HasSwitch(
594       switches::kEnableWebRtcStunOrigin);
595 }
596 
597 base::Optional<blink::WebString>
WebRtcStunProbeTrialParameter()598 RendererBlinkPlatformImpl::WebRtcStunProbeTrialParameter() {
599   const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
600   if (!cmd_line->HasSwitch(switches::kWebRtcStunProbeTrialParameter))
601     return base::nullopt;
602 
603   return blink::WebString::FromASCII(
604       cmd_line->GetSwitchValueASCII(switches::kWebRtcStunProbeTrialParameter));
605 }
606 
GetWebRTCMediaPermission(blink::WebLocalFrame * web_frame)607 media::MediaPermission* RendererBlinkPlatformImpl::GetWebRTCMediaPermission(
608     blink::WebLocalFrame* web_frame) {
609   DCHECK(ShouldEnforceWebRTCRoutingPreferences());
610 
611   media::MediaPermission* media_permission = nullptr;
612   RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(web_frame);
613   if (render_frame)
614     media_permission = render_frame->GetMediaPermission();
615   DCHECK(media_permission);
616   return media_permission;
617 }
618 
GetWebRTCRendererPreferences(blink::WebLocalFrame * web_frame,blink::WebString * ip_handling_policy,uint16_t * udp_min_port,uint16_t * udp_max_port,bool * allow_mdns_obfuscation)619 void RendererBlinkPlatformImpl::GetWebRTCRendererPreferences(
620     blink::WebLocalFrame* web_frame,
621     blink::WebString* ip_handling_policy,
622     uint16_t* udp_min_port,
623     uint16_t* udp_max_port,
624     bool* allow_mdns_obfuscation) {
625   DCHECK(ip_handling_policy);
626   DCHECK(udp_min_port);
627   DCHECK(udp_max_port);
628   DCHECK(allow_mdns_obfuscation);
629 
630   auto* render_frame = RenderFrameImpl::FromWebFrame(web_frame);
631   if (!render_frame)
632     return;
633 
634   *ip_handling_policy = blink::WebString::FromUTF8(
635       render_frame->GetRendererPreferences().webrtc_ip_handling_policy);
636   *udp_min_port = render_frame->GetRendererPreferences().webrtc_udp_min_port;
637   *udp_max_port = render_frame->GetRendererPreferences().webrtc_udp_max_port;
638   const std::vector<std::string>& allowed_urls =
639       render_frame->GetRendererPreferences().webrtc_local_ips_allowed_urls;
640   const std::string url(web_frame->GetSecurityOrigin().ToString().Utf8());
641   for (const auto& allowed_url : allowed_urls) {
642     if (base::MatchPattern(url, allowed_url)) {
643       *allow_mdns_obfuscation = false;
644       return;
645     }
646   }
647   *allow_mdns_obfuscation = true;
648 }
649 
GetAgcStartupMinimumVolume()650 base::Optional<int> RendererBlinkPlatformImpl::GetAgcStartupMinimumVolume() {
651   std::string min_volume_str =
652       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
653           switches::kAgcStartupMinVolume);
654   int startup_min_volume;
655   if (min_volume_str.empty() ||
656       !base::StringToInt(min_volume_str, &startup_min_volume)) {
657     return base::Optional<int>();
658   }
659   return base::Optional<int>(startup_min_volume);
660 }
661 
IsWebRtcHWH264DecodingEnabled(webrtc::VideoCodecType video_codec_type)662 bool RendererBlinkPlatformImpl::IsWebRtcHWH264DecodingEnabled(
663     webrtc::VideoCodecType video_codec_type) {
664 #if defined(OS_WIN)
665   // Do not use hardware decoding for H.264 on Win7, due to high latency.
666   // See https://crbug.com/webrtc/5717.
667   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
668           switches::kEnableWin7WebRtcHWH264Decoding) &&
669       video_codec_type == webrtc::kVideoCodecH264 &&
670       base::win::GetVersion() == base::win::Version::WIN7) {
671     DVLOG(1) << "H.264 HW decoding is not supported on Win7";
672     return false;
673   }
674 #endif  // defined(OS_WIN)
675   return true;
676 }
677 
IsWebRtcHWEncodingEnabled()678 bool RendererBlinkPlatformImpl::IsWebRtcHWEncodingEnabled() {
679   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
680       switches::kDisableWebRtcHWEncoding);
681 }
682 
IsWebRtcHWDecodingEnabled()683 bool RendererBlinkPlatformImpl::IsWebRtcHWDecodingEnabled() {
684   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
685       switches::kDisableWebRtcHWDecoding);
686 }
687 
IsWebRtcSrtpAesGcmEnabled()688 bool RendererBlinkPlatformImpl::IsWebRtcSrtpAesGcmEnabled() {
689   return base::CommandLine::ForCurrentProcess()->HasSwitch(
690       switches::kEnableWebRtcSrtpAesGcm);
691 }
692 
IsWebRtcSrtpEncryptedHeadersEnabled()693 bool RendererBlinkPlatformImpl::IsWebRtcSrtpEncryptedHeadersEnabled() {
694   return base::CommandLine::ForCurrentProcess()->HasSwitch(
695       switches::kEnableWebRtcSrtpEncryptedHeaders);
696 }
697 
AllowsLoopbackInPeerConnection()698 bool RendererBlinkPlatformImpl::AllowsLoopbackInPeerConnection() {
699   return base::CommandLine::ForCurrentProcess()->HasSwitch(
700       switches::kAllowLoopbackInPeerConnection);
701 }
702 
703 blink::WebVideoCaptureImplManager*
GetVideoCaptureImplManager()704 RendererBlinkPlatformImpl::GetVideoCaptureImplManager() {
705   RenderThreadImpl* thread = RenderThreadImpl::current();
706   return thread ? thread->video_capture_impl_manager() : nullptr;
707 }
708 
709 //------------------------------------------------------------------------------
710 
Collect3DContextInformation(blink::Platform::GraphicsInfo * gl_info,const gpu::GPUInfo & gpu_info)711 static void Collect3DContextInformation(blink::Platform::GraphicsInfo* gl_info,
712                                         const gpu::GPUInfo& gpu_info) {
713   DCHECK(gl_info);
714   const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
715   gl_info->vendor_id = active_gpu.vendor_id;
716   gl_info->device_id = active_gpu.device_id;
717   gl_info->renderer_info = WebString::FromUTF8(gpu_info.gl_renderer);
718   gl_info->vendor_info = WebString::FromUTF8(gpu_info.gl_vendor);
719   gl_info->driver_version = WebString::FromUTF8(active_gpu.driver_version);
720   gl_info->reset_notification_strategy =
721       gpu_info.gl_reset_notification_strategy;
722   gl_info->sandboxed = gpu_info.sandboxed;
723   gl_info->amd_switchable = gpu_info.amd_switchable;
724   gl_info->optimus = gpu_info.optimus;
725 }
726 
727 std::unique_ptr<blink::WebGraphicsContext3DProvider>
CreateOffscreenGraphicsContext3DProvider(const blink::Platform::ContextAttributes & web_attributes,const blink::WebURL & top_document_web_url,blink::Platform::GraphicsInfo * gl_info)728 RendererBlinkPlatformImpl::CreateOffscreenGraphicsContext3DProvider(
729     const blink::Platform::ContextAttributes& web_attributes,
730     const blink::WebURL& top_document_web_url,
731     blink::Platform::GraphicsInfo* gl_info) {
732   DCHECK(gl_info);
733   if (!RenderThreadImpl::current()) {
734     std::string error_message("Failed to run in Current RenderThreadImpl");
735     gl_info->error_message = WebString::FromUTF8(error_message);
736     return nullptr;
737   }
738 
739   scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
740       RenderThreadImpl::current()->EstablishGpuChannelSync());
741   if (!gpu_channel_host) {
742     std::string error_message(
743         "OffscreenContext Creation failed, GpuChannelHost creation failed");
744     gl_info->error_message = WebString::FromUTF8(error_message);
745     return nullptr;
746   }
747   Collect3DContextInformation(gl_info, gpu_channel_host->gpu_info());
748 
749   // This is an offscreen context. Generally it won't use the default
750   // frame buffer, in that case don't request any alpha, depth, stencil,
751   // antialiasing. But we do need those attributes for the "own
752   // offscreen surface" optimization which supports directly drawing
753   // to a custom surface backed frame buffer.
754   gpu::ContextCreationAttribs attributes;
755   attributes.alpha_size = web_attributes.support_alpha ? 8 : -1;
756   attributes.depth_size = web_attributes.support_depth ? 24 : 0;
757   attributes.stencil_size = web_attributes.support_stencil ? 8 : 0;
758   attributes.samples = web_attributes.support_antialias ? 4 : 0;
759   attributes.own_offscreen_surface =
760       web_attributes.support_alpha || web_attributes.support_depth ||
761       web_attributes.support_stencil || web_attributes.support_antialias;
762   attributes.sample_buffers = 0;
763   attributes.bind_generates_resource = false;
764   attributes.enable_raster_interface = web_attributes.enable_raster_interface;
765   attributes.enable_oop_rasterization =
766       attributes.enable_raster_interface &&
767       base::FeatureList::IsEnabled(features::kCanvasOopRasterization);
768   attributes.enable_gles2_interface = !attributes.enable_oop_rasterization;
769 
770   attributes.gpu_preference = web_attributes.prefer_low_power_gpu
771                                   ? gl::GpuPreference::kLowPower
772                                   : gl::GpuPreference::kHighPerformance;
773 
774   attributes.fail_if_major_perf_caveat =
775       web_attributes.fail_if_major_performance_caveat;
776 
777   attributes.context_type = ToGpuContextType(web_attributes.context_type);
778 
779   constexpr bool automatic_flushes = true;
780   constexpr bool support_locking = false;
781   bool use_grcontext =
782       !attributes.enable_oop_rasterization && web_attributes.support_grcontext;
783 
784   scoped_refptr<viz::ContextProviderCommandBuffer> provider(
785       new viz::ContextProviderCommandBuffer(
786           std::move(gpu_channel_host),
787           RenderThreadImpl::current()->GetGpuMemoryBufferManager(),
788           kGpuStreamIdDefault, kGpuStreamPriorityDefault,
789           gpu::kNullSurfaceHandle, GURL(top_document_web_url),
790           automatic_flushes, support_locking, use_grcontext,
791           gpu::SharedMemoryLimits(), attributes,
792           viz::command_buffer_metrics::ContextType::WEBGL));
793   return std::make_unique<WebGraphicsContext3DProviderImpl>(
794       std::move(provider));
795 }
796 
797 //------------------------------------------------------------------------------
798 
799 std::unique_ptr<blink::WebGraphicsContext3DProvider>
CreateSharedOffscreenGraphicsContext3DProvider()800 RendererBlinkPlatformImpl::CreateSharedOffscreenGraphicsContext3DProvider() {
801   auto* thread = RenderThreadImpl::current();
802 
803   scoped_refptr<viz::ContextProviderCommandBuffer> provider =
804       thread->SharedMainThreadContextProvider();
805   if (!provider)
806     return nullptr;
807 
808   scoped_refptr<gpu::GpuChannelHost> host = thread->EstablishGpuChannelSync();
809   // This shouldn't normally fail because we just got |provider|. But the
810   // channel can become lost on the IO thread since then. It is important that
811   // this happens after getting |provider|. In the case that this GpuChannelHost
812   // is not the same one backing |provider|, the context behind the |provider|
813   // will be already lost/dead on arrival.
814   if (!host)
815     return nullptr;
816 
817   return std::make_unique<WebGraphicsContext3DProviderImpl>(
818       std::move(provider));
819 }
820 
821 //------------------------------------------------------------------------------
822 
823 std::unique_ptr<blink::WebGraphicsContext3DProvider>
CreateWebGPUGraphicsContext3DProvider(const blink::WebURL & top_document_web_url)824 RendererBlinkPlatformImpl::CreateWebGPUGraphicsContext3DProvider(
825     const blink::WebURL& top_document_web_url) {
826 #if !BUILDFLAG(USE_DAWN)
827   return nullptr;
828 #else
829   scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
830       RenderThreadImpl::current()->EstablishGpuChannelSync());
831   if (!gpu_channel_host) {
832     // TODO(crbug.com/973017): Collect GPU info and surface context creation
833     // error.
834     return nullptr;
835   }
836 
837   gpu::ContextCreationAttribs attributes;
838   // TODO(kainino): It's not clear yet how GPU preferences work for WebGPU.
839   attributes.gpu_preference = gl::GpuPreference::kHighPerformance;
840   attributes.enable_gles2_interface = false;
841   attributes.context_type = gpu::CONTEXT_TYPE_WEBGPU;
842 
843   constexpr bool automatic_flushes = true;
844   constexpr bool support_locking = false;
845   constexpr bool support_grcontext = true;
846 
847   scoped_refptr<viz::ContextProviderCommandBuffer> provider(
848       new viz::ContextProviderCommandBuffer(
849           std::move(gpu_channel_host),
850           RenderThreadImpl::current()->GetGpuMemoryBufferManager(),
851           kGpuStreamIdDefault, kGpuStreamPriorityDefault,
852           gpu::kNullSurfaceHandle, GURL(top_document_web_url),
853           automatic_flushes, support_locking, support_grcontext,
854           gpu::SharedMemoryLimits::ForWebGPUContext(), attributes,
855           viz::command_buffer_metrics::ContextType::WEBGPU));
856   return std::make_unique<WebGraphicsContext3DProviderImpl>(
857       std::move(provider));
858 #endif
859 }
860 
861 //------------------------------------------------------------------------------
862 
863 gpu::GpuMemoryBufferManager*
GetGpuMemoryBufferManager()864 RendererBlinkPlatformImpl::GetGpuMemoryBufferManager() {
865   RenderThreadImpl* thread = RenderThreadImpl::current();
866   return thread ? thread->GetGpuMemoryBufferManager() : nullptr;
867 }
868 
869 //------------------------------------------------------------------------------
870 
ConvertIDNToUnicode(const blink::WebString & host)871 blink::WebString RendererBlinkPlatformImpl::ConvertIDNToUnicode(
872     const blink::WebString& host) {
873   return WebString::FromUTF16(url_formatter::IDNToUnicode(host.Ascii()));
874 }
875 
876 //------------------------------------------------------------------------------
877 
878 std::unique_ptr<blink::WebDedicatedWorkerHostFactoryClient>
CreateDedicatedWorkerHostFactoryClient(blink::WebDedicatedWorker * worker,const blink::BrowserInterfaceBrokerProxy & interface_broker)879 RendererBlinkPlatformImpl::CreateDedicatedWorkerHostFactoryClient(
880     blink::WebDedicatedWorker* worker,
881     const blink::BrowserInterfaceBrokerProxy& interface_broker) {
882   return std::make_unique<DedicatedWorkerHostFactoryClient>(worker,
883                                                             interface_broker);
884 }
885 
DidStartWorkerThread()886 void RendererBlinkPlatformImpl::DidStartWorkerThread() {
887   WorkerThreadRegistry::Instance()->DidStartCurrentWorkerThread();
888 }
889 
WillStopWorkerThread()890 void RendererBlinkPlatformImpl::WillStopWorkerThread() {
891   WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
892 }
893 
WorkerContextCreated(const v8::Local<v8::Context> & worker)894 void RendererBlinkPlatformImpl::WorkerContextCreated(
895     const v8::Local<v8::Context>& worker) {
896   GetContentClient()->renderer()->DidInitializeWorkerContextOnWorkerThread(
897       worker);
898 }
899 
AllowScriptExtensionForServiceWorker(const blink::WebSecurityOrigin & script_origin)900 bool RendererBlinkPlatformImpl::AllowScriptExtensionForServiceWorker(
901     const blink::WebSecurityOrigin& script_origin) {
902   return GetContentClient()->renderer()->AllowScriptExtensionForServiceWorker(
903       script_origin);
904 }
905 
906 blink::ProtocolHandlerSecurityLevel
GetProtocolHandlerSecurityLevel()907 RendererBlinkPlatformImpl::GetProtocolHandlerSecurityLevel() {
908   return GetContentClient()->renderer()->GetProtocolHandlerSecurityLevel();
909 }
910 
IsExcludedHeaderForServiceWorkerFetchEvent(const blink::WebString & header_name)911 bool RendererBlinkPlatformImpl::IsExcludedHeaderForServiceWorkerFetchEvent(
912     const blink::WebString& header_name) {
913   return GetContentClient()
914       ->renderer()
915       ->IsExcludedHeaderForServiceWorkerFetchEvent(header_name.Ascii());
916 }
917 
918 //------------------------------------------------------------------------------
919 
RecordMetricsForBackgroundedRendererPurge()920 void RendererBlinkPlatformImpl::RecordMetricsForBackgroundedRendererPurge() {
921   auto* render_thread = RenderThreadImpl::current();
922   // RenderThreadImpl is null in some tests.
923   if (!render_thread)
924     return;
925   render_thread->RecordMetricsForBackgroundedRendererPurge();
926 }
927 
928 //------------------------------------------------------------------------------
929 
930 // The returned BatchingMediaLog can be used on any thread, but must be
931 // destroyed on |owner_task_runner|. The aggregated MediaLogRecords will be
932 // sent back to the Browser via Mojo objects bound to |owner_task_runner|.
GetMediaLog(blink::MediaInspectorContext * inspector_context,scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner)933 std::unique_ptr<media::MediaLog> RendererBlinkPlatformImpl::GetMediaLog(
934     blink::MediaInspectorContext* inspector_context,
935     scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner) {
936   std::vector<std::unique_ptr<BatchingMediaLog::EventHandler>> handlers;
937 
938   // For chrome://media-internals.
939   handlers.push_back(std::make_unique<RenderMediaEventHandler>());
940 
941   // For devtools' media tab.
942   handlers.push_back(
943       std::make_unique<InspectorMediaEventHandler>(inspector_context));
944 
945   return std::make_unique<BatchingMediaLog>(owner_task_runner,
946                                             std::move(handlers));
947 }
948 
949 //------------------------------------------------------------------------------
950 media::GpuVideoAcceleratorFactories*
GetGpuFactories()951 RendererBlinkPlatformImpl::GetGpuFactories() {
952   auto* render_thread = RenderThreadImpl::current();
953   if (!render_thread)
954     return nullptr;
955 
956   return render_thread->GetGpuFactories();
957 }
958 
SetRenderingColorSpace(const gfx::ColorSpace & color_space)959 void RendererBlinkPlatformImpl::SetRenderingColorSpace(
960     const gfx::ColorSpace& color_space) {
961   auto* render_thread = RenderThreadImpl::current();
962   if (!render_thread)
963     return;
964 
965   render_thread->SetRenderingColorSpace(color_space);
966 }
967 
968 //------------------------------------------------------------------------------
969 
SetActiveURL(const blink::WebURL & url,const blink::WebString & top_url)970 void RendererBlinkPlatformImpl::SetActiveURL(const blink::WebURL& url,
971                                              const blink::WebString& top_url) {
972   GetContentClient()->SetActiveURL(url, top_url.Utf8());
973 }
974 
975 //------------------------------------------------------------------------------
976 
GetCodeCacheHost()977 blink::mojom::CodeCacheHost& RendererBlinkPlatformImpl::GetCodeCacheHost() {
978   if (!code_cache_host_) {
979     code_cache_host_ = mojo::SharedRemote<blink::mojom::CodeCacheHost>(
980         std::move(code_cache_host_remote_),
981         base::ThreadPool::CreateSequencedTaskRunner({}));
982   }
983   return *code_cache_host_;
984 }
985 
986 }  // namespace content
987