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