Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / services / html_viewer / blink_platform_impl.cc
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/services/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/public/cpp/application/application_impl.h"
14 #include "mojo/services/html_viewer/webcookiejar_impl.h"
15 #include "mojo/services/html_viewer/webthread_impl.h"
16 #include "mojo/services/html_viewer/weburlloader_impl.h"
17 #include "net/base/data_url.h"
18 #include "net/base/mime_util.h"
19 #include "net/base/net_errors.h"
20 #include "third_party/WebKit/public/platform/WebWaitableEvent.h"
21
22 namespace mojo {
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:
32   WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {}
33   virtual ~WebWaitableEventImpl() {}
34
35   virtual void wait() { impl_->Wait(); }
36   virtual void signal() { impl_->Signal(); }
37
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
49 BlinkPlatformImpl::BlinkPlatformImpl(ApplicationImpl* 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->ConnectToService("mojo:mojo_network_service", &network_service_);
57
58   CookieStorePtr cookie_store;
59   network_service_->GetCookieStore(Get(&cookie_store));
60   cookie_jar_.reset(new WebCookieJarImpl(cookie_store.Pass()));
61 }
62
63 BlinkPlatformImpl::~BlinkPlatformImpl() {
64 }
65
66 blink::WebCookieJar* BlinkPlatformImpl::cookieJar() {
67   return cookie_jar_.get();
68 }
69
70 blink::WebMimeRegistry* BlinkPlatformImpl::mimeRegistry() {
71   return &mime_registry_;
72 }
73
74 blink::WebThemeEngine* BlinkPlatformImpl::themeEngine() {
75   return &theme_engine_;
76 }
77
78 blink::WebString BlinkPlatformImpl::defaultLocale() {
79   return blink::WebString::fromUTF8("en-US");
80 }
81
82 double BlinkPlatformImpl::currentTime() {
83   return base::Time::Now().ToDoubleT();
84 }
85
86 double BlinkPlatformImpl::monotonicallyIncreasingTime() {
87   return base::TimeTicks::Now().ToInternalValue() /
88       static_cast<double>(base::Time::kMicrosecondsPerSecond);
89 }
90
91 void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer,
92                                                       size_t length) {
93   base::RandBytes(buffer, length);
94 }
95
96 void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) {
97   shared_timer_func_ = func;
98 }
99
100 void BlinkPlatformImpl::setSharedTimerFireInterval(
101     double interval_seconds) {
102   shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime();
103   if (shared_timer_suspended_) {
104     shared_timer_fire_time_was_set_while_suspended_ = true;
105     return;
106   }
107
108   // By converting between double and int64 representation, we run the risk
109   // of losing precision due to rounding errors. Performing computations in
110   // microseconds reduces this risk somewhat. But there still is the potential
111   // of us computing a fire time for the timer that is shorter than what we
112   // need.
113   // As the event loop will check event deadlines prior to actually firing
114   // them, there is a risk of needlessly rescheduling events and of
115   // needlessly looping if sleep times are too short even by small amounts.
116   // This results in measurable performance degradation unless we use ceil() to
117   // always round up the sleep times.
118   int64 interval = static_cast<int64>(
119       ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
120       * base::Time::kMicrosecondsPerMillisecond);
121
122   if (interval < 0)
123     interval = 0;
124
125   shared_timer_.Stop();
126   shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
127                       this, &BlinkPlatformImpl::DoTimeout);
128 }
129
130 void BlinkPlatformImpl::stopSharedTimer() {
131   shared_timer_.Stop();
132 }
133
134 void BlinkPlatformImpl::callOnMainThread(
135     void (*func)(void*), void* context) {
136   main_loop_->PostTask(FROM_HERE, base::Bind(func, context));
137 }
138
139 blink::WebScrollbarBehavior* BlinkPlatformImpl::scrollbarBehavior() {
140   return &scrollbar_behavior_;
141 }
142
143 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
144     const char* category_name) {
145   static const unsigned char buf[] = "*";
146   return buf;
147 }
148
149 blink::WebURLLoader* BlinkPlatformImpl::createURLLoader() {
150   return new WebURLLoaderImpl(network_service_.get());
151 }
152
153 blink::WebString BlinkPlatformImpl::userAgent() {
154   return blink::WebString::fromUTF8(kUserAgentString);
155 }
156
157 blink::WebData BlinkPlatformImpl::parseDataURL(
158     const blink::WebURL& url,
159     blink::WebString& mimetype_out,
160     blink::WebString& charset_out) {
161   std::string mimetype, charset, data;
162   if (net::DataURL::Parse(url, &mimetype, &charset, &data)
163       && net::IsSupportedMimeType(mimetype)) {
164     mimetype_out = blink::WebString::fromUTF8(mimetype);
165     charset_out = blink::WebString::fromUTF8(charset);
166     return data;
167   }
168   return blink::WebData();
169 }
170
171 blink::WebURLError BlinkPlatformImpl::cancelledError(const blink::WebURL& url)
172     const {
173   blink::WebURLError error;
174   error.domain = blink::WebString::fromUTF8(net::kErrorDomain);
175   error.reason = net::ERR_ABORTED;
176   error.unreachableURL = url;
177   error.staleCopyInCache = false;
178   error.isCancellation = true;
179   return error;
180 }
181
182 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
183   return new WebThreadImpl(name);
184 }
185
186 blink::WebThread* BlinkPlatformImpl::currentThread() {
187   WebThreadImplForMessageLoop* thread =
188       static_cast<WebThreadImplForMessageLoop*>(current_thread_slot_.Get());
189   if (thread)
190     return (thread);
191
192   scoped_refptr<base::MessageLoopProxy> message_loop =
193       base::MessageLoopProxy::current();
194   if (!message_loop.get())
195     return NULL;
196
197   thread = new WebThreadImplForMessageLoop(message_loop.get());
198   current_thread_slot_.Set(thread);
199   return thread;
200 }
201
202 blink::WebWaitableEvent* BlinkPlatformImpl::createWaitableEvent() {
203   return new WebWaitableEventImpl();
204 }
205
206 blink::WebWaitableEvent* BlinkPlatformImpl::waitMultipleEvents(
207     const blink::WebVector<blink::WebWaitableEvent*>& web_events) {
208   std::vector<base::WaitableEvent*> events;
209   for (size_t i = 0; i < web_events.size(); ++i)
210     events.push_back(static_cast<WebWaitableEventImpl*>(web_events[i])->impl());
211   size_t idx = base::WaitableEvent::WaitMany(
212       vector_as_array(&events), events.size());
213   DCHECK_LT(idx, web_events.size());
214   return web_events[idx];
215 }
216
217 // static
218 void BlinkPlatformImpl::DestroyCurrentThread(void* thread) {
219   WebThreadImplForMessageLoop* impl =
220       static_cast<WebThreadImplForMessageLoop*>(thread);
221   delete impl;
222 }
223
224 }  // namespace mojo