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