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/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/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" 71 #include "ui/gfx/color_profile.h" 72 #include "url/gurl.h" 73 #include "webkit/common/gpu/webgraphicscontext3d_provider_impl.h" 74 #include "webkit/common/quota/quota_types.h" 75 #include "webkit/glue/simple_webmimeregistry_impl.h" 76 #include "webkit/glue/webfileutilities_impl.h" 77 #include "webkit/glue/webkit_glue.h" 78 79 #if defined(OS_WIN) 80 #include "content/common/child_process_messages.h" 81 #include "third_party/WebKit/public/platform/win/WebSandboxSupport.h" 82 #endif 83 84 #if defined(OS_MACOSX) 85 #include "content/common/mac/font_descriptor.h" 86 #include "content/common/mac/font_loader.h" 87 #include "third_party/WebKit/public/platform/mac/WebSandboxSupport.h" 88 #endif 89 90 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 91 #include <map> 92 #include <string> 93 94 #include "base/synchronization/lock.h" 95 #include "content/common/child_process_sandbox_support_impl_linux.h" 96 #include "third_party/WebKit/public/platform/linux/WebFontFamily.h" 97 #include "third_party/WebKit/public/platform/linux/WebSandboxSupport.h" 98 #include "third_party/icu/source/common/unicode/utf16.h" 99 #endif 100 101 #if defined(OS_POSIX) 102 #include "base/file_descriptor_posix.h" 103 #endif 104 105 #if defined(OS_ANDROID) 106 #include "content/renderer/media/android/audio_decoder_android.h" 107 #endif 108 109 using blink::Platform; 110 using blink::WebAudioDevice; 111 using blink::WebBlobRegistry; 112 using blink::WebDatabaseObserver; 113 using blink::WebFileInfo; 114 using blink::WebFileSystem; 115 using blink::WebFrame; 116 using blink::WebGamepads; 117 using blink::WebIDBFactory; 118 using blink::WebMIDIAccessor; 119 using blink::WebMediaStreamCenter; 120 using blink::WebMediaStreamCenterClient; 121 using blink::WebMimeRegistry; 122 using blink::WebRTCPeerConnectionHandler; 123 using blink::WebRTCPeerConnectionHandlerClient; 124 using blink::WebStorageNamespace; 125 using blink::WebString; 126 using blink::WebURL; 127 using blink::WebVector; 128 129 namespace content { 130 131 static bool g_sandbox_enabled = true; 132 base::LazyInstance<WebGamepads>::Leaky g_test_gamepads = 133 LAZY_INSTANCE_INITIALIZER; 134 base::LazyInstance<blink::WebDeviceMotionData>::Leaky 135 g_test_device_motion_data = LAZY_INSTANCE_INITIALIZER; 136 base::LazyInstance<blink::WebDeviceOrientationData>::Leaky 137 g_test_device_orientation_data = LAZY_INSTANCE_INITIALIZER; 138 139 //------------------------------------------------------------------------------ 140 141 class RendererWebKitPlatformSupportImpl::MimeRegistry 142 : public webkit_glue::SimpleWebMimeRegistryImpl { 143 public: 144 virtual blink::WebMimeRegistry::SupportsType supportsMediaMIMEType( 145 const blink::WebString& mime_type, 146 const blink::WebString& codecs, 147 const blink::WebString& key_system); 148 virtual bool supportsMediaSourceMIMEType(const blink::WebString& mime_type, 149 const blink::WebString& codecs); 150 virtual blink::WebString mimeTypeForExtension( 151 const blink::WebString& file_extension); 152 virtual blink::WebString mimeTypeFromFile( 153 const blink::WebString& file_path); 154 }; 155 156 class RendererWebKitPlatformSupportImpl::FileUtilities 157 : public webkit_glue::WebFileUtilitiesImpl { 158 public: 159 explicit FileUtilities(ThreadSafeSender* sender) 160 : thread_safe_sender_(sender) {} 161 virtual bool getFileInfo(const WebString& path, WebFileInfo& result); 162 private: 163 bool SendSyncMessageFromAnyThread(IPC::SyncMessage* msg) const; 164 scoped_refptr<ThreadSafeSender> thread_safe_sender_; 165 }; 166 167 #if defined(OS_ANDROID) 168 // WebKit doesn't use WebSandboxSupport on android so we don't need to 169 // implement anything here. 170 class RendererWebKitPlatformSupportImpl::SandboxSupport { 171 }; 172 #else 173 class RendererWebKitPlatformSupportImpl::SandboxSupport 174 : public blink::WebSandboxSupport { 175 public: 176 virtual ~SandboxSupport() {} 177 178 #if defined(OS_WIN) 179 virtual bool ensureFontLoaded(HFONT); 180 #elif defined(OS_MACOSX) 181 virtual bool loadFont( 182 NSFont* src_font, 183 CGFontRef* container, 184 uint32* font_id); 185 #elif defined(OS_POSIX) 186 virtual void getFontFamilyForCharacter( 187 blink::WebUChar32 character, 188 const char* preferred_locale, 189 blink::WebFontFamily* family); 190 virtual void getRenderStyleForStrike( 191 const char* family, int sizeAndStyle, blink::WebFontRenderStyle* out); 192 193 private: 194 // WebKit likes to ask us for the correct font family to use for a set of 195 // unicode code points. It needs this information frequently so we cache it 196 // here. 197 base::Lock unicode_font_families_mutex_; 198 std::map<int32_t, blink::WebFontFamily> unicode_font_families_; 199 #endif 200 }; 201 #endif // defined(OS_ANDROID) 202 203 //------------------------------------------------------------------------------ 204 205 RendererWebKitPlatformSupportImpl::RendererWebKitPlatformSupportImpl() 206 : clipboard_client_(new RendererClipboardClient), 207 clipboard_(new WebClipboardImpl(clipboard_client_.get())), 208 mime_registry_(new RendererWebKitPlatformSupportImpl::MimeRegistry), 209 sudden_termination_disables_(0), 210 plugin_refresh_allowed_(true), 211 child_thread_loop_(base::MessageLoopProxy::current()) { 212 if (g_sandbox_enabled && sandboxEnabled()) { 213 sandbox_support_.reset( 214 new RendererWebKitPlatformSupportImpl::SandboxSupport); 215 } else { 216 DVLOG(1) << "Disabling sandbox support for testing."; 217 } 218 219 // ChildThread may not exist in some tests. 220 if (ChildThread::current()) { 221 sync_message_filter_ = ChildThread::current()->sync_message_filter(); 222 thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); 223 quota_message_filter_ = ChildThread::current()->quota_message_filter(); 224 blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_)); 225 web_idb_factory_.reset(new WebIDBFactoryImpl(thread_safe_sender_)); 226 web_database_observer_impl_.reset( 227 new WebDatabaseObserverImpl(sync_message_filter_)); 228 } 229 } 230 231 RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() { 232 WebFileSystemImpl::DeleteThreadSpecificInstance(); 233 } 234 235 //------------------------------------------------------------------------------ 236 237 blink::WebClipboard* RendererWebKitPlatformSupportImpl::clipboard() { 238 blink::WebClipboard* clipboard = 239 GetContentClient()->renderer()->OverrideWebClipboard(); 240 if (clipboard) 241 return clipboard; 242 return clipboard_.get(); 243 } 244 245 blink::WebMimeRegistry* RendererWebKitPlatformSupportImpl::mimeRegistry() { 246 return mime_registry_.get(); 247 } 248 249 blink::WebFileUtilities* 250 RendererWebKitPlatformSupportImpl::fileUtilities() { 251 if (!file_utilities_) { 252 file_utilities_.reset(new FileUtilities(thread_safe_sender_.get())); 253 file_utilities_->set_sandbox_enabled(sandboxEnabled()); 254 } 255 return file_utilities_.get(); 256 } 257 258 blink::WebSandboxSupport* RendererWebKitPlatformSupportImpl::sandboxSupport() { 259 #if defined(OS_ANDROID) 260 // WebKit doesn't use WebSandboxSupport on android. 261 return NULL; 262 #else 263 return sandbox_support_.get(); 264 #endif 265 } 266 267 blink::WebCookieJar* RendererWebKitPlatformSupportImpl::cookieJar() { 268 NOTREACHED() << "Use WebFrameClient::cookieJar() instead!"; 269 return NULL; 270 } 271 272 blink::WebThemeEngine* RendererWebKitPlatformSupportImpl::themeEngine() { 273 blink::WebThemeEngine* theme_engine = 274 GetContentClient()->renderer()->OverrideThemeEngine(); 275 if (theme_engine) 276 return theme_engine; 277 return WebKitPlatformSupportImpl::themeEngine(); 278 } 279 280 bool RendererWebKitPlatformSupportImpl::sandboxEnabled() { 281 // As explained in Platform.h, this function is used to decide 282 // whether to allow file system operations to come out of WebKit or not. 283 // Even if the sandbox is disabled, there's no reason why the code should 284 // act any differently...unless we're in single process mode. In which 285 // case, we have no other choice. Platform.h discourages using 286 // this switch unless absolutely necessary, so hopefully we won't end up 287 // with too many code paths being different in single-process mode. 288 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); 289 } 290 291 unsigned long long RendererWebKitPlatformSupportImpl::visitedLinkHash( 292 const char* canonical_url, 293 size_t length) { 294 return GetContentClient()->renderer()->VisitedLinkHash(canonical_url, length); 295 } 296 297 bool RendererWebKitPlatformSupportImpl::isLinkVisited( 298 unsigned long long link_hash) { 299 return GetContentClient()->renderer()->IsLinkVisited(link_hash); 300 } 301 302 blink::WebMessagePortChannel* 303 RendererWebKitPlatformSupportImpl::createMessagePortChannel() { 304 return new WebMessagePortChannelImpl(child_thread_loop_.get()); 305 } 306 307 blink::WebPrescientNetworking* 308 RendererWebKitPlatformSupportImpl::prescientNetworking() { 309 return GetContentClient()->renderer()->GetPrescientNetworking(); 310 } 311 312 bool 313 RendererWebKitPlatformSupportImpl::CheckPreparsedJsCachingEnabled() const { 314 static bool checked = false; 315 static bool result = false; 316 if (!checked) { 317 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 318 result = command_line.HasSwitch(switches::kEnablePreparsedJsCaching); 319 checked = true; 320 } 321 return result; 322 } 323 324 void RendererWebKitPlatformSupportImpl::cacheMetadata( 325 const blink::WebURL& url, 326 double response_time, 327 const char* data, 328 size_t size) { 329 if (!CheckPreparsedJsCachingEnabled()) 330 return; 331 332 // Let the browser know we generated cacheable metadata for this resource. The 333 // browser may cache it and return it on subsequent responses to speed 334 // the processing of this resource. 335 std::vector<char> copy(data, data + size); 336 RenderThread::Get()->Send( 337 new ViewHostMsg_DidGenerateCacheableMetadata(url, response_time, copy)); 338 } 339 340 WebString RendererWebKitPlatformSupportImpl::defaultLocale() { 341 return ASCIIToUTF16(RenderThread::Get()->GetLocale()); 342 } 343 344 void RendererWebKitPlatformSupportImpl::suddenTerminationChanged(bool enabled) { 345 if (enabled) { 346 // We should not get more enables than disables, but we want it to be a 347 // non-fatal error if it does happen. 348 DCHECK_GT(sudden_termination_disables_, 0); 349 sudden_termination_disables_ = std::max(sudden_termination_disables_ - 1, 350 0); 351 if (sudden_termination_disables_ != 0) 352 return; 353 } else { 354 sudden_termination_disables_++; 355 if (sudden_termination_disables_ != 1) 356 return; 357 } 358 359 RenderThread* thread = RenderThread::Get(); 360 if (thread) // NULL in unittests. 361 thread->Send(new ViewHostMsg_SuddenTerminationChanged(enabled)); 362 } 363 364 WebStorageNamespace* 365 RendererWebKitPlatformSupportImpl::createLocalStorageNamespace() { 366 return new WebStorageNamespaceImpl(); 367 } 368 369 370 //------------------------------------------------------------------------------ 371 372 WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() { 373 return web_idb_factory_.get(); 374 } 375 376 //------------------------------------------------------------------------------ 377 378 WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() { 379 return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); 380 } 381 382 //------------------------------------------------------------------------------ 383 384 WebMimeRegistry::SupportsType 385 RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaMIMEType( 386 const WebString& mime_type, 387 const WebString& codecs, 388 const WebString& key_system) { 389 const std::string mime_type_ascii = ToASCIIOrEmpty(mime_type); 390 // Not supporting the container is a flat-out no. 391 if (!net::IsSupportedMediaMimeType(mime_type_ascii)) 392 return IsNotSupported; 393 394 if (!key_system.isEmpty()) { 395 // Check whether the key system is supported with the mime_type and codecs. 396 397 std::vector<std::string> strict_codecs; 398 bool strip_suffix = !net::IsStrictMediaMimeType(mime_type_ascii); 399 net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, strip_suffix); 400 401 if (!IsSupportedKeySystemWithMediaMimeType( 402 mime_type_ascii, strict_codecs, ToASCIIOrEmpty(key_system))) 403 return IsNotSupported; 404 405 // Continue processing the mime_type and codecs. 406 } 407 408 // Check list of strict codecs to see if it is supported. 409 if (net::IsStrictMediaMimeType(mime_type_ascii)) { 410 // We support the container, but no codecs were specified. 411 if (codecs.isNull()) 412 return MayBeSupported; 413 414 // Check if the codecs are a perfect match. 415 std::vector<std::string> strict_codecs; 416 net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, false); 417 if (!net::IsSupportedStrictMediaMimeType(mime_type_ascii, strict_codecs)) 418 return IsNotSupported; 419 420 // Good to go! 421 return IsSupported; 422 } 423 424 // If we don't recognize the codec, it's possible we support it. 425 std::vector<std::string> parsed_codecs; 426 net::ParseCodecString(ToASCIIOrEmpty(codecs), &parsed_codecs, true); 427 if (!net::AreSupportedMediaCodecs(parsed_codecs)) 428 return MayBeSupported; 429 430 // Otherwise we have a perfect match. 431 return IsSupported; 432 } 433 434 bool 435 RendererWebKitPlatformSupportImpl::MimeRegistry::supportsMediaSourceMIMEType( 436 const blink::WebString& mime_type, 437 const WebString& codecs) { 438 const std::string mime_type_ascii = ToASCIIOrEmpty(mime_type); 439 std::vector<std::string> parsed_codec_ids; 440 net::ParseCodecString(ToASCIIOrEmpty(codecs), &parsed_codec_ids, false); 441 if (mime_type_ascii.empty()) 442 return false; 443 return media::StreamParserFactory::IsTypeSupported( 444 mime_type_ascii, parsed_codec_ids); 445 } 446 447 WebString 448 RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeForExtension( 449 const WebString& file_extension) { 450 if (IsPluginProcess()) 451 return SimpleWebMimeRegistryImpl::mimeTypeForExtension(file_extension); 452 453 // The sandbox restricts our access to the registry, so we need to proxy 454 // these calls over to the browser process. 455 std::string mime_type; 456 RenderThread::Get()->Send( 457 new MimeRegistryMsg_GetMimeTypeFromExtension( 458 base::FilePath::FromUTF16Unsafe(file_extension).value(), &mime_type)); 459 return ASCIIToUTF16(mime_type); 460 } 461 462 WebString RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeFromFile( 463 const WebString& file_path) { 464 if (IsPluginProcess()) 465 return SimpleWebMimeRegistryImpl::mimeTypeFromFile(file_path); 466 467 // The sandbox restricts our access to the registry, so we need to proxy 468 // these calls over to the browser process. 469 std::string mime_type; 470 RenderThread::Get()->Send(new MimeRegistryMsg_GetMimeTypeFromFile( 471 base::FilePath::FromUTF16Unsafe(file_path), 472 &mime_type)); 473 return ASCIIToUTF16(mime_type); 474 } 475 476 //------------------------------------------------------------------------------ 477 478 bool RendererWebKitPlatformSupportImpl::FileUtilities::getFileInfo( 479 const WebString& path, 480 WebFileInfo& web_file_info) { 481 base::PlatformFileInfo file_info; 482 base::PlatformFileError status; 483 if (!SendSyncMessageFromAnyThread(new FileUtilitiesMsg_GetFileInfo( 484 base::FilePath::FromUTF16Unsafe(path), &file_info, &status)) || 485 status != base::PLATFORM_FILE_OK) { 486 return false; 487 } 488 webkit_glue::PlatformFileInfoToWebFileInfo(file_info, &web_file_info); 489 web_file_info.platformPath = path; 490 return true; 491 } 492 493 bool RendererWebKitPlatformSupportImpl::FileUtilities:: 494 SendSyncMessageFromAnyThread(IPC::SyncMessage* msg) const { 495 base::TimeTicks begin = base::TimeTicks::Now(); 496 const bool success = thread_safe_sender_->Send(msg); 497 base::TimeDelta delta = base::TimeTicks::Now() - begin; 498 UMA_HISTOGRAM_TIMES("RendererSyncIPC.ElapsedTime", delta); 499 return success; 500 } 501 502 //------------------------------------------------------------------------------ 503 504 #if defined(OS_WIN) 505 506 bool RendererWebKitPlatformSupportImpl::SandboxSupport::ensureFontLoaded( 507 HFONT font) { 508 LOGFONT logfont; 509 GetObject(font, sizeof(LOGFONT), &logfont); 510 RenderThread::Get()->PreCacheFont(logfont); 511 return true; 512 } 513 514 #elif defined(OS_MACOSX) 515 516 bool RendererWebKitPlatformSupportImpl::SandboxSupport::loadFont( 517 NSFont* src_font, CGFontRef* out, uint32* font_id) { 518 uint32 font_data_size; 519 FontDescriptor src_font_descriptor(src_font); 520 base::SharedMemoryHandle font_data; 521 if (!RenderThread::Get()->Send(new ViewHostMsg_LoadFont( 522 src_font_descriptor, &font_data_size, &font_data, font_id))) { 523 *out = NULL; 524 *font_id = 0; 525 return false; 526 } 527 528 if (font_data_size == 0 || font_data == base::SharedMemory::NULLHandle() || 529 *font_id == 0) { 530 LOG(ERROR) << "Bad response from ViewHostMsg_LoadFont() for " << 531 src_font_descriptor.font_name; 532 *out = NULL; 533 *font_id = 0; 534 return false; 535 } 536 537 // TODO(jeremy): Need to call back into WebKit to make sure that the font 538 // isn't already activated, based on the font id. If it's already 539 // activated, don't reactivate it here - crbug.com/72727 . 540 541 return FontLoader::CGFontRefFromBuffer(font_data, font_data_size, out); 542 } 543 544 #elif defined(OS_ANDROID) 545 546 // WebKit doesn't use WebSandboxSupport on android so we don't need to 547 // implement anything here. This is cleaner to support than excluding the 548 // whole class for android. 549 550 #elif defined(OS_POSIX) 551 552 void 553 RendererWebKitPlatformSupportImpl::SandboxSupport::getFontFamilyForCharacter( 554 blink::WebUChar32 character, 555 const char* preferred_locale, 556 blink::WebFontFamily* family) { 557 base::AutoLock lock(unicode_font_families_mutex_); 558 const std::map<int32_t, blink::WebFontFamily>::const_iterator iter = 559 unicode_font_families_.find(character); 560 if (iter != unicode_font_families_.end()) { 561 family->name = iter->second.name; 562 family->isBold = iter->second.isBold; 563 family->isItalic = iter->second.isItalic; 564 return; 565 } 566 567 GetFontFamilyForCharacter(character, preferred_locale, family); 568 unicode_font_families_.insert(std::make_pair(character, *family)); 569 } 570 571 void 572 RendererWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike( 573 const char* family, int sizeAndStyle, blink::WebFontRenderStyle* out) { 574 GetRenderStyleForStrike(family, sizeAndStyle, out); 575 } 576 577 #endif 578 579 //------------------------------------------------------------------------------ 580 581 Platform::FileHandle 582 RendererWebKitPlatformSupportImpl::databaseOpenFile( 583 const WebString& vfs_file_name, int desired_flags) { 584 return DatabaseUtil::DatabaseOpenFile( 585 vfs_file_name, desired_flags, sync_message_filter_.get()); 586 } 587 588 int RendererWebKitPlatformSupportImpl::databaseDeleteFile( 589 const WebString& vfs_file_name, bool sync_dir) { 590 return DatabaseUtil::DatabaseDeleteFile( 591 vfs_file_name, sync_dir, sync_message_filter_.get()); 592 } 593 594 long RendererWebKitPlatformSupportImpl::databaseGetFileAttributes( 595 const WebString& vfs_file_name) { 596 return DatabaseUtil::DatabaseGetFileAttributes(vfs_file_name, 597 sync_message_filter_.get()); 598 } 599 600 long long RendererWebKitPlatformSupportImpl::databaseGetFileSize( 601 const WebString& vfs_file_name) { 602 return DatabaseUtil::DatabaseGetFileSize(vfs_file_name, 603 sync_message_filter_.get()); 604 } 605 606 long long RendererWebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin( 607 const WebString& origin_identifier) { 608 return DatabaseUtil::DatabaseGetSpaceAvailable(origin_identifier, 609 sync_message_filter_.get()); 610 } 611 612 bool RendererWebKitPlatformSupportImpl::canAccelerate2dCanvas() { 613 RenderThreadImpl* thread = RenderThreadImpl::current(); 614 GpuChannelHost* host = thread->EstablishGpuChannelSync( 615 CAUSE_FOR_GPU_LAUNCH_CANVAS_2D); 616 if (!host) 617 return false; 618 619 return host->gpu_info().SupportsAccelerated2dCanvas(); 620 } 621 622 bool RendererWebKitPlatformSupportImpl::isThreadedCompositingEnabled() { 623 return !!RenderThreadImpl::current()->compositor_message_loop_proxy().get(); 624 } 625 626 double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() { 627 RenderThreadImpl* thread = RenderThreadImpl::current(); 628 return thread->GetAudioHardwareConfig()->GetOutputSampleRate(); 629 } 630 631 size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() { 632 RenderThreadImpl* thread = RenderThreadImpl::current(); 633 return thread->GetAudioHardwareConfig()->GetOutputBufferSize(); 634 } 635 636 unsigned RendererWebKitPlatformSupportImpl::audioHardwareOutputChannels() { 637 RenderThreadImpl* thread = RenderThreadImpl::current(); 638 return thread->GetAudioHardwareConfig()->GetOutputChannels(); 639 } 640 641 WebDatabaseObserver* RendererWebKitPlatformSupportImpl::databaseObserver() { 642 return web_database_observer_impl_.get(); 643 } 644 645 // TODO(crogers): remove deprecated API as soon as WebKit calls new API. 646 WebAudioDevice* 647 RendererWebKitPlatformSupportImpl::createAudioDevice( 648 size_t buffer_size, 649 unsigned channels, 650 double sample_rate, 651 WebAudioDevice::RenderCallback* callback) { 652 return createAudioDevice( 653 buffer_size, 0, channels, sample_rate, callback, "default"); 654 } 655 656 // TODO(crogers): remove deprecated API as soon as WebKit calls new API. 657 WebAudioDevice* 658 RendererWebKitPlatformSupportImpl::createAudioDevice( 659 size_t buffer_size, 660 unsigned input_channels, 661 unsigned channels, 662 double sample_rate, 663 WebAudioDevice::RenderCallback* callback) { 664 return createAudioDevice( 665 buffer_size, input_channels, channels, sample_rate, callback, "default"); 666 } 667 668 WebAudioDevice* 669 RendererWebKitPlatformSupportImpl::createAudioDevice( 670 size_t buffer_size, 671 unsigned input_channels, 672 unsigned channels, 673 double sample_rate, 674 WebAudioDevice::RenderCallback* callback, 675 const blink::WebString& input_device_id) { 676 // Use a mock for testing. 677 blink::WebAudioDevice* mock_device = 678 GetContentClient()->renderer()->OverrideCreateAudioDevice(sample_rate); 679 if (mock_device) 680 return mock_device; 681 682 // The |channels| does not exactly identify the channel layout of the 683 // device. The switch statement below assigns a best guess to the channel 684 // layout based on number of channels. 685 // TODO(crogers): WebKit should give the channel layout instead of the hard 686 // channel count. 687 media::ChannelLayout layout = media::CHANNEL_LAYOUT_UNSUPPORTED; 688 switch (channels) { 689 case 1: 690 layout = media::CHANNEL_LAYOUT_MONO; 691 break; 692 case 2: 693 layout = media::CHANNEL_LAYOUT_STEREO; 694 break; 695 case 3: 696 layout = media::CHANNEL_LAYOUT_2_1; 697 break; 698 case 4: 699 layout = media::CHANNEL_LAYOUT_4_0; 700 break; 701 case 5: 702 layout = media::CHANNEL_LAYOUT_5_0; 703 break; 704 case 6: 705 layout = media::CHANNEL_LAYOUT_5_1; 706 break; 707 case 7: 708 layout = media::CHANNEL_LAYOUT_7_0; 709 break; 710 case 8: 711 layout = media::CHANNEL_LAYOUT_7_1; 712 break; 713 default: 714 layout = media::CHANNEL_LAYOUT_STEREO; 715 } 716 717 int session_id = 0; 718 if (input_device_id.isNull() || 719 !base::StringToInt(UTF16ToUTF8(input_device_id), &session_id)) { 720 if (input_channels > 0) 721 DLOG(WARNING) << "createAudioDevice(): request for audio input ignored"; 722 723 input_channels = 0; 724 } 725 726 media::AudioParameters params( 727 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 728 layout, input_channels, 729 static_cast<int>(sample_rate), 16, buffer_size, 730 media::AudioParameters::NO_EFFECTS); 731 732 return new RendererWebAudioDeviceImpl(params, callback, session_id); 733 } 734 735 #if defined(OS_ANDROID) 736 bool RendererWebKitPlatformSupportImpl::loadAudioResource( 737 blink::WebAudioBus* destination_bus, const char* audio_file_data, 738 size_t data_size, double sample_rate) { 739 return DecodeAudioFileData(destination_bus, 740 audio_file_data, 741 data_size, 742 sample_rate, 743 thread_safe_sender_); 744 } 745 #else 746 bool RendererWebKitPlatformSupportImpl::loadAudioResource( 747 blink::WebAudioBus* destination_bus, const char* audio_file_data, 748 size_t data_size, double sample_rate) { 749 return DecodeAudioFileData( 750 destination_bus, audio_file_data, data_size, sample_rate); 751 } 752 #endif // defined(OS_ANDROID) 753 754 //------------------------------------------------------------------------------ 755 756 blink::WebContentDecryptionModule* 757 RendererWebKitPlatformSupportImpl::createContentDecryptionModule( 758 const blink::WebString& key_system) { 759 return WebContentDecryptionModuleImpl::Create(key_system); 760 } 761 762 //------------------------------------------------------------------------------ 763 764 blink::WebMIDIAccessor* 765 RendererWebKitPlatformSupportImpl::createMIDIAccessor( 766 blink::WebMIDIAccessorClient* client) { 767 blink::WebMIDIAccessor* accessor = 768 GetContentClient()->renderer()->OverrideCreateMIDIAccessor(client); 769 if (accessor) 770 return accessor; 771 772 return new RendererWebMIDIAccessorImpl(client); 773 } 774 775 void RendererWebKitPlatformSupportImpl::getPluginList( 776 bool refresh, 777 blink::WebPluginListBuilder* builder) { 778 #if defined(ENABLE_PLUGINS) 779 std::vector<WebPluginInfo> plugins; 780 if (!plugin_refresh_allowed_) 781 refresh = false; 782 RenderThread::Get()->Send( 783 new ViewHostMsg_GetPlugins(refresh, &plugins)); 784 for (size_t i = 0; i < plugins.size(); ++i) { 785 const WebPluginInfo& plugin = plugins[i]; 786 787 builder->addPlugin( 788 plugin.name, plugin.desc, 789 plugin.path.BaseName().AsUTF16Unsafe()); 790 791 for (size_t j = 0; j < plugin.mime_types.size(); ++j) { 792 const WebPluginMimeType& mime_type = plugin.mime_types[j]; 793 794 builder->addMediaTypeToLastPlugin( 795 WebString::fromUTF8(mime_type.mime_type), mime_type.description); 796 797 for (size_t k = 0; k < mime_type.file_extensions.size(); ++k) { 798 builder->addFileExtensionToLastMediaType( 799 WebString::fromUTF8(mime_type.file_extensions[k])); 800 } 801 } 802 } 803 #endif 804 } 805 806 //------------------------------------------------------------------------------ 807 808 blink::WebPublicSuffixList* 809 RendererWebKitPlatformSupportImpl::publicSuffixList() { 810 return &public_suffix_list_; 811 } 812 813 //------------------------------------------------------------------------------ 814 815 blink::WebString 816 RendererWebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( 817 unsigned key_size_index, 818 const blink::WebString& challenge, 819 const blink::WebURL& url) { 820 std::string signed_public_key; 821 RenderThread::Get()->Send(new ViewHostMsg_Keygen( 822 static_cast<uint32>(key_size_index), 823 challenge.utf8(), 824 GURL(url), 825 &signed_public_key)); 826 return WebString::fromUTF8(signed_public_key); 827 } 828 829 //------------------------------------------------------------------------------ 830 831 void RendererWebKitPlatformSupportImpl::screenColorProfile( 832 WebVector<char>* to_profile) { 833 #if defined(OS_WIN) 834 // On Windows screen color profile is only available in the browser. 835 std::vector<char> profile; 836 RenderThread::Get()->Send( 837 new ViewHostMsg_GetMonitorColorProfile(&profile)); 838 *to_profile = profile; 839 #else 840 // On other platforms color profile can be obtained directly. 841 gfx::ColorProfile profile; 842 *to_profile = profile.profile(); 843 #endif 844 } 845 846 //------------------------------------------------------------------------------ 847 848 WebBlobRegistry* RendererWebKitPlatformSupportImpl::blobRegistry() { 849 // blob_registry_ can be NULL when running some tests. 850 return blob_registry_.get(); 851 } 852 853 //------------------------------------------------------------------------------ 854 855 void RendererWebKitPlatformSupportImpl::sampleGamepads(WebGamepads& gamepads) { 856 if (g_test_gamepads == 0) { 857 RenderThreadImpl::current()->SampleGamepads(&gamepads); 858 } else { 859 gamepads = g_test_gamepads.Get(); 860 } 861 } 862 863 blink::WebString RendererWebKitPlatformSupportImpl::userAgent( 864 const blink::WebURL& url) { 865 return WebKitPlatformSupportImpl::userAgent(url); 866 } 867 868 //------------------------------------------------------------------------------ 869 870 WebRTCPeerConnectionHandler* 871 RendererWebKitPlatformSupportImpl::createRTCPeerConnectionHandler( 872 WebRTCPeerConnectionHandlerClient* client) { 873 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 874 DCHECK(render_thread); 875 if (!render_thread) 876 return NULL; 877 878 #if defined(ENABLE_WEBRTC) 879 WebRTCPeerConnectionHandler* peer_connection_handler = 880 GetContentClient()->renderer()->OverrideCreateWebRTCPeerConnectionHandler( 881 client); 882 if (peer_connection_handler) 883 return peer_connection_handler; 884 885 MediaStreamDependencyFactory* rtc_dependency_factory = 886 render_thread->GetMediaStreamDependencyFactory(); 887 return rtc_dependency_factory->CreateRTCPeerConnectionHandler(client); 888 #else 889 return NULL; 890 #endif // defined(ENABLE_WEBRTC) 891 } 892 893 //------------------------------------------------------------------------------ 894 895 WebMediaStreamCenter* 896 RendererWebKitPlatformSupportImpl::createMediaStreamCenter( 897 WebMediaStreamCenterClient* client) { 898 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 899 DCHECK(render_thread); 900 if (!render_thread) 901 return NULL; 902 return render_thread->CreateMediaStreamCenter(client); 903 } 904 905 // static 906 bool RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting( 907 bool enable) { 908 bool was_enabled = g_sandbox_enabled; 909 g_sandbox_enabled = enable; 910 return was_enabled; 911 } 912 913 // static 914 void RendererWebKitPlatformSupportImpl::SetMockGamepadsForTesting( 915 const WebGamepads& pads) { 916 g_test_gamepads.Get() = pads; 917 } 918 919 //------------------------------------------------------------------------------ 920 921 blink::WebSpeechSynthesizer* 922 RendererWebKitPlatformSupportImpl::createSpeechSynthesizer( 923 blink::WebSpeechSynthesizerClient* client) { 924 return GetContentClient()->renderer()->OverrideSpeechSynthesizer(client); 925 } 926 927 //------------------------------------------------------------------------------ 928 929 bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes( 930 size_t* private_bytes, size_t* shared_bytes) { 931 content::RenderThread::Get()->Send( 932 new ViewHostMsg_GetProcessMemorySizes(private_bytes, shared_bytes)); 933 return true; 934 } 935 936 //------------------------------------------------------------------------------ 937 938 blink::WebGraphicsContext3D* 939 RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D( 940 const blink::WebGraphicsContext3D::Attributes& attributes) { 941 if (!RenderThreadImpl::current()) 942 return NULL; 943 944 scoped_refptr<GpuChannelHost> gpu_channel_host( 945 RenderThreadImpl::current()->EstablishGpuChannelSync( 946 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)); 947 948 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits; 949 950 CommandLine* command_line = CommandLine::ForCurrentProcess(); 951 if (command_line->HasSwitch(switches::kWebGLCommandBufferSizeKb)) { 952 std::string size_string = command_line->GetSwitchValueASCII( 953 switches::kWebGLCommandBufferSizeKb); 954 size_t buffer_size_kb; 955 if (base::StringToSizeT(size_string, &buffer_size_kb)) { 956 limits.command_buffer_size = buffer_size_kb * 1024; 957 } 958 } 959 960 return WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 961 gpu_channel_host.get(), 962 attributes, 963 GURL(attributes.topDocumentURL), 964 limits); 965 } 966 967 //------------------------------------------------------------------------------ 968 969 blink::WebGraphicsContext3DProvider* RendererWebKitPlatformSupportImpl:: 970 createSharedOffscreenGraphicsContext3DProvider() { 971 scoped_refptr<cc::ContextProvider> provider = 972 RenderThreadImpl::current()->SharedMainThreadContextProvider(); 973 if (!provider) 974 return NULL; 975 return new webkit::gpu::WebGraphicsContext3DProviderImpl(provider); 976 } 977 978 //------------------------------------------------------------------------------ 979 980 blink::WebCompositorSupport* 981 RendererWebKitPlatformSupportImpl::compositorSupport() { 982 return &compositor_support_; 983 } 984 985 //------------------------------------------------------------------------------ 986 987 blink::WebString RendererWebKitPlatformSupportImpl::convertIDNToUnicode( 988 const blink::WebString& host, 989 const blink::WebString& languages) { 990 return net::IDNToUnicode(host.utf8(), languages.utf8()); 991 } 992 993 //------------------------------------------------------------------------------ 994 995 void RendererWebKitPlatformSupportImpl::setDeviceMotionListener( 996 blink::WebDeviceMotionListener* listener) { 997 if (g_test_device_motion_data == 0) { 998 if (!device_motion_event_pump_) { 999 device_motion_event_pump_.reset(new DeviceMotionEventPump); 1000 device_motion_event_pump_->Attach(RenderThreadImpl::current()); 1001 } 1002 device_motion_event_pump_->SetListener(listener); 1003 } else if (listener) { 1004 // Testing mode: just echo the test data to the listener. 1005 base::MessageLoopProxy::current()->PostTask( 1006 FROM_HERE, 1007 base::Bind(&blink::WebDeviceMotionListener::didChangeDeviceMotion, 1008 base::Unretained(listener), 1009 g_test_device_motion_data.Get())); 1010 } 1011 } 1012 1013 // static 1014 void RendererWebKitPlatformSupportImpl::SetMockDeviceMotionDataForTesting( 1015 const blink::WebDeviceMotionData& data) { 1016 g_test_device_motion_data.Get() = data; 1017 } 1018 1019 //------------------------------------------------------------------------------ 1020 1021 void RendererWebKitPlatformSupportImpl::setDeviceOrientationListener( 1022 blink::WebDeviceOrientationListener* listener) { 1023 if (g_test_device_orientation_data == 0) { 1024 if (!device_orientation_event_pump_) { 1025 device_orientation_event_pump_.reset(new DeviceOrientationEventPump); 1026 device_orientation_event_pump_->Attach(RenderThreadImpl::current()); 1027 } 1028 device_orientation_event_pump_->SetListener(listener); 1029 } else if (listener) { 1030 // Testing mode: just echo the test data to the listener. 1031 base::MessageLoopProxy::current()->PostTask( 1032 FROM_HERE, 1033 base::Bind( 1034 &blink::WebDeviceOrientationListener::didChangeDeviceOrientation, 1035 base::Unretained(listener), 1036 g_test_device_orientation_data.Get())); 1037 } 1038 } 1039 1040 // static 1041 void RendererWebKitPlatformSupportImpl::SetMockDeviceOrientationDataForTesting( 1042 const blink::WebDeviceOrientationData& data) { 1043 g_test_device_orientation_data.Get() = data; 1044 } 1045 1046 //------------------------------------------------------------------------------ 1047 1048 blink::WebCrypto* RendererWebKitPlatformSupportImpl::crypto() { 1049 if (!web_crypto_) 1050 web_crypto_.reset(new WebCryptoImpl()); 1051 return web_crypto_.get(); 1052 1053 } 1054 1055 //------------------------------------------------------------------------------ 1056 1057 void RendererWebKitPlatformSupportImpl::vibrate(unsigned int milliseconds) { 1058 RenderThread::Get()->Send( 1059 new ViewHostMsg_Vibrate(base::checked_numeric_cast<int64>(milliseconds))); 1060 } 1061 1062 void RendererWebKitPlatformSupportImpl::cancelVibration() { 1063 RenderThread::Get()->Send(new ViewHostMsg_CancelVibration()); 1064 } 1065 1066 //------------------------------------------------------------------------------ 1067 1068 void RendererWebKitPlatformSupportImpl::queryStorageUsageAndQuota( 1069 const blink::WebURL& storage_partition, 1070 blink::WebStorageQuotaType type, 1071 blink::WebStorageQuotaCallbacks* callbacks) { 1072 if (!thread_safe_sender_.get() || !quota_message_filter_.get()) 1073 return; 1074 QuotaDispatcher::ThreadSpecificInstance( 1075 thread_safe_sender_.get(), 1076 quota_message_filter_.get())->QueryStorageUsageAndQuota( 1077 storage_partition, 1078 static_cast<quota::StorageType>(type), 1079 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks)); 1080 } 1081 1082 } // namespace content 1083