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 109using blink::Platform; 110using blink::WebAudioDevice; 111using blink::WebBlobRegistry; 112using blink::WebDatabaseObserver; 113using blink::WebFileInfo; 114using blink::WebFileSystem; 115using blink::WebFrame; 116using blink::WebGamepads; 117using blink::WebIDBFactory; 118using blink::WebMIDIAccessor; 119using blink::WebMediaStreamCenter; 120using blink::WebMediaStreamCenterClient; 121using blink::WebMimeRegistry; 122using blink::WebRTCPeerConnectionHandler; 123using blink::WebRTCPeerConnectionHandlerClient; 124using blink::WebStorageNamespace; 125using blink::WebString; 126using blink::WebURL; 127using blink::WebVector; 128 129namespace content { 130 131static bool g_sandbox_enabled = true; 132base::LazyInstance<WebGamepads>::Leaky g_test_gamepads = 133 LAZY_INSTANCE_INITIALIZER; 134base::LazyInstance<blink::WebDeviceMotionData>::Leaky 135 g_test_device_motion_data = LAZY_INSTANCE_INITIALIZER; 136base::LazyInstance<blink::WebDeviceOrientationData>::Leaky 137 g_test_device_orientation_data = LAZY_INSTANCE_INITIALIZER; 138 139//------------------------------------------------------------------------------ 140 141class 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 156class 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. 170class RendererWebKitPlatformSupportImpl::SandboxSupport { 171}; 172#else 173class 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 205RendererWebKitPlatformSupportImpl::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 231RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() { 232 WebFileSystemImpl::DeleteThreadSpecificInstance(); 233} 234 235//------------------------------------------------------------------------------ 236 237blink::WebClipboard* RendererWebKitPlatformSupportImpl::clipboard() { 238 blink::WebClipboard* clipboard = 239 GetContentClient()->renderer()->OverrideWebClipboard(); 240 if (clipboard) 241 return clipboard; 242 return clipboard_.get(); 243} 244 245blink::WebMimeRegistry* RendererWebKitPlatformSupportImpl::mimeRegistry() { 246 return mime_registry_.get(); 247} 248 249blink::WebFileUtilities* 250RendererWebKitPlatformSupportImpl::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 258blink::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 267blink::WebCookieJar* RendererWebKitPlatformSupportImpl::cookieJar() { 268 NOTREACHED() << "Use WebFrameClient::cookieJar() instead!"; 269 return NULL; 270} 271 272blink::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 280bool 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 291unsigned long long RendererWebKitPlatformSupportImpl::visitedLinkHash( 292 const char* canonical_url, 293 size_t length) { 294 return GetContentClient()->renderer()->VisitedLinkHash(canonical_url, length); 295} 296 297bool RendererWebKitPlatformSupportImpl::isLinkVisited( 298 unsigned long long link_hash) { 299 return GetContentClient()->renderer()->IsLinkVisited(link_hash); 300} 301 302blink::WebMessagePortChannel* 303RendererWebKitPlatformSupportImpl::createMessagePortChannel() { 304 return new WebMessagePortChannelImpl(child_thread_loop_.get()); 305} 306 307blink::WebPrescientNetworking* 308RendererWebKitPlatformSupportImpl::prescientNetworking() { 309 return GetContentClient()->renderer()->GetPrescientNetworking(); 310} 311 312bool 313RendererWebKitPlatformSupportImpl::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 324void 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 340WebString RendererWebKitPlatformSupportImpl::defaultLocale() { 341 return ASCIIToUTF16(RenderThread::Get()->GetLocale()); 342} 343 344void 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 364WebStorageNamespace* 365RendererWebKitPlatformSupportImpl::createLocalStorageNamespace() { 366 return new WebStorageNamespaceImpl(); 367} 368 369 370//------------------------------------------------------------------------------ 371 372WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() { 373 return web_idb_factory_.get(); 374} 375 376//------------------------------------------------------------------------------ 377 378WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() { 379 return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); 380} 381 382//------------------------------------------------------------------------------ 383 384WebMimeRegistry::SupportsType 385RendererWebKitPlatformSupportImpl::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 434bool 435RendererWebKitPlatformSupportImpl::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 447WebString 448RendererWebKitPlatformSupportImpl::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 462WebString 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 478bool 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 493bool RendererWebKitPlatformSupportImpl::FileUtilities:: 494SendSyncMessageFromAnyThread(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 506bool 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 516bool 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 552void 553RendererWebKitPlatformSupportImpl::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 571void 572RendererWebKitPlatformSupportImpl::SandboxSupport::getRenderStyleForStrike( 573 const char* family, int sizeAndStyle, blink::WebFontRenderStyle* out) { 574 GetRenderStyleForStrike(family, sizeAndStyle, out); 575} 576 577#endif 578 579//------------------------------------------------------------------------------ 580 581Platform::FileHandle 582RendererWebKitPlatformSupportImpl::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 588int 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 594long RendererWebKitPlatformSupportImpl::databaseGetFileAttributes( 595 const WebString& vfs_file_name) { 596 return DatabaseUtil::DatabaseGetFileAttributes(vfs_file_name, 597 sync_message_filter_.get()); 598} 599 600long long RendererWebKitPlatformSupportImpl::databaseGetFileSize( 601 const WebString& vfs_file_name) { 602 return DatabaseUtil::DatabaseGetFileSize(vfs_file_name, 603 sync_message_filter_.get()); 604} 605 606long long RendererWebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin( 607 const WebString& origin_identifier) { 608 return DatabaseUtil::DatabaseGetSpaceAvailable(origin_identifier, 609 sync_message_filter_.get()); 610} 611 612bool 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 622bool RendererWebKitPlatformSupportImpl::isThreadedCompositingEnabled() { 623 return !!RenderThreadImpl::current()->compositor_message_loop_proxy().get(); 624} 625 626double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() { 627 RenderThreadImpl* thread = RenderThreadImpl::current(); 628 return thread->GetAudioHardwareConfig()->GetOutputSampleRate(); 629} 630 631size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() { 632 RenderThreadImpl* thread = RenderThreadImpl::current(); 633 return thread->GetAudioHardwareConfig()->GetOutputBufferSize(); 634} 635 636unsigned RendererWebKitPlatformSupportImpl::audioHardwareOutputChannels() { 637 RenderThreadImpl* thread = RenderThreadImpl::current(); 638 return thread->GetAudioHardwareConfig()->GetOutputChannels(); 639} 640 641WebDatabaseObserver* RendererWebKitPlatformSupportImpl::databaseObserver() { 642 return web_database_observer_impl_.get(); 643} 644 645// TODO(crogers): remove deprecated API as soon as WebKit calls new API. 646WebAudioDevice* 647RendererWebKitPlatformSupportImpl::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. 657WebAudioDevice* 658RendererWebKitPlatformSupportImpl::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 668WebAudioDevice* 669RendererWebKitPlatformSupportImpl::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) 736bool 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 746bool 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 756blink::WebContentDecryptionModule* 757RendererWebKitPlatformSupportImpl::createContentDecryptionModule( 758 const blink::WebString& key_system) { 759 return WebContentDecryptionModuleImpl::Create(key_system); 760} 761 762//------------------------------------------------------------------------------ 763 764blink::WebMIDIAccessor* 765RendererWebKitPlatformSupportImpl::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 775void 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 808blink::WebPublicSuffixList* 809RendererWebKitPlatformSupportImpl::publicSuffixList() { 810 return &public_suffix_list_; 811} 812 813//------------------------------------------------------------------------------ 814 815blink::WebString 816RendererWebKitPlatformSupportImpl::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 831void 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 848WebBlobRegistry* RendererWebKitPlatformSupportImpl::blobRegistry() { 849 // blob_registry_ can be NULL when running some tests. 850 return blob_registry_.get(); 851} 852 853//------------------------------------------------------------------------------ 854 855void 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 863blink::WebString RendererWebKitPlatformSupportImpl::userAgent( 864 const blink::WebURL& url) { 865 return WebKitPlatformSupportImpl::userAgent(url); 866} 867 868//------------------------------------------------------------------------------ 869 870WebRTCPeerConnectionHandler* 871RendererWebKitPlatformSupportImpl::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 895WebMediaStreamCenter* 896RendererWebKitPlatformSupportImpl::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 906bool 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 914void RendererWebKitPlatformSupportImpl::SetMockGamepadsForTesting( 915 const WebGamepads& pads) { 916 g_test_gamepads.Get() = pads; 917} 918 919//------------------------------------------------------------------------------ 920 921blink::WebSpeechSynthesizer* 922RendererWebKitPlatformSupportImpl::createSpeechSynthesizer( 923 blink::WebSpeechSynthesizerClient* client) { 924 return GetContentClient()->renderer()->OverrideSpeechSynthesizer(client); 925} 926 927//------------------------------------------------------------------------------ 928 929bool 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 938blink::WebGraphicsContext3D* 939RendererWebKitPlatformSupportImpl::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 969blink::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 980blink::WebCompositorSupport* 981RendererWebKitPlatformSupportImpl::compositorSupport() { 982 return &compositor_support_; 983} 984 985//------------------------------------------------------------------------------ 986 987blink::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 995void 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 1014void RendererWebKitPlatformSupportImpl::SetMockDeviceMotionDataForTesting( 1015 const blink::WebDeviceMotionData& data) { 1016 g_test_device_motion_data.Get() = data; 1017} 1018 1019//------------------------------------------------------------------------------ 1020 1021void 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 1041void RendererWebKitPlatformSupportImpl::SetMockDeviceOrientationDataForTesting( 1042 const blink::WebDeviceOrientationData& data) { 1043 g_test_device_orientation_data.Get() = data; 1044} 1045 1046//------------------------------------------------------------------------------ 1047 1048blink::WebCrypto* RendererWebKitPlatformSupportImpl::crypto() { 1049 if (!web_crypto_) 1050 web_crypto_.reset(new WebCryptoImpl()); 1051 return web_crypto_.get(); 1052 1053} 1054 1055//------------------------------------------------------------------------------ 1056 1057void RendererWebKitPlatformSupportImpl::vibrate(unsigned int milliseconds) { 1058 RenderThread::Get()->Send( 1059 new ViewHostMsg_Vibrate(base::checked_numeric_cast<int64>(milliseconds))); 1060} 1061 1062void RendererWebKitPlatformSupportImpl::cancelVibration() { 1063 RenderThread::Get()->Send(new ViewHostMsg_CancelVibration()); 1064} 1065 1066//------------------------------------------------------------------------------ 1067 1068void 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