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.
5 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/lazy_instance.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/metrics/histogram.h"
13 #include "base/platform_file.h"
14 #include "base/safe_numerics.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "content/child/database_util.h"
18 #include "content/child/fileapi/webfilesystem_impl.h"
19 #include "content/child/indexed_db/proxy_webidbfactory_impl.h"
20 #include "content/child/npapi/npobject_util.h"
21 #include "content/child/quota_dispatcher.h"
22 #include "content/child/quota_message_filter.h"
23 #include "content/child/thread_safe_sender.h"
24 #include "content/child/web_database_observer_impl.h"
25 #include "content/child/webblobregistry_impl.h"
26 #include "content/child/webmessageportchannel_impl.h"
27 #include "content/common/file_utilities_messages.h"
28 #include "content/common/gpu/client/context_provider_command_buffer.h"
29 #include "content/common/gpu/client/gpu_channel_host.h"
30 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
31 #include "content/common/gpu/gpu_process_launch_causes.h"
32 #include "content/common/mime_registry_messages.h"
33 #include "content/common/view_messages.h"
34 #include "content/public/common/content_switches.h"
35 #include "content/public/common/webplugininfo.h"
36 #include "content/public/renderer/content_renderer_client.h"
37 #include "content/renderer/device_orientation/device_motion_event_pump.h"
38 #include "content/renderer/device_orientation/device_orientation_event_pump.h"
39 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
40 #include "content/renderer/gamepad_shared_memory_reader.h"
41 #include "content/renderer/media/audio_decoder.h"
42 #include "content/renderer/media/crypto/key_systems.h"
43 #include "content/renderer/media/media_stream_dependency_factory.h"
44 #include "content/renderer/media/renderer_webaudiodevice_impl.h"
45 #include "content/renderer/media/renderer_webmidiaccessor_impl.h"
46 #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
47 #include "content/renderer/render_thread_impl.h"
48 #include "content/renderer/renderer_clipboard_client.h"
49 #include "content/renderer/webclipboard_impl.h"
50 #include "content/renderer/webcrypto/webcrypto_impl.h"
51 #include "content/renderer/webpublicsuffixlist_impl.h"
52 #include "gpu/config/gpu_info.h"
53 #include "ipc/ipc_sync_message_filter.h"
54 #include "media/audio/audio_output_device.h"
55 #include "media/base/audio_hardware_config.h"
56 #include "media/filters/stream_parser_factory.h"
57 #include "net/base/mime_util.h"
58 #include "net/base/net_util.h"
59 #include "third_party/WebKit/public/platform/WebBlobRegistry.h"
60 #include "third_party/WebKit/public/platform/WebDeviceMotionListener.h"
61 #include "third_party/WebKit/public/platform/WebDeviceOrientationListener.h"
62 #include "third_party/WebKit/public/platform/WebFileInfo.h"
63 #include "third_party/WebKit/public/platform/WebGamepads.h"
64 #include "third_party/WebKit/public/platform/WebMediaStreamCenter.h"
65 #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h"
66 #include "third_party/WebKit/public/platform/WebPluginListBuilder.h"
67 #include "third_party/WebKit/public/platform/WebURL.h"
68 #include "third_party/WebKit/public/platform/WebVector.h"
69 #include "third_party/WebKit/public/web/WebFrame.h"
70 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
72 #include "webkit/common/gpu/webgraphicscontext3d_provider_impl.h"
73 #include "webkit/common/quota/quota_types.h"
74 #include "webkit/glue/simple_webmimeregistry_impl.h"
75 #include "webkit/glue/webfileutilities_impl.h"
76 #include "webkit/glue/webkit_glue.h"
79 #include "content/common/child_process_messages.h"
80 #include "third_party/WebKit/public/platform/win/WebSandboxSupport.h"
83 #if defined(OS_MACOSX)
84 #include "content/common/mac/font_descriptor.h"
85 #include "content/common/mac/font_loader.h"
86 #include "third_party/WebKit/public/platform/mac/WebSandboxSupport.h"
89 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
93 #include "base/synchronization/lock.h"
94 #include "content/common/child_process_sandbox_support_impl_linux.h"
95 #include "third_party/WebKit/public/platform/linux/WebFontFamily.h"
96 #include "third_party/WebKit/public/platform/linux/WebSandboxSupport.h"
97 #include "third_party/icu/source/common/unicode/utf16.h"
100 #if defined(OS_POSIX)
101 #include "base/file_descriptor_posix.h"
104 #if defined(OS_ANDROID)
105 #include "content/renderer/media/android/audio_decoder_android.h"
108 using blink::Platform
;
109 using blink::WebAudioDevice
;
110 using blink::WebBlobRegistry
;
111 using blink::WebDatabaseObserver
;
112 using blink::WebFileInfo
;
113 using blink::WebFileSystem
;
114 using blink::WebFrame
;
115 using blink::WebGamepads
;
116 using blink::WebIDBFactory
;
117 using blink::WebMIDIAccessor
;
118 using blink::WebMediaStreamCenter
;
119 using blink::WebMediaStreamCenterClient
;
120 using blink::WebMimeRegistry
;
121 using blink::WebRTCPeerConnectionHandler
;
122 using blink::WebRTCPeerConnectionHandlerClient
;
123 using blink::WebStorageNamespace
;
124 using blink::WebString
;
126 using blink::WebVector
;
130 static bool g_sandbox_enabled
= true;
131 base::LazyInstance
<WebGamepads
>::Leaky g_test_gamepads
=
132 LAZY_INSTANCE_INITIALIZER
;
133 base::LazyInstance
<blink::WebDeviceMotionData
>::Leaky
134 g_test_device_motion_data
= LAZY_INSTANCE_INITIALIZER
;
135 base::LazyInstance
<blink::WebDeviceOrientationData
>::Leaky
136 g_test_device_orientation_data
= LAZY_INSTANCE_INITIALIZER
;
138 //------------------------------------------------------------------------------
140 class RendererWebKitPlatformSupportImpl::MimeRegistry
141 : public webkit_glue::SimpleWebMimeRegistryImpl
{
143 virtual blink::WebMimeRegistry::SupportsType
supportsMediaMIMEType(
144 const blink::WebString
& mime_type
,
145 const blink::WebString
& codecs
,
146 const blink::WebString
& key_system
);
147 virtual bool supportsMediaSourceMIMEType(const blink::WebString
& mime_type
,
148 const blink::WebString
& codecs
);
149 virtual blink::WebString
mimeTypeForExtension(
150 const blink::WebString
& file_extension
);
151 virtual blink::WebString
mimeTypeFromFile(
152 const blink::WebString
& file_path
);
155 class RendererWebKitPlatformSupportImpl::FileUtilities
156 : public webkit_glue::WebFileUtilitiesImpl
{
158 explicit FileUtilities(ThreadSafeSender
* sender
)
159 : thread_safe_sender_(sender
) {}
160 virtual bool getFileInfo(const WebString
& path
, WebFileInfo
& result
);
162 bool SendSyncMessageFromAnyThread(IPC::SyncMessage
* msg
) const;
163 scoped_refptr
<ThreadSafeSender
> thread_safe_sender_
;
166 #if defined(OS_ANDROID)
167 // WebKit doesn't use WebSandboxSupport on android so we don't need to
168 // implement anything here.
169 class RendererWebKitPlatformSupportImpl::SandboxSupport
{
172 class RendererWebKitPlatformSupportImpl::SandboxSupport
173 : public blink::WebSandboxSupport
{
175 virtual ~SandboxSupport() {}
178 virtual bool ensureFontLoaded(HFONT
);
179 #elif defined(OS_MACOSX)
180 virtual bool loadFont(
182 CGFontRef
* container
,
184 #elif defined(OS_POSIX)
185 virtual void getFontFamilyForCharacter(
186 blink::WebUChar32 character
,
187 const char* preferred_locale
,
188 blink::WebFontFamily
* family
);
189 virtual void getRenderStyleForStrike(
190 const char* family
, int sizeAndStyle
, blink::WebFontRenderStyle
* out
);
193 // WebKit likes to ask us for the correct font family to use for a set of
194 // unicode code points. It needs this information frequently so we cache it
196 base::Lock unicode_font_families_mutex_
;
197 std::map
<int32_t, blink::WebFontFamily
> unicode_font_families_
;
200 #endif // defined(OS_ANDROID)
202 //------------------------------------------------------------------------------
204 RendererWebKitPlatformSupportImpl::RendererWebKitPlatformSupportImpl()
205 : clipboard_client_(new RendererClipboardClient
),
206 clipboard_(new WebClipboardImpl(clipboard_client_
.get())),
207 mime_registry_(new RendererWebKitPlatformSupportImpl::MimeRegistry
),
208 sudden_termination_disables_(0),
209 plugin_refresh_allowed_(true),
210 child_thread_loop_(base::MessageLoopProxy::current()) {
211 if (g_sandbox_enabled
&& sandboxEnabled()) {
212 sandbox_support_
.reset(
213 new RendererWebKitPlatformSupportImpl::SandboxSupport
);
215 DVLOG(1) << "Disabling sandbox support for testing.";
218 // ChildThread may not exist in some tests.
219 if (ChildThread::current()) {
220 sync_message_filter_
= ChildThread::current()->sync_message_filter();
221 thread_safe_sender_
= ChildThread::current()->thread_safe_sender();
222 quota_message_filter_
= ChildThread::current()->quota_message_filter();
223 blob_registry_
.reset(new WebBlobRegistryImpl(thread_safe_sender_
));
224 web_idb_factory_
.reset(new RendererWebIDBFactoryImpl(thread_safe_sender_
));
225 web_database_observer_impl_
.reset(
226 new WebDatabaseObserverImpl(sync_message_filter_
));
230 RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() {
231 WebFileSystemImpl::DeleteThreadSpecificInstance();
234 //------------------------------------------------------------------------------
236 blink::WebClipboard
* RendererWebKitPlatformSupportImpl::clipboard() {
237 blink::WebClipboard
* clipboard
=
238 GetContentClient()->renderer()->OverrideWebClipboard();
241 return clipboard_
.get();
244 blink::WebMimeRegistry
* RendererWebKitPlatformSupportImpl::mimeRegistry() {
245 return mime_registry_
.get();
248 blink::WebFileUtilities
*
249 RendererWebKitPlatformSupportImpl::fileUtilities() {
250 if (!file_utilities_
) {
251 file_utilities_
.reset(new FileUtilities(thread_safe_sender_
.get()));
252 file_utilities_
->set_sandbox_enabled(sandboxEnabled());
254 return file_utilities_
.get();
257 blink::WebSandboxSupport
* RendererWebKitPlatformSupportImpl::sandboxSupport() {
258 #if defined(OS_ANDROID)
259 // WebKit doesn't use WebSandboxSupport on android.
262 return sandbox_support_
.get();
266 blink::WebCookieJar
* RendererWebKitPlatformSupportImpl::cookieJar() {
267 NOTREACHED() << "Use WebFrameClient::cookieJar() instead!";
271 blink::WebThemeEngine
* RendererWebKitPlatformSupportImpl::themeEngine() {
272 blink::WebThemeEngine
* theme_engine
=
273 GetContentClient()->renderer()->OverrideThemeEngine();
276 return WebKitPlatformSupportImpl::themeEngine();
279 bool RendererWebKitPlatformSupportImpl::sandboxEnabled() {
280 // As explained in Platform.h, this function is used to decide
281 // whether to allow file system operations to come out of WebKit or not.
282 // Even if the sandbox is disabled, there's no reason why the code should
283 // act any differently...unless we're in single process mode. In which
284 // case, we have no other choice. Platform.h discourages using
285 // this switch unless absolutely necessary, so hopefully we won't end up
286 // with too many code paths being different in single-process mode.
287 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
);
290 unsigned long long RendererWebKitPlatformSupportImpl::visitedLinkHash(
291 const char* canonical_url
,
293 return GetContentClient()->renderer()->VisitedLinkHash(canonical_url
, length
);
296 bool RendererWebKitPlatformSupportImpl::isLinkVisited(
297 unsigned long long link_hash
) {
298 return GetContentClient()->renderer()->IsLinkVisited(link_hash
);
301 blink::WebMessagePortChannel
*
302 RendererWebKitPlatformSupportImpl::createMessagePortChannel() {
303 return new WebMessagePortChannelImpl(child_thread_loop_
.get());
306 blink::WebPrescientNetworking
*
307 RendererWebKitPlatformSupportImpl::prescientNetworking() {
308 return GetContentClient()->renderer()->GetPrescientNetworking();
312 RendererWebKitPlatformSupportImpl::CheckPreparsedJsCachingEnabled() const {
313 static bool checked
= false;
314 static bool result
= false;
316 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
317 result
= command_line
.HasSwitch(switches::kEnablePreparsedJsCaching
);
323 void RendererWebKitPlatformSupportImpl::cacheMetadata(
324 const blink::WebURL
& url
,
325 double response_time
,
328 if (!CheckPreparsedJsCachingEnabled())
331 // Let the browser know we generated cacheable metadata for this resource. The
332 // browser may cache it and return it on subsequent responses to speed
333 // the processing of this resource.
334 std::vector
<char> copy(data
, data
+ size
);
335 RenderThread::Get()->Send(
336 new ViewHostMsg_DidGenerateCacheableMetadata(url
, response_time
, copy
));
339 WebString
RendererWebKitPlatformSupportImpl::defaultLocale() {
340 return ASCIIToUTF16(RenderThread::Get()->GetLocale());
343 void RendererWebKitPlatformSupportImpl::suddenTerminationChanged(bool enabled
) {
345 // We should not get more enables than disables, but we want it to be a
346 // non-fatal error if it does happen.
347 DCHECK_GT(sudden_termination_disables_
, 0);
348 sudden_termination_disables_
= std::max(sudden_termination_disables_
- 1,
350 if (sudden_termination_disables_
!= 0)
353 sudden_termination_disables_
++;
354 if (sudden_termination_disables_
!= 1)
358 RenderThread
* thread
= RenderThread::Get();
359 if (thread
) // NULL in unittests.
360 thread
->Send(new ViewHostMsg_SuddenTerminationChanged(enabled
));
364 RendererWebKitPlatformSupportImpl::createLocalStorageNamespace() {
365 return new WebStorageNamespaceImpl();
369 //------------------------------------------------------------------------------
371 WebIDBFactory
* RendererWebKitPlatformSupportImpl::idbFactory() {
372 return web_idb_factory_
.get();
375 //------------------------------------------------------------------------------
377 WebFileSystem
* RendererWebKitPlatformSupportImpl::fileSystem() {
378 return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_
.get());
381 //------------------------------------------------------------------------------
383 WebMimeRegistry::SupportsType
384 RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaMIMEType(
385 const WebString
& mime_type
,
386 const WebString
& codecs
,
387 const WebString
& key_system
) {
388 const std::string mime_type_ascii
= ToASCIIOrEmpty(mime_type
);
389 // Not supporting the container is a flat-out no.
390 if (!net::IsSupportedMediaMimeType(mime_type_ascii
))
391 return IsNotSupported
;
393 if (!key_system
.isEmpty()) {
394 // Check whether the key system is supported with the mime_type and codecs.
396 std::vector
<std::string
> strict_codecs
;
397 bool strip_suffix
= !net::IsStrictMediaMimeType(mime_type_ascii
);
398 net::ParseCodecString(ToASCIIOrEmpty(codecs
), &strict_codecs
, strip_suffix
);
400 if (!IsSupportedKeySystemWithMediaMimeType(
401 mime_type_ascii
, strict_codecs
, ToASCIIOrEmpty(key_system
)))
402 return IsNotSupported
;
404 // Continue processing the mime_type and codecs.
407 // Check list of strict codecs to see if it is supported.
408 if (net::IsStrictMediaMimeType(mime_type_ascii
)) {
409 // We support the container, but no codecs were specified.
411 return MayBeSupported
;
413 // Check if the codecs are a perfect match.
414 std::vector
<std::string
> strict_codecs
;
415 net::ParseCodecString(ToASCIIOrEmpty(codecs
), &strict_codecs
, false);
416 if (!net::IsSupportedStrictMediaMimeType(mime_type_ascii
, strict_codecs
))
417 return IsNotSupported
;
423 // If we don't recognize the codec, it's possible we support it.
424 std::vector
<std::string
> parsed_codecs
;
425 net::ParseCodecString(ToASCIIOrEmpty(codecs
), &parsed_codecs
, true);
426 if (!net::AreSupportedMediaCodecs(parsed_codecs
))
427 return MayBeSupported
;
429 // Otherwise we have a perfect match.
434 RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaSourceMIMEType(
435 const blink::WebString
& mime_type
,
436 const WebString
& codecs
) {
437 const std::string mime_type_ascii
= ToASCIIOrEmpty(mime_type
);
438 std::vector
<std::string
> parsed_codec_ids
;
439 net::ParseCodecString(ToASCIIOrEmpty(codecs
), &parsed_codec_ids
, false);
440 if (mime_type_ascii
.empty())
442 return media::StreamParserFactory::IsTypeSupported(
443 mime_type_ascii
, parsed_codec_ids
);
447 RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeForExtension(
448 const WebString
& file_extension
) {
449 if (IsPluginProcess())
450 return SimpleWebMimeRegistryImpl::mimeTypeForExtension(file_extension
);
452 // The sandbox restricts our access to the registry, so we need to proxy
453 // these calls over to the browser process.
454 std::string mime_type
;
455 RenderThread::Get()->Send(
456 new MimeRegistryMsg_GetMimeTypeFromExtension(
457 base::FilePath::FromUTF16Unsafe(file_extension
).value(), &mime_type
));
458 return ASCIIToUTF16(mime_type
);
461 WebString
RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeFromFile(
462 const WebString
& file_path
) {
463 if (IsPluginProcess())
464 return SimpleWebMimeRegistryImpl::mimeTypeFromFile(file_path
);
466 // The sandbox restricts our access to the registry, so we need to proxy
467 // these calls over to the browser process.
468 std::string mime_type
;
469 RenderThread::Get()->Send(new MimeRegistryMsg_GetMimeTypeFromFile(
470 base::FilePath::FromUTF16Unsafe(file_path
),
472 return ASCIIToUTF16(mime_type
);
475 //------------------------------------------------------------------------------
477 bool RendererWebKitPlatformSupportImpl::FileUtilities::getFileInfo(
478 const WebString
& path
,
479 WebFileInfo
& web_file_info
) {
480 base::PlatformFileInfo file_info
;
481 base::PlatformFileError status
;
482 if (!SendSyncMessageFromAnyThread(new FileUtilitiesMsg_GetFileInfo(
483 base::FilePath::FromUTF16Unsafe(path
), &file_info
, &status
)) ||
484 status
!= base::PLATFORM_FILE_OK
) {
487 webkit_glue::PlatformFileInfoToWebFileInfo(file_info
, &web_file_info
);
488 web_file_info
.platformPath
= path
;
492 bool RendererWebKitPlatformSupportImpl::FileUtilities::
493 SendSyncMessageFromAnyThread(IPC::SyncMessage
* msg
) const {
494 base::TimeTicks begin
= base::TimeTicks::Now();
495 const bool success
= thread_safe_sender_
->Send(msg
);
496 base::TimeDelta delta
= base::TimeTicks::Now() - begin
;
497 UMA_HISTOGRAM_TIMES("RendererSyncIPC.ElapsedTime", delta
);
501 //------------------------------------------------------------------------------
505 bool RendererWebKitPlatformSupportImpl::SandboxSupport::ensureFontLoaded(
508 GetObject(font
, sizeof(LOGFONT
), &logfont
);
509 RenderThread::Get()->PreCacheFont(logfont
);
513 #elif defined(OS_MACOSX)
515 bool RendererWebKitPlatformSupportImpl::SandboxSupport::loadFont(
516 NSFont
* src_font
, CGFontRef
* out
, uint32
* font_id
) {
517 uint32 font_data_size
;
518 FontDescriptor
src_font_descriptor(src_font
);
519 base::SharedMemoryHandle font_data
;
520 if (!RenderThread::Get()->Send(new ViewHostMsg_LoadFont(
521 src_font_descriptor
, &font_data_size
, &font_data
, font_id
))) {
527 if (font_data_size
== 0 || font_data
== base::SharedMemory::NULLHandle() ||
529 LOG(ERROR
) << "Bad response from ViewHostMsg_LoadFont() for " <<
530 src_font_descriptor
.font_name
;
536 // TODO(jeremy): Need to call back into WebKit to make sure that the font
537 // isn't already activated, based on the font id. If it's already
538 // activated, don't reactivate it here - crbug.com/72727 .
540 return FontLoader::CGFontRefFromBuffer(font_data
, font_data_size
, out
);
543 #elif defined(OS_ANDROID)
545 // WebKit doesn't use WebSandboxSupport on android so we don't need to
546 // implement anything here. This is cleaner to support than excluding the
547 // whole class for android.
549 #elif defined(OS_POSIX)
552 RendererWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacter(
553 blink::WebUChar32 character
,
554 const char* preferred_locale
,
555 blink::WebFontFamily
* family
) {
556 base::AutoLock
lock(unicode_font_families_mutex_
);
557 const std::map
<int32_t, blink::WebFontFamily
>::const_iterator iter
=
558 unicode_font_families_
.find(character
);
559 if (iter
!= unicode_font_families_
.end()) {
560 family
->name
= iter
->second
.name
;
561 family
->isBold
= iter
->second
.isBold
;
562 family
->isItalic
= iter
->second
.isItalic
;
566 GetFontFamilyForCharacter(character
, preferred_locale
, family
);
567 unicode_font_families_
.insert(std::make_pair(character
, *family
));
571 RendererWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike(
572 const char* family
, int sizeAndStyle
, blink::WebFontRenderStyle
* out
) {
573 GetRenderStyleForStrike(family
, sizeAndStyle
, out
);
578 //------------------------------------------------------------------------------
581 RendererWebKitPlatformSupportImpl::databaseOpenFile(
582 const WebString
& vfs_file_name
, int desired_flags
) {
583 return DatabaseUtil::DatabaseOpenFile(
584 vfs_file_name
, desired_flags
, sync_message_filter_
.get());
587 int RendererWebKitPlatformSupportImpl::databaseDeleteFile(
588 const WebString
& vfs_file_name
, bool sync_dir
) {
589 return DatabaseUtil::DatabaseDeleteFile(
590 vfs_file_name
, sync_dir
, sync_message_filter_
.get());
593 long RendererWebKitPlatformSupportImpl::databaseGetFileAttributes(
594 const WebString
& vfs_file_name
) {
595 return DatabaseUtil::DatabaseGetFileAttributes(vfs_file_name
,
596 sync_message_filter_
.get());
599 long long RendererWebKitPlatformSupportImpl::databaseGetFileSize(
600 const WebString
& vfs_file_name
) {
601 return DatabaseUtil::DatabaseGetFileSize(vfs_file_name
,
602 sync_message_filter_
.get());
605 long long RendererWebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin(
606 const WebString
& origin_identifier
) {
607 return DatabaseUtil::DatabaseGetSpaceAvailable(origin_identifier
,
608 sync_message_filter_
.get());
611 bool RendererWebKitPlatformSupportImpl::canAccelerate2dCanvas() {
612 RenderThreadImpl
* thread
= RenderThreadImpl::current();
613 GpuChannelHost
* host
= thread
->EstablishGpuChannelSync(
614 CAUSE_FOR_GPU_LAUNCH_CANVAS_2D
);
618 const gpu::GPUInfo
& gpu_info
= host
->gpu_info();
619 if (gpu_info
.can_lose_context
|| gpu_info
.software_rendering
)
625 bool RendererWebKitPlatformSupportImpl::isThreadedCompositingEnabled() {
626 return !!RenderThreadImpl::current()->compositor_message_loop_proxy().get();
629 double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() {
630 RenderThreadImpl
* thread
= RenderThreadImpl::current();
631 return thread
->GetAudioHardwareConfig()->GetOutputSampleRate();
634 size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() {
635 RenderThreadImpl
* thread
= RenderThreadImpl::current();
636 return thread
->GetAudioHardwareConfig()->GetOutputBufferSize();
639 unsigned RendererWebKitPlatformSupportImpl::audioHardwareOutputChannels() {
640 RenderThreadImpl
* thread
= RenderThreadImpl::current();
641 return thread
->GetAudioHardwareConfig()->GetOutputChannels();
644 WebDatabaseObserver
* RendererWebKitPlatformSupportImpl::databaseObserver() {
645 return web_database_observer_impl_
.get();
648 // TODO(crogers): remove deprecated API as soon as WebKit calls new API.
650 RendererWebKitPlatformSupportImpl::createAudioDevice(
654 WebAudioDevice::RenderCallback
* callback
) {
655 return createAudioDevice(
656 buffer_size
, 0, channels
, sample_rate
, callback
, "default");
659 // TODO(crogers): remove deprecated API as soon as WebKit calls new API.
661 RendererWebKitPlatformSupportImpl::createAudioDevice(
663 unsigned input_channels
,
666 WebAudioDevice::RenderCallback
* callback
) {
667 return createAudioDevice(
668 buffer_size
, input_channels
, channels
, sample_rate
, callback
, "default");
672 RendererWebKitPlatformSupportImpl::createAudioDevice(
674 unsigned input_channels
,
677 WebAudioDevice::RenderCallback
* callback
,
678 const blink::WebString
& input_device_id
) {
679 // Use a mock for testing.
680 blink::WebAudioDevice
* mock_device
=
681 GetContentClient()->renderer()->OverrideCreateAudioDevice(sample_rate
);
685 // The |channels| does not exactly identify the channel layout of the
686 // device. The switch statement below assigns a best guess to the channel
687 // layout based on number of channels.
688 // TODO(crogers): WebKit should give the channel layout instead of the hard
690 media::ChannelLayout layout
= media::CHANNEL_LAYOUT_UNSUPPORTED
;
693 layout
= media::CHANNEL_LAYOUT_MONO
;
696 layout
= media::CHANNEL_LAYOUT_STEREO
;
699 layout
= media::CHANNEL_LAYOUT_2_1
;
702 layout
= media::CHANNEL_LAYOUT_4_0
;
705 layout
= media::CHANNEL_LAYOUT_5_0
;
708 layout
= media::CHANNEL_LAYOUT_5_1
;
711 layout
= media::CHANNEL_LAYOUT_7_0
;
714 layout
= media::CHANNEL_LAYOUT_7_1
;
717 layout
= media::CHANNEL_LAYOUT_STEREO
;
721 if (input_device_id
.isNull() ||
722 !base::StringToInt(UTF16ToUTF8(input_device_id
), &session_id
)) {
723 if (input_channels
> 0)
724 DLOG(WARNING
) << "createAudioDevice(): request for audio input ignored";
729 media::AudioParameters
params(
730 media::AudioParameters::AUDIO_PCM_LOW_LATENCY
,
731 layout
, input_channels
,
732 static_cast<int>(sample_rate
), 16, buffer_size
);
734 return new RendererWebAudioDeviceImpl(params
, callback
, session_id
);
737 #if defined(OS_ANDROID)
738 bool RendererWebKitPlatformSupportImpl::loadAudioResource(
739 blink::WebAudioBus
* destination_bus
, const char* audio_file_data
,
740 size_t data_size
, double sample_rate
) {
741 return DecodeAudioFileData(destination_bus
,
745 thread_safe_sender_
);
748 bool RendererWebKitPlatformSupportImpl::loadAudioResource(
749 blink::WebAudioBus
* destination_bus
, const char* audio_file_data
,
750 size_t data_size
, double sample_rate
) {
751 return DecodeAudioFileData(
752 destination_bus
, audio_file_data
, data_size
, sample_rate
);
754 #endif // defined(OS_ANDROID)
756 //------------------------------------------------------------------------------
758 blink::WebContentDecryptionModule
*
759 RendererWebKitPlatformSupportImpl::createContentDecryptionModule(
760 const blink::WebString
& key_system
) {
761 return WebContentDecryptionModuleImpl::Create(key_system
);
764 //------------------------------------------------------------------------------
766 blink::WebMIDIAccessor
*
767 RendererWebKitPlatformSupportImpl::createMIDIAccessor(
768 blink::WebMIDIAccessorClient
* client
) {
769 blink::WebMIDIAccessor
* accessor
=
770 GetContentClient()->renderer()->OverrideCreateMIDIAccessor(client
);
774 return new RendererWebMIDIAccessorImpl(client
);
777 void RendererWebKitPlatformSupportImpl::getPluginList(
779 blink::WebPluginListBuilder
* builder
) {
780 #if defined(ENABLE_PLUGINS)
781 std::vector
<WebPluginInfo
> plugins
;
782 if (!plugin_refresh_allowed_
)
784 RenderThread::Get()->Send(
785 new ViewHostMsg_GetPlugins(refresh
, &plugins
));
786 for (size_t i
= 0; i
< plugins
.size(); ++i
) {
787 const WebPluginInfo
& plugin
= plugins
[i
];
790 plugin
.name
, plugin
.desc
,
791 plugin
.path
.BaseName().AsUTF16Unsafe());
793 for (size_t j
= 0; j
< plugin
.mime_types
.size(); ++j
) {
794 const WebPluginMimeType
& mime_type
= plugin
.mime_types
[j
];
796 builder
->addMediaTypeToLastPlugin(
797 WebString::fromUTF8(mime_type
.mime_type
), mime_type
.description
);
799 for (size_t k
= 0; k
< mime_type
.file_extensions
.size(); ++k
) {
800 builder
->addFileExtensionToLastMediaType(
801 WebString::fromUTF8(mime_type
.file_extensions
[k
]));
808 //------------------------------------------------------------------------------
810 blink::WebPublicSuffixList
*
811 RendererWebKitPlatformSupportImpl::publicSuffixList() {
812 return &public_suffix_list_
;
815 //------------------------------------------------------------------------------
818 RendererWebKitPlatformSupportImpl::signedPublicKeyAndChallengeString(
819 unsigned key_size_index
,
820 const blink::WebString
& challenge
,
821 const blink::WebURL
& url
) {
822 std::string signed_public_key
;
823 RenderThread::Get()->Send(new ViewHostMsg_Keygen(
824 static_cast<uint32
>(key_size_index
),
827 &signed_public_key
));
828 return WebString::fromUTF8(signed_public_key
);
831 //------------------------------------------------------------------------------
833 void RendererWebKitPlatformSupportImpl::screenColorProfile(
834 WebVector
<char>* to_profile
) {
835 std::vector
<char> profile
;
836 RenderThread::Get()->Send(
837 new ViewHostMsg_GetMonitorColorProfile(&profile
));
838 *to_profile
= profile
;
841 //------------------------------------------------------------------------------
843 WebBlobRegistry
* RendererWebKitPlatformSupportImpl::blobRegistry() {
844 // blob_registry_ can be NULL when running some tests.
845 return blob_registry_
.get();
848 //------------------------------------------------------------------------------
850 void RendererWebKitPlatformSupportImpl::sampleGamepads(WebGamepads
& gamepads
) {
851 if (g_test_gamepads
== 0) {
852 RenderThreadImpl::current()->SampleGamepads(&gamepads
);
854 gamepads
= g_test_gamepads
.Get();
858 blink::WebString
RendererWebKitPlatformSupportImpl::userAgent(
859 const blink::WebURL
& url
) {
860 return WebKitPlatformSupportImpl::userAgent(url
);
863 //------------------------------------------------------------------------------
865 WebRTCPeerConnectionHandler
*
866 RendererWebKitPlatformSupportImpl::createRTCPeerConnectionHandler(
867 WebRTCPeerConnectionHandlerClient
* client
) {
868 RenderThreadImpl
* render_thread
= RenderThreadImpl::current();
869 DCHECK(render_thread
);
873 #if defined(ENABLE_WEBRTC)
874 WebRTCPeerConnectionHandler
* peer_connection_handler
=
875 GetContentClient()->renderer()->OverrideCreateWebRTCPeerConnectionHandler(
877 if (peer_connection_handler
)
878 return peer_connection_handler
;
880 MediaStreamDependencyFactory
* rtc_dependency_factory
=
881 render_thread
->GetMediaStreamDependencyFactory();
882 return rtc_dependency_factory
->CreateRTCPeerConnectionHandler(client
);
885 #endif // defined(ENABLE_WEBRTC)
888 //------------------------------------------------------------------------------
890 WebMediaStreamCenter
*
891 RendererWebKitPlatformSupportImpl::createMediaStreamCenter(
892 WebMediaStreamCenterClient
* client
) {
893 RenderThreadImpl
* render_thread
= RenderThreadImpl::current();
894 DCHECK(render_thread
);
897 return render_thread
->CreateMediaStreamCenter(client
);
901 bool RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting(
903 bool was_enabled
= g_sandbox_enabled
;
904 g_sandbox_enabled
= enable
;
909 void RendererWebKitPlatformSupportImpl::SetMockGamepadsForTesting(
910 const WebGamepads
& pads
) {
911 g_test_gamepads
.Get() = pads
;
914 //------------------------------------------------------------------------------
916 blink::WebSpeechSynthesizer
*
917 RendererWebKitPlatformSupportImpl::createSpeechSynthesizer(
918 blink::WebSpeechSynthesizerClient
* client
) {
919 return GetContentClient()->renderer()->OverrideSpeechSynthesizer(client
);
922 //------------------------------------------------------------------------------
924 bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes(
925 size_t* private_bytes
, size_t* shared_bytes
) {
926 content::RenderThread::Get()->Send(
927 new ViewHostMsg_GetProcessMemorySizes(private_bytes
, shared_bytes
));
931 //------------------------------------------------------------------------------
933 blink::WebGraphicsContext3D
*
934 RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D(
935 const blink::WebGraphicsContext3D::Attributes
& attributes
) {
936 if (!RenderThreadImpl::current())
939 scoped_refptr
<GpuChannelHost
> gpu_channel_host(
940 RenderThreadImpl::current()->EstablishGpuChannelSync(
941 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
));
943 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits
;
945 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
946 if (command_line
->HasSwitch(switches::kWebGLCommandBufferSizeKb
)) {
947 std::string size_string
= command_line
->GetSwitchValueASCII(
948 switches::kWebGLCommandBufferSizeKb
);
949 size_t buffer_size_kb
;
950 if (base::StringToSizeT(size_string
, &buffer_size_kb
)) {
951 limits
.command_buffer_size
= buffer_size_kb
* 1024;
955 return WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
956 gpu_channel_host
.get(),
958 GURL(attributes
.topDocumentURL
),
962 //------------------------------------------------------------------------------
964 blink::WebGraphicsContext3DProvider
* RendererWebKitPlatformSupportImpl::
965 createSharedOffscreenGraphicsContext3DProvider() {
966 scoped_refptr
<cc::ContextProvider
> provider
=
967 RenderThreadImpl::current()->SharedMainThreadContextProvider();
970 return new webkit::gpu::WebGraphicsContext3DProviderImpl(provider
);
973 //------------------------------------------------------------------------------
975 blink::WebCompositorSupport
*
976 RendererWebKitPlatformSupportImpl::compositorSupport() {
977 return &compositor_support_
;
980 //------------------------------------------------------------------------------
982 blink::WebString
RendererWebKitPlatformSupportImpl::convertIDNToUnicode(
983 const blink::WebString
& host
,
984 const blink::WebString
& languages
) {
985 return net::IDNToUnicode(host
.utf8(), languages
.utf8());
988 //------------------------------------------------------------------------------
990 void RendererWebKitPlatformSupportImpl::setDeviceMotionListener(
991 blink::WebDeviceMotionListener
* listener
) {
992 if (g_test_device_motion_data
== 0) {
993 if (!device_motion_event_pump_
) {
994 device_motion_event_pump_
.reset(new DeviceMotionEventPump
);
995 device_motion_event_pump_
->Attach(RenderThreadImpl::current());
997 device_motion_event_pump_
->SetListener(listener
);
998 } else if (listener
) {
999 // Testing mode: just echo the test data to the listener.
1000 base::MessageLoopProxy::current()->PostTask(
1002 base::Bind(&blink::WebDeviceMotionListener::didChangeDeviceMotion
,
1003 base::Unretained(listener
),
1004 g_test_device_motion_data
.Get()));
1009 void RendererWebKitPlatformSupportImpl::SetMockDeviceMotionDataForTesting(
1010 const blink::WebDeviceMotionData
& data
) {
1011 g_test_device_motion_data
.Get() = data
;
1014 //------------------------------------------------------------------------------
1016 void RendererWebKitPlatformSupportImpl::setDeviceOrientationListener(
1017 blink::WebDeviceOrientationListener
* listener
) {
1018 if (g_test_device_orientation_data
== 0) {
1019 if (!device_orientation_event_pump_
) {
1020 device_orientation_event_pump_
.reset(new DeviceOrientationEventPump
);
1021 device_orientation_event_pump_
->Attach(RenderThreadImpl::current());
1023 device_orientation_event_pump_
->SetListener(listener
);
1024 } else if (listener
) {
1025 // Testing mode: just echo the test data to the listener.
1026 base::MessageLoopProxy::current()->PostTask(
1029 &blink::WebDeviceOrientationListener::didChangeDeviceOrientation
,
1030 base::Unretained(listener
),
1031 g_test_device_orientation_data
.Get()));
1036 void RendererWebKitPlatformSupportImpl::SetMockDeviceOrientationDataForTesting(
1037 const blink::WebDeviceOrientationData
& data
) {
1038 g_test_device_orientation_data
.Get() = data
;
1041 //------------------------------------------------------------------------------
1043 blink::WebCrypto
* RendererWebKitPlatformSupportImpl::crypto() {
1045 web_crypto_
.reset(new WebCryptoImpl());
1046 return web_crypto_
.get();
1050 //------------------------------------------------------------------------------
1052 void RendererWebKitPlatformSupportImpl::vibrate(unsigned int milliseconds
) {
1053 RenderThread::Get()->Send(
1054 new ViewHostMsg_Vibrate(base::checked_numeric_cast
<int64
>(milliseconds
)));
1057 void RendererWebKitPlatformSupportImpl::cancelVibration() {
1058 RenderThread::Get()->Send(new ViewHostMsg_CancelVibration());
1061 //------------------------------------------------------------------------------
1063 void RendererWebKitPlatformSupportImpl::queryStorageUsageAndQuota(
1064 const blink::WebURL
& storage_partition
,
1065 blink::WebStorageQuotaType type
,
1066 blink::WebStorageQuotaCallbacks
* callbacks
) {
1067 if (!thread_safe_sender_
.get() || !quota_message_filter_
.get())
1069 QuotaDispatcher::ThreadSpecificInstance(
1070 thread_safe_sender_
.get(),
1071 quota_message_filter_
.get())->QueryStorageUsageAndQuota(
1073 static_cast<quota::StorageType
>(type
),
1074 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks
));
1077 } // namespace content