• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "mojo/examples/html_viewer/blink_platform_impl.h"
6 
7 #include <cmath>
8 
9 #include "base/rand_util.h"
10 #include "base/stl_util.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/time/time.h"
13 #include "mojo/examples/html_viewer/webthread_impl.h"
14 #include "mojo/examples/html_viewer/weburlloader_impl.h"
15 #include "mojo/public/cpp/application/application.h"
16 #include "net/base/data_url.h"
17 #include "net/base/mime_util.h"
18 #include "net/base/net_errors.h"
19 #include "third_party/WebKit/public/platform/WebWaitableEvent.h"
20 
21 namespace mojo {
22 namespace examples {
23 namespace {
24 
25 // TODO(darin): Figure out what our UA should really be.
26 const char kUserAgentString[] =
27   "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
28   "Chrome/35.0.1916.153 Safari/537.36";
29 
30 class WebWaitableEventImpl : public blink::WebWaitableEvent {
31  public:
WebWaitableEventImpl()32   WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {}
~WebWaitableEventImpl()33   virtual ~WebWaitableEventImpl() {}
34 
wait()35   virtual void wait() { impl_->Wait(); }
signal()36   virtual void signal() { impl_->Signal(); }
37 
impl()38   base::WaitableEvent* impl() {
39     return impl_.get();
40   }
41 
42  private:
43   scoped_ptr<base::WaitableEvent> impl_;
44   DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl);
45 };
46 
47 }  // namespace
48 
BlinkPlatformImpl(Application * app)49 BlinkPlatformImpl::BlinkPlatformImpl(Application* app)
50     : main_loop_(base::MessageLoop::current()),
51       shared_timer_func_(NULL),
52       shared_timer_fire_time_(0.0),
53       shared_timer_fire_time_was_set_while_suspended_(false),
54       shared_timer_suspended_(0),
55       current_thread_slot_(&DestroyCurrentThread) {
56   app->ConnectTo("mojo:mojo_network_service", &network_service_);
57 }
58 
~BlinkPlatformImpl()59 BlinkPlatformImpl::~BlinkPlatformImpl() {
60 }
61 
mimeRegistry()62 blink::WebMimeRegistry* BlinkPlatformImpl::mimeRegistry() {
63   return &mime_registry_;
64 }
65 
themeEngine()66 blink::WebThemeEngine* BlinkPlatformImpl::themeEngine() {
67   return &dummy_theme_engine_;
68 }
69 
defaultLocale()70 blink::WebString BlinkPlatformImpl::defaultLocale() {
71   return blink::WebString::fromUTF8("en-US");
72 }
73 
currentTime()74 double BlinkPlatformImpl::currentTime() {
75   return base::Time::Now().ToDoubleT();
76 }
77 
monotonicallyIncreasingTime()78 double BlinkPlatformImpl::monotonicallyIncreasingTime() {
79   return base::TimeTicks::Now().ToInternalValue() /
80       static_cast<double>(base::Time::kMicrosecondsPerSecond);
81 }
82 
cryptographicallyRandomValues(unsigned char * buffer,size_t length)83 void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer,
84                                                       size_t length) {
85   base::RandBytes(buffer, length);
86 }
87 
setSharedTimerFiredFunction(void (* func)())88 void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) {
89   shared_timer_func_ = func;
90 }
91 
setSharedTimerFireInterval(double interval_seconds)92 void BlinkPlatformImpl::setSharedTimerFireInterval(
93     double interval_seconds) {
94   shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime();
95   if (shared_timer_suspended_) {
96     shared_timer_fire_time_was_set_while_suspended_ = true;
97     return;
98   }
99 
100   // By converting between double and int64 representation, we run the risk
101   // of losing precision due to rounding errors. Performing computations in
102   // microseconds reduces this risk somewhat. But there still is the potential
103   // of us computing a fire time for the timer that is shorter than what we
104   // need.
105   // As the event loop will check event deadlines prior to actually firing
106   // them, there is a risk of needlessly rescheduling events and of
107   // needlessly looping if sleep times are too short even by small amounts.
108   // This results in measurable performance degradation unless we use ceil() to
109   // always round up the sleep times.
110   int64 interval = static_cast<int64>(
111       ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
112       * base::Time::kMicrosecondsPerMillisecond);
113 
114   if (interval < 0)
115     interval = 0;
116 
117   shared_timer_.Stop();
118   shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
119                       this, &BlinkPlatformImpl::DoTimeout);
120 }
121 
stopSharedTimer()122 void BlinkPlatformImpl::stopSharedTimer() {
123   shared_timer_.Stop();
124 }
125 
callOnMainThread(void (* func)(void *),void * context)126 void BlinkPlatformImpl::callOnMainThread(
127     void (*func)(void*), void* context) {
128   main_loop_->PostTask(FROM_HERE, base::Bind(func, context));
129 }
130 
getTraceCategoryEnabledFlag(const char * category_name)131 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
132     const char* category_name) {
133   static const unsigned char buf[] = "*";
134   return buf;
135 }
136 
createURLLoader()137 blink::WebURLLoader* BlinkPlatformImpl::createURLLoader() {
138   return new WebURLLoaderImpl(network_service_.get());
139 }
140 
userAgent()141 blink::WebString BlinkPlatformImpl::userAgent() {
142   return blink::WebString::fromUTF8(kUserAgentString);
143 }
144 
parseDataURL(const blink::WebURL & url,blink::WebString & mimetype_out,blink::WebString & charset_out)145 blink::WebData BlinkPlatformImpl::parseDataURL(
146     const blink::WebURL& url,
147     blink::WebString& mimetype_out,
148     blink::WebString& charset_out) {
149   std::string mimetype, charset, data;
150   if (net::DataURL::Parse(url, &mimetype, &charset, &data)
151       && net::IsSupportedMimeType(mimetype)) {
152     mimetype_out = blink::WebString::fromUTF8(mimetype);
153     charset_out = blink::WebString::fromUTF8(charset);
154     return data;
155   }
156   return blink::WebData();
157 }
158 
cancelledError(const blink::WebURL & url) const159 blink::WebURLError BlinkPlatformImpl::cancelledError(const blink::WebURL& url)
160     const {
161   blink::WebURLError error;
162   error.domain = blink::WebString::fromUTF8(net::kErrorDomain);
163   error.reason = net::ERR_ABORTED;
164   error.unreachableURL = url;
165   error.staleCopyInCache = false;
166   error.isCancellation = true;
167   return error;
168 }
169 
createThread(const char * name)170 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
171   return new WebThreadImpl(name);
172 }
173 
currentThread()174 blink::WebThread* BlinkPlatformImpl::currentThread() {
175   WebThreadImplForMessageLoop* thread =
176       static_cast<WebThreadImplForMessageLoop*>(current_thread_slot_.Get());
177   if (thread)
178     return (thread);
179 
180   scoped_refptr<base::MessageLoopProxy> message_loop =
181       base::MessageLoopProxy::current();
182   if (!message_loop.get())
183     return NULL;
184 
185   thread = new WebThreadImplForMessageLoop(message_loop.get());
186   current_thread_slot_.Set(thread);
187   return thread;
188 }
189 
createWaitableEvent()190 blink::WebWaitableEvent* BlinkPlatformImpl::createWaitableEvent() {
191   return new WebWaitableEventImpl();
192 }
193 
waitMultipleEvents(const blink::WebVector<blink::WebWaitableEvent * > & web_events)194 blink::WebWaitableEvent* BlinkPlatformImpl::waitMultipleEvents(
195     const blink::WebVector<blink::WebWaitableEvent*>& web_events) {
196   std::vector<base::WaitableEvent*> events;
197   for (size_t i = 0; i < web_events.size(); ++i)
198     events.push_back(static_cast<WebWaitableEventImpl*>(web_events[i])->impl());
199   size_t idx = base::WaitableEvent::WaitMany(
200       vector_as_array(&events), events.size());
201   DCHECK_LT(idx, web_events.size());
202   return web_events[idx];
203 }
204 
205 // static
DestroyCurrentThread(void * thread)206 void BlinkPlatformImpl::DestroyCurrentThread(void* thread) {
207   WebThreadImplForMessageLoop* impl =
208       static_cast<WebThreadImplForMessageLoop*>(thread);
209   delete impl;
210 }
211 
212 }  // namespace examples
213 }  // namespace mojo
214