1 // Copyright 2014 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.
5 #include "mojo/services/html_viewer/blink_platform_impl.h"
9 #include "base/rand_util.h"
10 #include "base/stl_util.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/platform_thread.h"
13 #include "base/time/time.h"
14 #include "mojo/services/html_viewer/webthread_impl.h"
15 #include "net/base/data_url.h"
16 #include "net/base/mime_util.h"
17 #include "net/base/net_errors.h"
18 #include "third_party/WebKit/public/platform/WebWaitableEvent.h"
23 // TODO(darin): Figure out what our UA should really be.
24 const char kUserAgentString
[] =
25 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
26 "Chrome/35.0.1916.153 Safari/537.36";
28 class WebWaitableEventImpl
: public blink::WebWaitableEvent
{
30 WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {}
31 virtual ~WebWaitableEventImpl() {}
33 virtual void wait() { impl_
->Wait(); }
34 virtual void signal() { impl_
->Signal(); }
36 base::WaitableEvent
* impl() {
41 scoped_ptr
<base::WaitableEvent
> impl_
;
42 DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl
);
47 BlinkPlatformImpl::BlinkPlatformImpl()
48 : main_loop_(base::MessageLoop::current()),
49 shared_timer_func_(NULL
),
50 shared_timer_fire_time_(0.0),
51 shared_timer_fire_time_was_set_while_suspended_(false),
52 shared_timer_suspended_(0),
53 current_thread_slot_(&DestroyCurrentThread
) {
56 BlinkPlatformImpl::~BlinkPlatformImpl() {
59 blink::WebMimeRegistry
* BlinkPlatformImpl::mimeRegistry() {
60 return &mime_registry_
;
63 blink::WebThemeEngine
* BlinkPlatformImpl::themeEngine() {
64 return &theme_engine_
;
67 blink::WebString
BlinkPlatformImpl::defaultLocale() {
68 return blink::WebString::fromUTF8("en-US");
71 double BlinkPlatformImpl::currentTime() {
72 return base::Time::Now().ToDoubleT();
75 double BlinkPlatformImpl::monotonicallyIncreasingTime() {
76 return base::TimeTicks::Now().ToInternalValue() /
77 static_cast<double>(base::Time::kMicrosecondsPerSecond
);
80 void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer
,
82 base::RandBytes(buffer
, length
);
85 void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func
)()) {
86 shared_timer_func_
= func
;
89 void BlinkPlatformImpl::setSharedTimerFireInterval(
90 double interval_seconds
) {
91 shared_timer_fire_time_
= interval_seconds
+ monotonicallyIncreasingTime();
92 if (shared_timer_suspended_
) {
93 shared_timer_fire_time_was_set_while_suspended_
= true;
97 // By converting between double and int64 representation, we run the risk
98 // of losing precision due to rounding errors. Performing computations in
99 // microseconds reduces this risk somewhat. But there still is the potential
100 // of us computing a fire time for the timer that is shorter than what we
102 // As the event loop will check event deadlines prior to actually firing
103 // them, there is a risk of needlessly rescheduling events and of
104 // needlessly looping if sleep times are too short even by small amounts.
105 // This results in measurable performance degradation unless we use ceil() to
106 // always round up the sleep times.
107 int64 interval
= static_cast<int64
>(
108 ceil(interval_seconds
* base::Time::kMillisecondsPerSecond
)
109 * base::Time::kMicrosecondsPerMillisecond
);
114 shared_timer_
.Stop();
115 shared_timer_
.Start(FROM_HERE
, base::TimeDelta::FromMicroseconds(interval
),
116 this, &BlinkPlatformImpl::DoTimeout
);
119 void BlinkPlatformImpl::stopSharedTimer() {
120 shared_timer_
.Stop();
123 void BlinkPlatformImpl::callOnMainThread(
124 void (*func
)(void*), void* context
) {
125 main_loop_
->PostTask(FROM_HERE
, base::Bind(func
, context
));
128 bool BlinkPlatformImpl::isThreadedCompositingEnabled() {
132 blink::WebCompositorSupport
* BlinkPlatformImpl::compositorSupport() {
133 return &compositor_support_
;
136 blink::WebScrollbarBehavior
* BlinkPlatformImpl::scrollbarBehavior() {
137 return &scrollbar_behavior_
;
140 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
141 const char* category_name
) {
142 static const unsigned char buf
[] = "*";
146 blink::WebURLLoader
* BlinkPlatformImpl::createURLLoader() {
150 blink::WebSocketHandle
* BlinkPlatformImpl::createWebSocketHandle() {
154 blink::WebString
BlinkPlatformImpl::userAgent() {
155 return blink::WebString::fromUTF8(kUserAgentString
);
158 blink::WebData
BlinkPlatformImpl::parseDataURL(
159 const blink::WebURL
& url
,
160 blink::WebString
& mimetype_out
,
161 blink::WebString
& charset_out
) {
162 std::string mimetype
, charset
, data
;
163 if (net::DataURL::Parse(url
, &mimetype
, &charset
, &data
)
164 && net::IsSupportedMimeType(mimetype
)) {
165 mimetype_out
= blink::WebString::fromUTF8(mimetype
);
166 charset_out
= blink::WebString::fromUTF8(charset
);
169 return blink::WebData();
172 blink::WebURLError
BlinkPlatformImpl::cancelledError(const blink::WebURL
& url
)
174 blink::WebURLError error
;
175 error
.domain
= blink::WebString::fromUTF8(net::kErrorDomain
);
176 error
.reason
= net::ERR_ABORTED
;
177 error
.unreachableURL
= url
;
178 error
.staleCopyInCache
= false;
179 error
.isCancellation
= true;
183 blink::WebThread
* BlinkPlatformImpl::createThread(const char* name
) {
184 return new WebThreadImpl(name
);
187 blink::WebThread
* BlinkPlatformImpl::currentThread() {
188 WebThreadImplForMessageLoop
* thread
=
189 static_cast<WebThreadImplForMessageLoop
*>(current_thread_slot_
.Get());
193 scoped_refptr
<base::MessageLoopProxy
> message_loop
=
194 base::MessageLoopProxy::current();
195 if (!message_loop
.get())
198 thread
= new WebThreadImplForMessageLoop(message_loop
.get());
199 current_thread_slot_
.Set(thread
);
203 void BlinkPlatformImpl::yieldCurrentThread() {
204 base::PlatformThread::YieldCurrentThread();
207 blink::WebWaitableEvent
* BlinkPlatformImpl::createWaitableEvent() {
208 return new WebWaitableEventImpl();
211 blink::WebWaitableEvent
* BlinkPlatformImpl::waitMultipleEvents(
212 const blink::WebVector
<blink::WebWaitableEvent
*>& web_events
) {
213 std::vector
<base::WaitableEvent
*> events
;
214 for (size_t i
= 0; i
< web_events
.size(); ++i
)
215 events
.push_back(static_cast<WebWaitableEventImpl
*>(web_events
[i
])->impl());
216 size_t idx
= base::WaitableEvent::WaitMany(
217 vector_as_array(&events
), events
.size());
218 DCHECK_LT(idx
, web_events
.size());
219 return web_events
[idx
];
223 void BlinkPlatformImpl::DestroyCurrentThread(void* thread
) {
224 WebThreadImplForMessageLoop
* impl
=
225 static_cast<WebThreadImplForMessageLoop
*>(thread
);