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_webkitplatformsupport_impl.h" 6 7#include "base/command_line.h" 8#include "base/files/file_path.h" 9#include "base/lazy_instance.h" 10#include "base/logging.h" 11#include "base/memory/shared_memory.h" 12#include "base/message_loop/message_loop_proxy.h" 13#include "base/metrics/histogram.h" 14#include "base/numerics/safe_conversions.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/file_info_util.h" 19#include "content/child/fileapi/webfilesystem_impl.h" 20#include "content/child/indexed_db/webidbfactory_impl.h" 21#include "content/child/npapi/npobject_util.h" 22#include "content/child/quota_dispatcher.h" 23#include "content/child/quota_message_filter.h" 24#include "content/child/simple_webmimeregistry_impl.h" 25#include "content/child/thread_safe_sender.h" 26#include "content/child/web_database_observer_impl.h" 27#include "content/child/webblobregistry_impl.h" 28#include "content/child/webfileutilities_impl.h" 29#include "content/child/webmessageportchannel_impl.h" 30#include "content/common/file_utilities_messages.h" 31#include "content/common/gpu/client/context_provider_command_buffer.h" 32#include "content/common/gpu/client/gpu_channel_host.h" 33#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 34#include "content/common/gpu/gpu_process_launch_causes.h" 35#include "content/common/mime_registry_messages.h" 36#include "content/common/view_messages.h" 37#include "content/public/common/content_switches.h" 38#include "content/public/common/webplugininfo.h" 39#include "content/public/renderer/content_renderer_client.h" 40#include "content/renderer/battery_status/battery_status_dispatcher.h" 41#include "content/renderer/device_sensors/device_light_event_pump.h" 42#include "content/renderer/device_sensors/device_motion_event_pump.h" 43#include "content/renderer/device_sensors/device_orientation_event_pump.h" 44#include "content/renderer/dom_storage/webstoragenamespace_impl.h" 45#include "content/renderer/gamepad_shared_memory_reader.h" 46#include "content/renderer/media/audio_decoder.h" 47#include "content/renderer/media/crypto/key_systems.h" 48#include "content/renderer/media/renderer_webaudiodevice_impl.h" 49#include "content/renderer/media/renderer_webmidiaccessor_impl.h" 50#include "content/renderer/media/webcontentdecryptionmodule_impl.h" 51#include "content/renderer/render_thread_impl.h" 52#include "content/renderer/renderer_clipboard_client.h" 53#include "content/renderer/screen_orientation/screen_orientation_observer.h" 54#include "content/renderer/webclipboard_impl.h" 55#include "content/renderer/webgraphicscontext3d_provider_impl.h" 56#include "content/renderer/webpublicsuffixlist_impl.h" 57#include "gpu/config/gpu_info.h" 58#include "ipc/ipc_sync_message_filter.h" 59#include "media/audio/audio_output_device.h" 60#include "media/base/audio_hardware_config.h" 61#include "media/filters/stream_parser_factory.h" 62#include "net/base/mime_util.h" 63#include "net/base/net_util.h" 64#include "storage/common/quota/quota_types.h" 65#include "third_party/WebKit/public/platform/WebBatteryStatusListener.h" 66#include "third_party/WebKit/public/platform/WebBlobRegistry.h" 67#include "third_party/WebKit/public/platform/WebDeviceLightListener.h" 68#include "third_party/WebKit/public/platform/WebDeviceMotionListener.h" 69#include "third_party/WebKit/public/platform/WebDeviceOrientationListener.h" 70#include "third_party/WebKit/public/platform/WebFileInfo.h" 71#include "third_party/WebKit/public/platform/WebGamepads.h" 72#include "third_party/WebKit/public/platform/WebMediaStreamCenter.h" 73#include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h" 74#include "third_party/WebKit/public/platform/WebPluginListBuilder.h" 75#include "third_party/WebKit/public/platform/WebURL.h" 76#include "third_party/WebKit/public/platform/WebVector.h" 77#include "ui/gfx/color_profile.h" 78#include "url/gurl.h" 79#include "webkit/common/gpu/context_provider_web_context.h" 80 81#if defined(OS_ANDROID) 82#include "content/renderer/android/synchronous_compositor_factory.h" 83#include "content/renderer/media/android/audio_decoder_android.h" 84#endif 85 86#if defined(OS_MACOSX) 87#include "content/common/mac/font_descriptor.h" 88#include "content/common/mac/font_loader.h" 89#include "content/renderer/webscrollbarbehavior_impl_mac.h" 90#include "third_party/WebKit/public/platform/mac/WebSandboxSupport.h" 91#endif 92 93#if defined(OS_POSIX) 94#include "base/file_descriptor_posix.h" 95#if !defined(OS_MACOSX) && !defined(OS_ANDROID) 96#include <map> 97#include <string> 98 99#include "base/synchronization/lock.h" 100#include "content/common/child_process_sandbox_support_impl_linux.h" 101#include "third_party/WebKit/public/platform/linux/WebFallbackFont.h" 102#include "third_party/WebKit/public/platform/linux/WebSandboxSupport.h" 103#include "third_party/icu/source/common/unicode/utf16.h" 104#endif 105#endif 106 107#if defined(OS_WIN) 108#include "content/common/child_process_messages.h" 109#include "third_party/WebKit/public/platform/win/WebSandboxSupport.h" 110#endif 111 112#if defined(USE_AURA) 113#include "content/renderer/webscrollbarbehavior_impl_gtkoraura.h" 114#elif !defined(OS_MACOSX) 115#include "third_party/WebKit/public/platform/WebScrollbarBehavior.h" 116#define WebScrollbarBehaviorImpl blink::WebScrollbarBehavior 117#endif 118 119#if defined(ENABLE_WEBRTC) 120#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" 121#endif 122 123using blink::Platform; 124using blink::WebAudioDevice; 125using blink::WebBlobRegistry; 126using blink::WebDatabaseObserver; 127using blink::WebFileInfo; 128using blink::WebFileSystem; 129using blink::WebGamepad; 130using blink::WebGamepads; 131using blink::WebIDBFactory; 132using blink::WebMIDIAccessor; 133using blink::WebMediaStreamCenter; 134using blink::WebMediaStreamCenterClient; 135using blink::WebMimeRegistry; 136using blink::WebRTCPeerConnectionHandler; 137using blink::WebRTCPeerConnectionHandlerClient; 138using blink::WebStorageNamespace; 139using blink::WebString; 140using blink::WebURL; 141using blink::WebVector; 142 143namespace content { 144 145namespace { 146 147bool g_sandbox_enabled = true; 148double g_test_device_light_data = -1; 149base::LazyInstance<blink::WebDeviceMotionData>::Leaky 150 g_test_device_motion_data = LAZY_INSTANCE_INITIALIZER; 151base::LazyInstance<blink::WebDeviceOrientationData>::Leaky 152 g_test_device_orientation_data = LAZY_INSTANCE_INITIALIZER; 153 154} // namespace 155 156//------------------------------------------------------------------------------ 157 158class RendererWebKitPlatformSupportImpl::MimeRegistry 159 : public SimpleWebMimeRegistryImpl { 160 public: 161 virtual blink::WebMimeRegistry::SupportsType supportsMediaMIMEType( 162 const blink::WebString& mime_type, 163 const blink::WebString& codecs, 164 const blink::WebString& key_system); 165 virtual bool supportsMediaSourceMIMEType(const blink::WebString& mime_type, 166 const blink::WebString& codecs); 167 virtual bool supportsEncryptedMediaMIMEType(const WebString& key_system, 168 const WebString& mime_type, 169 const WebString& codecs) OVERRIDE; 170 virtual blink::WebString mimeTypeForExtension( 171 const blink::WebString& file_extension); 172 virtual blink::WebString mimeTypeFromFile( 173 const blink::WebString& file_path); 174}; 175 176class RendererWebKitPlatformSupportImpl::FileUtilities 177 : public WebFileUtilitiesImpl { 178 public: 179 explicit FileUtilities(ThreadSafeSender* sender) 180 : thread_safe_sender_(sender) {} 181 virtual bool getFileInfo(const WebString& path, WebFileInfo& result); 182 private: 183 bool SendSyncMessageFromAnyThread(IPC::SyncMessage* msg) const; 184 scoped_refptr<ThreadSafeSender> thread_safe_sender_; 185}; 186 187#if defined(OS_ANDROID) 188// WebKit doesn't use WebSandboxSupport on android so we don't need to 189// implement anything here. 190class RendererWebKitPlatformSupportImpl::SandboxSupport { 191}; 192#else 193class RendererWebKitPlatformSupportImpl::SandboxSupport 194 : public blink::WebSandboxSupport { 195 public: 196 virtual ~SandboxSupport() {} 197 198#if defined(OS_WIN) 199 virtual bool ensureFontLoaded(HFONT); 200#elif defined(OS_MACOSX) 201 virtual bool loadFont( 202 NSFont* src_font, 203 CGFontRef* container, 204 uint32* font_id); 205#elif defined(OS_POSIX) 206 virtual void getFallbackFontForCharacter( 207 blink::WebUChar32 character, 208 const char* preferred_locale, 209 blink::WebFallbackFont* fallbackFont); 210 virtual void getRenderStyleForStrike( 211 const char* family, int sizeAndStyle, blink::WebFontRenderStyle* out); 212 213 private: 214 // WebKit likes to ask us for the correct font family to use for a set of 215 // unicode code points. It needs this information frequently so we cache it 216 // here. 217 base::Lock unicode_font_families_mutex_; 218 std::map<int32_t, blink::WebFallbackFont> unicode_font_families_; 219#endif 220}; 221#endif // defined(OS_ANDROID) 222 223//------------------------------------------------------------------------------ 224 225RendererWebKitPlatformSupportImpl::RendererWebKitPlatformSupportImpl() 226 : clipboard_client_(new RendererClipboardClient), 227 clipboard_(new WebClipboardImpl(clipboard_client_.get())), 228 mime_registry_(new RendererWebKitPlatformSupportImpl::MimeRegistry), 229 sudden_termination_disables_(0), 230 plugin_refresh_allowed_(true), 231 child_thread_loop_(base::MessageLoopProxy::current()), 232 web_scrollbar_behavior_(new WebScrollbarBehaviorImpl) { 233 if (g_sandbox_enabled && sandboxEnabled()) { 234 sandbox_support_.reset( 235 new RendererWebKitPlatformSupportImpl::SandboxSupport); 236 } else { 237 DVLOG(1) << "Disabling sandbox support for testing."; 238 } 239 240 // ChildThread may not exist in some tests. 241 if (ChildThread::current()) { 242 sync_message_filter_ = ChildThread::current()->sync_message_filter(); 243 thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); 244 quota_message_filter_ = ChildThread::current()->quota_message_filter(); 245 blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_.get())); 246 web_idb_factory_.reset(new WebIDBFactoryImpl(thread_safe_sender_.get())); 247 web_database_observer_impl_.reset( 248 new WebDatabaseObserverImpl(sync_message_filter_.get())); 249 } 250} 251 252RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() { 253 WebFileSystemImpl::DeleteThreadSpecificInstance(); 254} 255 256//------------------------------------------------------------------------------ 257 258blink::WebClipboard* RendererWebKitPlatformSupportImpl::clipboard() { 259 blink::WebClipboard* clipboard = 260 GetContentClient()->renderer()->OverrideWebClipboard(); 261 if (clipboard) 262 return clipboard; 263 return clipboard_.get(); 264} 265 266blink::WebMimeRegistry* RendererWebKitPlatformSupportImpl::mimeRegistry() { 267 return mime_registry_.get(); 268} 269 270blink::WebFileUtilities* 271RendererWebKitPlatformSupportImpl::fileUtilities() { 272 if (!file_utilities_) { 273 file_utilities_.reset(new FileUtilities(thread_safe_sender_.get())); 274 file_utilities_->set_sandbox_enabled(sandboxEnabled()); 275 } 276 return file_utilities_.get(); 277} 278 279blink::WebSandboxSupport* RendererWebKitPlatformSupportImpl::sandboxSupport() { 280#if defined(OS_ANDROID) 281 // WebKit doesn't use WebSandboxSupport on android. 282 return NULL; 283#else 284 return sandbox_support_.get(); 285#endif 286} 287 288blink::WebCookieJar* RendererWebKitPlatformSupportImpl::cookieJar() { 289 NOTREACHED() << "Use WebFrameClient::cookieJar() instead!"; 290 return NULL; 291} 292 293blink::WebThemeEngine* RendererWebKitPlatformSupportImpl::themeEngine() { 294 blink::WebThemeEngine* theme_engine = 295 GetContentClient()->renderer()->OverrideThemeEngine(); 296 if (theme_engine) 297 return theme_engine; 298 return BlinkPlatformImpl::themeEngine(); 299} 300 301bool RendererWebKitPlatformSupportImpl::sandboxEnabled() { 302 // As explained in Platform.h, this function is used to decide 303 // whether to allow file system operations to come out of WebKit or not. 304 // Even if the sandbox is disabled, there's no reason why the code should 305 // act any differently...unless we're in single process mode. In which 306 // case, we have no other choice. Platform.h discourages using 307 // this switch unless absolutely necessary, so hopefully we won't end up 308 // with too many code paths being different in single-process mode. 309 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); 310} 311 312unsigned long long RendererWebKitPlatformSupportImpl::visitedLinkHash( 313 const char* canonical_url, 314 size_t length) { 315 return GetContentClient()->renderer()->VisitedLinkHash(canonical_url, length); 316} 317 318bool RendererWebKitPlatformSupportImpl::isLinkVisited( 319 unsigned long long link_hash) { 320 return GetContentClient()->renderer()->IsLinkVisited(link_hash); 321} 322 323void RendererWebKitPlatformSupportImpl::createMessageChannel( 324 blink::WebMessagePortChannel** channel1, 325 blink::WebMessagePortChannel** channel2) { 326 WebMessagePortChannelImpl::CreatePair( 327 child_thread_loop_.get(), channel1, channel2); 328} 329 330blink::WebPrescientNetworking* 331RendererWebKitPlatformSupportImpl::prescientNetworking() { 332 return GetContentClient()->renderer()->GetPrescientNetworking(); 333} 334 335void RendererWebKitPlatformSupportImpl::cacheMetadata( 336 const blink::WebURL& url, 337 double response_time, 338 const char* data, 339 size_t size) { 340 // Let the browser know we generated cacheable metadata for this resource. The 341 // browser may cache it and return it on subsequent responses to speed 342 // the processing of this resource. 343 std::vector<char> copy(data, data + size); 344 RenderThread::Get()->Send( 345 new ViewHostMsg_DidGenerateCacheableMetadata(url, response_time, copy)); 346} 347 348WebString RendererWebKitPlatformSupportImpl::defaultLocale() { 349 return base::ASCIIToUTF16(RenderThread::Get()->GetLocale()); 350} 351 352void RendererWebKitPlatformSupportImpl::suddenTerminationChanged(bool enabled) { 353 if (enabled) { 354 // We should not get more enables than disables, but we want it to be a 355 // non-fatal error if it does happen. 356 DCHECK_GT(sudden_termination_disables_, 0); 357 sudden_termination_disables_ = std::max(sudden_termination_disables_ - 1, 358 0); 359 if (sudden_termination_disables_ != 0) 360 return; 361 } else { 362 sudden_termination_disables_++; 363 if (sudden_termination_disables_ != 1) 364 return; 365 } 366 367 RenderThread* thread = RenderThread::Get(); 368 if (thread) // NULL in unittests. 369 thread->Send(new ViewHostMsg_SuddenTerminationChanged(enabled)); 370} 371 372WebStorageNamespace* 373RendererWebKitPlatformSupportImpl::createLocalStorageNamespace() { 374 return new WebStorageNamespaceImpl(); 375} 376 377 378//------------------------------------------------------------------------------ 379 380WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() { 381 return web_idb_factory_.get(); 382} 383 384//------------------------------------------------------------------------------ 385 386WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() { 387 return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); 388} 389 390//------------------------------------------------------------------------------ 391 392WebMimeRegistry::SupportsType 393RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaMIMEType( 394 const WebString& mime_type, 395 const WebString& codecs, 396 const WebString& key_system) { 397 const std::string mime_type_ascii = ToASCIIOrEmpty(mime_type); 398 // Not supporting the container is a flat-out no. 399 if (!net::IsSupportedMediaMimeType(mime_type_ascii)) 400 return IsNotSupported; 401 402 if (!key_system.isEmpty()) { 403 // Check whether the key system is supported with the mime_type and codecs. 404 405 // Chromium only supports ASCII parameters. 406 if (!base::IsStringASCII(key_system)) 407 return IsNotSupported; 408 409 std::string key_system_ascii = 410 GetUnprefixedKeySystemName(base::UTF16ToASCII(key_system)); 411 std::vector<std::string> strict_codecs; 412 net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, true); 413 414 if (!IsSupportedKeySystemWithMediaMimeType( 415 mime_type_ascii, strict_codecs, key_system_ascii)) { 416 return IsNotSupported; 417 } 418 419 // Continue processing the mime_type and codecs. 420 } 421 422 // Check list of strict codecs to see if it is supported. 423 if (net::IsStrictMediaMimeType(mime_type_ascii)) { 424 // Check if the codecs are a perfect match. 425 std::vector<std::string> strict_codecs; 426 net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, false); 427 return static_cast<WebMimeRegistry::SupportsType> ( 428 net::IsSupportedStrictMediaMimeType(mime_type_ascii, strict_codecs)); 429 } 430 431 // If we don't recognize the codec, it's possible we support it. 432 std::vector<std::string> parsed_codecs; 433 net::ParseCodecString(ToASCIIOrEmpty(codecs), &parsed_codecs, true); 434 if (!net::AreSupportedMediaCodecs(parsed_codecs)) 435 return MayBeSupported; 436 437 // Otherwise we have a perfect match. 438 return IsSupported; 439} 440 441bool 442RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaSourceMIMEType( 443 const blink::WebString& mime_type, 444 const WebString& codecs) { 445 const std::string mime_type_ascii = ToASCIIOrEmpty(mime_type); 446 std::vector<std::string> parsed_codec_ids; 447 net::ParseCodecString(ToASCIIOrEmpty(codecs), &parsed_codec_ids, false); 448 if (mime_type_ascii.empty()) 449 return false; 450 return media::StreamParserFactory::IsTypeSupported( 451 mime_type_ascii, parsed_codec_ids); 452} 453 454bool 455RendererWebKitPlatformSupportImpl::MimeRegistry::supportsEncryptedMediaMIMEType( 456 const WebString& key_system, 457 const WebString& mime_type, 458 const WebString& codecs) { 459 // Chromium only supports ASCII parameters. 460 if (!base::IsStringASCII(key_system) || !base::IsStringASCII(mime_type) || 461 !base::IsStringASCII(codecs)) { 462 return false; 463 } 464 465 if (key_system.isEmpty()) 466 return false; 467 468 const std::string mime_type_ascii = base::UTF16ToASCII(mime_type); 469 470 std::vector<std::string> codec_vector; 471 bool strip_suffix = !net::IsStrictMediaMimeType(mime_type_ascii); 472 net::ParseCodecString(base::UTF16ToASCII(codecs), &codec_vector, 473 strip_suffix); 474 475 return IsSupportedKeySystemWithMediaMimeType( 476 mime_type_ascii, codec_vector, base::UTF16ToASCII(key_system)); 477} 478 479WebString 480RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeForExtension( 481 const WebString& file_extension) { 482 if (IsPluginProcess()) 483 return SimpleWebMimeRegistryImpl::mimeTypeForExtension(file_extension); 484 485 // The sandbox restricts our access to the registry, so we need to proxy 486 // these calls over to the browser process. 487 std::string mime_type; 488 RenderThread::Get()->Send( 489 new MimeRegistryMsg_GetMimeTypeFromExtension( 490 base::FilePath::FromUTF16Unsafe(file_extension).value(), &mime_type)); 491 return base::ASCIIToUTF16(mime_type); 492} 493 494WebString RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeFromFile( 495 const WebString& file_path) { 496 if (IsPluginProcess()) 497 return SimpleWebMimeRegistryImpl::mimeTypeFromFile(file_path); 498 499 // The sandbox restricts our access to the registry, so we need to proxy 500 // these calls over to the browser process. 501 std::string mime_type; 502 RenderThread::Get()->Send(new MimeRegistryMsg_GetMimeTypeFromFile( 503 base::FilePath::FromUTF16Unsafe(file_path), 504 &mime_type)); 505 return base::ASCIIToUTF16(mime_type); 506} 507 508//------------------------------------------------------------------------------ 509 510bool RendererWebKitPlatformSupportImpl::FileUtilities::getFileInfo( 511 const WebString& path, 512 WebFileInfo& web_file_info) { 513 base::File::Info file_info; 514 base::File::Error status = base::File::FILE_ERROR_MAX; 515 if (!SendSyncMessageFromAnyThread(new FileUtilitiesMsg_GetFileInfo( 516 base::FilePath::FromUTF16Unsafe(path), &file_info, &status)) || 517 status != base::File::FILE_OK) { 518 return false; 519 } 520 FileInfoToWebFileInfo(file_info, &web_file_info); 521 web_file_info.platformPath = path; 522 return true; 523} 524 525bool RendererWebKitPlatformSupportImpl::FileUtilities:: 526SendSyncMessageFromAnyThread(IPC::SyncMessage* msg) const { 527 base::TimeTicks begin = base::TimeTicks::Now(); 528 const bool success = thread_safe_sender_->Send(msg); 529 base::TimeDelta delta = base::TimeTicks::Now() - begin; 530 UMA_HISTOGRAM_TIMES("RendererSyncIPC.ElapsedTime", delta); 531 return success; 532} 533 534//------------------------------------------------------------------------------ 535 536#if defined(OS_WIN) 537 538bool RendererWebKitPlatformSupportImpl::SandboxSupport::ensureFontLoaded( 539 HFONT font) { 540 LOGFONT logfont; 541 GetObject(font, sizeof(LOGFONT), &logfont); 542 RenderThread::Get()->PreCacheFont(logfont); 543 return true; 544} 545 546#elif defined(OS_MACOSX) 547 548bool RendererWebKitPlatformSupportImpl::SandboxSupport::loadFont( 549 NSFont* src_font, CGFontRef* out, uint32* font_id) { 550 uint32 font_data_size; 551 FontDescriptor src_font_descriptor(src_font); 552 base::SharedMemoryHandle font_data; 553 if (!RenderThread::Get()->Send(new ViewHostMsg_LoadFont( 554 src_font_descriptor, &font_data_size, &font_data, font_id))) { 555 *out = NULL; 556 *font_id = 0; 557 return false; 558 } 559 560 if (font_data_size == 0 || font_data == base::SharedMemory::NULLHandle() || 561 *font_id == 0) { 562 LOG(ERROR) << "Bad response from ViewHostMsg_LoadFont() for " << 563 src_font_descriptor.font_name; 564 *out = NULL; 565 *font_id = 0; 566 return false; 567 } 568 569 // TODO(jeremy): Need to call back into WebKit to make sure that the font 570 // isn't already activated, based on the font id. If it's already 571 // activated, don't reactivate it here - crbug.com/72727 . 572 573 return FontLoader::CGFontRefFromBuffer(font_data, font_data_size, out); 574} 575 576#elif defined(OS_ANDROID) 577 578// WebKit doesn't use WebSandboxSupport on android so we don't need to 579// implement anything here. This is cleaner to support than excluding the 580// whole class for android. 581 582#elif defined(OS_POSIX) 583 584void 585RendererWebKitPlatformSupportImpl::SandboxSupport::getFallbackFontForCharacter( 586 blink::WebUChar32 character, 587 const char* preferred_locale, 588 blink::WebFallbackFont* fallbackFont) { 589 base::AutoLock lock(unicode_font_families_mutex_); 590 const std::map<int32_t, blink::WebFallbackFont>::const_iterator iter = 591 unicode_font_families_.find(character); 592 if (iter != unicode_font_families_.end()) { 593 fallbackFont->name = iter->second.name; 594 fallbackFont->filename = iter->second.filename; 595 fallbackFont->fontconfigInterfaceId = iter->second.fontconfigInterfaceId; 596 fallbackFont->ttcIndex = iter->second.ttcIndex; 597 fallbackFont->isBold = iter->second.isBold; 598 fallbackFont->isItalic = iter->second.isItalic; 599 return; 600 } 601 602 GetFallbackFontForCharacter(character, preferred_locale, fallbackFont); 603 unicode_font_families_.insert(std::make_pair(character, *fallbackFont)); 604} 605 606void 607RendererWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike( 608 const char* family, int sizeAndStyle, blink::WebFontRenderStyle* out) { 609 GetRenderStyleForStrike(family, sizeAndStyle, out); 610} 611 612#endif 613 614//------------------------------------------------------------------------------ 615 616Platform::FileHandle 617RendererWebKitPlatformSupportImpl::databaseOpenFile( 618 const WebString& vfs_file_name, int desired_flags) { 619 return DatabaseUtil::DatabaseOpenFile( 620 vfs_file_name, desired_flags, sync_message_filter_.get()); 621} 622 623int RendererWebKitPlatformSupportImpl::databaseDeleteFile( 624 const WebString& vfs_file_name, bool sync_dir) { 625 return DatabaseUtil::DatabaseDeleteFile( 626 vfs_file_name, sync_dir, sync_message_filter_.get()); 627} 628 629long RendererWebKitPlatformSupportImpl::databaseGetFileAttributes( 630 const WebString& vfs_file_name) { 631 return DatabaseUtil::DatabaseGetFileAttributes(vfs_file_name, 632 sync_message_filter_.get()); 633} 634 635long long RendererWebKitPlatformSupportImpl::databaseGetFileSize( 636 const WebString& vfs_file_name) { 637 return DatabaseUtil::DatabaseGetFileSize(vfs_file_name, 638 sync_message_filter_.get()); 639} 640 641long long RendererWebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin( 642 const WebString& origin_identifier) { 643 return DatabaseUtil::DatabaseGetSpaceAvailable(origin_identifier, 644 sync_message_filter_.get()); 645} 646 647bool RendererWebKitPlatformSupportImpl::canAccelerate2dCanvas() { 648 RenderThreadImpl* thread = RenderThreadImpl::current(); 649 GpuChannelHost* host = thread->EstablishGpuChannelSync( 650 CAUSE_FOR_GPU_LAUNCH_CANVAS_2D); 651 if (!host) 652 return false; 653 654 return host->gpu_info().SupportsAccelerated2dCanvas(); 655} 656 657bool RendererWebKitPlatformSupportImpl::isThreadedCompositingEnabled() { 658 RenderThreadImpl* thread = RenderThreadImpl::current(); 659 // thread can be NULL in tests. 660 return thread && thread->compositor_message_loop_proxy().get(); 661} 662 663double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() { 664 RenderThreadImpl* thread = RenderThreadImpl::current(); 665 return thread->GetAudioHardwareConfig()->GetOutputSampleRate(); 666} 667 668size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() { 669 RenderThreadImpl* thread = RenderThreadImpl::current(); 670 return thread->GetAudioHardwareConfig()->GetOutputBufferSize(); 671} 672 673unsigned RendererWebKitPlatformSupportImpl::audioHardwareOutputChannels() { 674 RenderThreadImpl* thread = RenderThreadImpl::current(); 675 return thread->GetAudioHardwareConfig()->GetOutputChannels(); 676} 677 678WebDatabaseObserver* RendererWebKitPlatformSupportImpl::databaseObserver() { 679 return web_database_observer_impl_.get(); 680} 681 682WebAudioDevice* 683RendererWebKitPlatformSupportImpl::createAudioDevice( 684 size_t buffer_size, 685 unsigned input_channels, 686 unsigned channels, 687 double sample_rate, 688 WebAudioDevice::RenderCallback* callback, 689 const blink::WebString& input_device_id) { 690 // Use a mock for testing. 691 blink::WebAudioDevice* mock_device = 692 GetContentClient()->renderer()->OverrideCreateAudioDevice(sample_rate); 693 if (mock_device) 694 return mock_device; 695 696 // The |channels| does not exactly identify the channel layout of the 697 // device. The switch statement below assigns a best guess to the channel 698 // layout based on number of channels. 699 // TODO(crogers): WebKit should give the channel layout instead of the hard 700 // channel count. 701 media::ChannelLayout layout = media::CHANNEL_LAYOUT_UNSUPPORTED; 702 switch (channels) { 703 case 1: 704 layout = media::CHANNEL_LAYOUT_MONO; 705 break; 706 case 2: 707 layout = media::CHANNEL_LAYOUT_STEREO; 708 break; 709 case 3: 710 layout = media::CHANNEL_LAYOUT_2_1; 711 break; 712 case 4: 713 layout = media::CHANNEL_LAYOUT_4_0; 714 break; 715 case 5: 716 layout = media::CHANNEL_LAYOUT_5_0; 717 break; 718 case 6: 719 layout = media::CHANNEL_LAYOUT_5_1; 720 break; 721 case 7: 722 layout = media::CHANNEL_LAYOUT_7_0; 723 break; 724 case 8: 725 layout = media::CHANNEL_LAYOUT_7_1; 726 break; 727 default: 728 layout = media::CHANNEL_LAYOUT_STEREO; 729 } 730 731 int session_id = 0; 732 if (input_device_id.isNull() || 733 !base::StringToInt(base::UTF16ToUTF8(input_device_id), &session_id)) { 734 if (input_channels > 0) 735 DLOG(WARNING) << "createAudioDevice(): request for audio input ignored"; 736 737 input_channels = 0; 738 } 739 740 media::AudioParameters params( 741 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 742 layout, static_cast<int>(sample_rate), 16, buffer_size, 743 media::AudioParameters::NO_EFFECTS); 744 745 return new RendererWebAudioDeviceImpl(params, callback, session_id); 746} 747 748#if defined(OS_ANDROID) 749bool RendererWebKitPlatformSupportImpl::loadAudioResource( 750 blink::WebAudioBus* destination_bus, const char* audio_file_data, 751 size_t data_size) { 752 return DecodeAudioFileData(destination_bus, 753 audio_file_data, 754 data_size, 755 thread_safe_sender_); 756} 757#else 758bool RendererWebKitPlatformSupportImpl::loadAudioResource( 759 blink::WebAudioBus* destination_bus, const char* audio_file_data, 760 size_t data_size) { 761 return DecodeAudioFileData( 762 destination_bus, audio_file_data, data_size); 763} 764#endif // defined(OS_ANDROID) 765 766//------------------------------------------------------------------------------ 767 768blink::WebMIDIAccessor* 769RendererWebKitPlatformSupportImpl::createMIDIAccessor( 770 blink::WebMIDIAccessorClient* client) { 771 blink::WebMIDIAccessor* accessor = 772 GetContentClient()->renderer()->OverrideCreateMIDIAccessor(client); 773 if (accessor) 774 return accessor; 775 776 return new RendererWebMIDIAccessorImpl(client); 777} 778 779void RendererWebKitPlatformSupportImpl::getPluginList( 780 bool refresh, 781 blink::WebPluginListBuilder* builder) { 782#if defined(ENABLE_PLUGINS) 783 std::vector<WebPluginInfo> plugins; 784 if (!plugin_refresh_allowed_) 785 refresh = false; 786 RenderThread::Get()->Send( 787 new ViewHostMsg_GetPlugins(refresh, &plugins)); 788 for (size_t i = 0; i < plugins.size(); ++i) { 789 const WebPluginInfo& plugin = plugins[i]; 790 791 builder->addPlugin( 792 plugin.name, plugin.desc, 793 plugin.path.BaseName().AsUTF16Unsafe()); 794 795 for (size_t j = 0; j < plugin.mime_types.size(); ++j) { 796 const WebPluginMimeType& mime_type = plugin.mime_types[j]; 797 798 builder->addMediaTypeToLastPlugin( 799 WebString::fromUTF8(mime_type.mime_type), mime_type.description); 800 801 for (size_t k = 0; k < mime_type.file_extensions.size(); ++k) { 802 builder->addFileExtensionToLastMediaType( 803 WebString::fromUTF8(mime_type.file_extensions[k])); 804 } 805 } 806 } 807#endif 808} 809 810//------------------------------------------------------------------------------ 811 812blink::WebPublicSuffixList* 813RendererWebKitPlatformSupportImpl::publicSuffixList() { 814 return &public_suffix_list_; 815} 816 817//------------------------------------------------------------------------------ 818 819blink::WebString 820RendererWebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( 821 unsigned key_size_index, 822 const blink::WebString& challenge, 823 const blink::WebURL& url) { 824 std::string signed_public_key; 825 RenderThread::Get()->Send(new ViewHostMsg_Keygen( 826 static_cast<uint32>(key_size_index), 827 challenge.utf8(), 828 GURL(url), 829 &signed_public_key)); 830 return WebString::fromUTF8(signed_public_key); 831} 832 833//------------------------------------------------------------------------------ 834 835void RendererWebKitPlatformSupportImpl::screenColorProfile( 836 WebVector<char>* to_profile) { 837#if defined(OS_WIN) 838 // On Windows screen color profile is only available in the browser. 839 std::vector<char> profile; 840 // This Send() can be called from any impl-side thread. Use a thread 841 // safe send to avoid crashing trying to access RenderThread::Get(), 842 // which is not accessible from arbitrary threads. 843 thread_safe_sender_->Send( 844 new ViewHostMsg_GetMonitorColorProfile(&profile)); 845 *to_profile = profile; 846#else 847 // On other platforms, the primary monitor color profile can be read 848 // directly. 849 gfx::ColorProfile profile; 850 *to_profile = profile.profile(); 851#endif 852} 853 854//------------------------------------------------------------------------------ 855 856blink::WebScrollbarBehavior* 857 RendererWebKitPlatformSupportImpl::scrollbarBehavior() { 858 return web_scrollbar_behavior_.get(); 859} 860 861//------------------------------------------------------------------------------ 862 863WebBlobRegistry* RendererWebKitPlatformSupportImpl::blobRegistry() { 864 // blob_registry_ can be NULL when running some tests. 865 return blob_registry_.get(); 866} 867 868//------------------------------------------------------------------------------ 869 870void RendererWebKitPlatformSupportImpl::sampleGamepads(WebGamepads& gamepads) { 871 PlatformEventObserverBase* observer = 872 platform_event_observers_.Lookup(blink::WebPlatformEventGamepad); 873 if (!observer) 874 return; 875 static_cast<RendererGamepadProvider*>(observer)->SampleGamepads(gamepads); 876} 877 878//------------------------------------------------------------------------------ 879 880WebRTCPeerConnectionHandler* 881RendererWebKitPlatformSupportImpl::createRTCPeerConnectionHandler( 882 WebRTCPeerConnectionHandlerClient* client) { 883 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 884 DCHECK(render_thread); 885 if (!render_thread) 886 return NULL; 887 888#if defined(ENABLE_WEBRTC) 889 WebRTCPeerConnectionHandler* peer_connection_handler = 890 GetContentClient()->renderer()->OverrideCreateWebRTCPeerConnectionHandler( 891 client); 892 if (peer_connection_handler) 893 return peer_connection_handler; 894 895 PeerConnectionDependencyFactory* rtc_dependency_factory = 896 render_thread->GetPeerConnectionDependencyFactory(); 897 return rtc_dependency_factory->CreateRTCPeerConnectionHandler(client); 898#else 899 return NULL; 900#endif // defined(ENABLE_WEBRTC) 901} 902 903//------------------------------------------------------------------------------ 904 905WebMediaStreamCenter* 906RendererWebKitPlatformSupportImpl::createMediaStreamCenter( 907 WebMediaStreamCenterClient* client) { 908 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 909 DCHECK(render_thread); 910 if (!render_thread) 911 return NULL; 912 return render_thread->CreateMediaStreamCenter(client); 913} 914 915// static 916bool RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting( 917 bool enable) { 918 bool was_enabled = g_sandbox_enabled; 919 g_sandbox_enabled = enable; 920 return was_enabled; 921} 922 923//------------------------------------------------------------------------------ 924 925blink::WebSpeechSynthesizer* 926RendererWebKitPlatformSupportImpl::createSpeechSynthesizer( 927 blink::WebSpeechSynthesizerClient* client) { 928 return GetContentClient()->renderer()->OverrideSpeechSynthesizer(client); 929} 930 931//------------------------------------------------------------------------------ 932 933bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes( 934 size_t* private_bytes, size_t* shared_bytes) { 935 content::RenderThread::Get()->Send( 936 new ViewHostMsg_GetProcessMemorySizes(private_bytes, shared_bytes)); 937 return true; 938} 939 940//------------------------------------------------------------------------------ 941 942blink::WebGraphicsContext3D* 943RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D( 944 const blink::WebGraphicsContext3D::Attributes& attributes) { 945 return createOffscreenGraphicsContext3D(attributes, NULL); 946} 947 948blink::WebGraphicsContext3D* 949RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D( 950 const blink::WebGraphicsContext3D::Attributes& attributes, 951 blink::WebGraphicsContext3D* share_context) { 952 if (!RenderThreadImpl::current()) 953 return NULL; 954 955 scoped_ptr<webkit::gpu::WebGraphicsContext3DImpl> context; 956 bool must_use_synchronous_factory = false; 957#if defined(OS_ANDROID) 958 if (SynchronousCompositorFactory* factory = 959 SynchronousCompositorFactory::GetInstance()) { 960 context.reset(factory->CreateOffscreenGraphicsContext3D(attributes)); 961 must_use_synchronous_factory = true; 962 } 963#endif 964 if (!must_use_synchronous_factory) { 965 scoped_refptr<GpuChannelHost> gpu_channel_host( 966 RenderThreadImpl::current()->EstablishGpuChannelSync( 967 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)); 968 969 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits; 970 bool lose_context_when_out_of_memory = false; 971 context.reset(WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 972 gpu_channel_host.get(), 973 attributes, 974 lose_context_when_out_of_memory, 975 GURL(attributes.topDocumentURL), 976 limits, 977 static_cast<WebGraphicsContext3DCommandBufferImpl*>(share_context))); 978 } 979 // Most likely the GPU process exited and the attempt to reconnect to it 980 // failed. Need to try to restore the context again later. 981 if (!context || !context->InitializeOnCurrentThread()) 982 return NULL; 983 return context.release(); 984} 985 986//------------------------------------------------------------------------------ 987 988blink::WebGraphicsContext3DProvider* RendererWebKitPlatformSupportImpl:: 989 createSharedOffscreenGraphicsContext3DProvider() { 990 scoped_refptr<webkit::gpu::ContextProviderWebContext> provider = 991 RenderThreadImpl::current()->SharedMainThreadContextProvider(); 992 if (!provider.get()) 993 return NULL; 994 return new WebGraphicsContext3DProviderImpl(provider); 995} 996 997//------------------------------------------------------------------------------ 998 999blink::WebCompositorSupport* 1000RendererWebKitPlatformSupportImpl::compositorSupport() { 1001 return &compositor_support_; 1002} 1003 1004//------------------------------------------------------------------------------ 1005 1006blink::WebString RendererWebKitPlatformSupportImpl::convertIDNToUnicode( 1007 const blink::WebString& host, 1008 const blink::WebString& languages) { 1009 return net::IDNToUnicode(host.utf8(), languages.utf8()); 1010} 1011 1012//------------------------------------------------------------------------------ 1013 1014// static 1015void RendererWebKitPlatformSupportImpl::SetMockDeviceLightDataForTesting( 1016 double data) { 1017 g_test_device_light_data = data; 1018} 1019 1020//------------------------------------------------------------------------------ 1021 1022// static 1023void RendererWebKitPlatformSupportImpl::SetMockDeviceMotionDataForTesting( 1024 const blink::WebDeviceMotionData& data) { 1025 g_test_device_motion_data.Get() = data; 1026} 1027 1028//------------------------------------------------------------------------------ 1029 1030// static 1031void RendererWebKitPlatformSupportImpl::SetMockDeviceOrientationDataForTesting( 1032 const blink::WebDeviceOrientationData& data) { 1033 g_test_device_orientation_data.Get() = data; 1034} 1035 1036//------------------------------------------------------------------------------ 1037 1038void RendererWebKitPlatformSupportImpl::vibrate(unsigned int milliseconds) { 1039 RenderThread::Get()->Send( 1040 new ViewHostMsg_Vibrate(base::checked_cast<int64>(milliseconds))); 1041} 1042 1043void RendererWebKitPlatformSupportImpl::cancelVibration() { 1044 RenderThread::Get()->Send(new ViewHostMsg_CancelVibration()); 1045} 1046 1047//------------------------------------------------------------------------------ 1048 1049// static 1050PlatformEventObserverBase* 1051RendererWebKitPlatformSupportImpl::CreatePlatformEventObserverFromType( 1052 blink::WebPlatformEventType type) { 1053 RenderThread* thread = RenderThreadImpl::current(); 1054 1055 // When running layout tests, those observers should not listen to the actual 1056 // hardware changes. In order to make that happen, they will receive a null 1057 // thread. 1058 if (thread && RenderThreadImpl::current()->layout_test_mode()) 1059 thread = 0; 1060 1061 switch (type) { 1062 case blink::WebPlatformEventDeviceMotion: { 1063 return new DeviceMotionEventPump(thread); 1064 } 1065 case blink::WebPlatformEventDeviceOrientation: { 1066 return new DeviceOrientationEventPump(thread); 1067 } 1068 case blink::WebPlatformEventDeviceLight: { 1069 return new DeviceLightEventPump(thread); 1070 } 1071 case blink::WebPlatformEventBattery: { 1072 return new BatteryStatusDispatcher(thread); 1073 } 1074 case blink::WebPlatformEventGamepad: 1075 return new GamepadSharedMemoryReader(thread); 1076 break; 1077 case blink::WebPlatformEventScreenOrientation: 1078 return new ScreenOrientationObserver(); 1079 default: 1080 // A default statement is required to prevent compilation errors when Blink 1081 // adds a new type. 1082 VLOG(1) << "RendererWebKitPlatformSupportImpl::startListening() with " 1083 "unknown type."; 1084 } 1085 1086 return 0; 1087} 1088 1089void RendererWebKitPlatformSupportImpl::SetPlatformEventObserverForTesting( 1090 blink::WebPlatformEventType type, 1091 scoped_ptr<PlatformEventObserverBase> observer) { 1092 if (platform_event_observers_.Lookup(type)) 1093 platform_event_observers_.Remove(type); 1094 platform_event_observers_.AddWithID(observer.release(), type); 1095} 1096 1097void RendererWebKitPlatformSupportImpl::startListening( 1098 blink::WebPlatformEventType type, 1099 blink::WebPlatformEventListener* listener) { 1100 PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type); 1101 if (!observer) { 1102 observer = CreatePlatformEventObserverFromType(type); 1103 if (!observer) 1104 return; 1105 platform_event_observers_.AddWithID(observer, static_cast<int32>(type)); 1106 } 1107 observer->Start(listener); 1108 1109 // Device events (motion, orientation and light) expect to get an event fired 1110 // as soon as a listener is registered if a fake data was passed before. 1111 // TODO(mlamouri,timvolodine): make those send mock values directly instead of 1112 // using this broken pattern. 1113 if (RenderThreadImpl::current() && 1114 RenderThreadImpl::current()->layout_test_mode() && 1115 (type == blink::WebPlatformEventDeviceMotion || 1116 type == blink::WebPlatformEventDeviceOrientation || 1117 type == blink::WebPlatformEventDeviceLight)) { 1118 SendFakeDeviceEventDataForTesting(type); 1119 } 1120} 1121 1122void RendererWebKitPlatformSupportImpl::SendFakeDeviceEventDataForTesting( 1123 blink::WebPlatformEventType type) { 1124 PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type); 1125 CHECK(observer); 1126 1127 void* data = 0; 1128 1129 switch (type) { 1130 case blink::WebPlatformEventDeviceMotion: 1131 if (!(g_test_device_motion_data == 0)) 1132 data = &g_test_device_motion_data.Get(); 1133 break; 1134 case blink::WebPlatformEventDeviceOrientation: 1135 if (!(g_test_device_orientation_data == 0)) 1136 data = &g_test_device_orientation_data.Get(); 1137 break; 1138 case blink::WebPlatformEventDeviceLight: 1139 if (g_test_device_light_data >= 0) 1140 data = &g_test_device_light_data; 1141 break; 1142 default: 1143 NOTREACHED(); 1144 break; 1145 } 1146 1147 if (!data) 1148 return; 1149 1150 base::MessageLoopProxy::current()->PostTask( 1151 FROM_HERE, 1152 base::Bind(&PlatformEventObserverBase::SendFakeDataForTesting, 1153 base::Unretained(observer), data)); 1154} 1155 1156void RendererWebKitPlatformSupportImpl::stopListening( 1157 blink::WebPlatformEventType type) { 1158 PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type); 1159 if (!observer) 1160 return; 1161 observer->Stop(); 1162} 1163 1164//------------------------------------------------------------------------------ 1165 1166void RendererWebKitPlatformSupportImpl::queryStorageUsageAndQuota( 1167 const blink::WebURL& storage_partition, 1168 blink::WebStorageQuotaType type, 1169 blink::WebStorageQuotaCallbacks callbacks) { 1170 if (!thread_safe_sender_.get() || !quota_message_filter_.get()) 1171 return; 1172 QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender_.get(), 1173 quota_message_filter_.get()) 1174 ->QueryStorageUsageAndQuota( 1175 storage_partition, 1176 static_cast<storage::StorageType>(type), 1177 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks)); 1178} 1179 1180//------------------------------------------------------------------------------ 1181 1182void RendererWebKitPlatformSupportImpl::MockBatteryStatusChangedForTesting( 1183 const blink::WebBatteryStatus& status) { 1184 PlatformEventObserverBase* observer = 1185 platform_event_observers_.Lookup(blink::WebPlatformEventBattery); 1186 if (!observer) 1187 return; 1188 observer->SendFakeDataForTesting((void*)&status); 1189} 1190 1191} // namespace content 1192