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