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