OLD | NEW |
| (Empty) |
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/command_line.h" | |
10 #include "base/rand_util.h" | |
11 #include "base/stl_util.h" | |
12 #include "base/synchronization/waitable_event.h" | |
13 #include "base/threading/platform_thread.h" | |
14 #include "base/time/time.h" | |
15 #include "mojo/services/html_viewer/blink_resource_constants.h" | |
16 #include "mojo/services/html_viewer/web_clipboard_impl.h" | |
17 #include "mojo/services/html_viewer/web_cookie_jar_impl.h" | |
18 #include "mojo/services/html_viewer/web_message_port_channel_impl.h" | |
19 #include "mojo/services/html_viewer/web_socket_handle_impl.h" | |
20 #include "mojo/services/html_viewer/web_thread_impl.h" | |
21 #include "mojo/services/html_viewer/web_url_loader_impl.h" | |
22 #include "net/base/data_url.h" | |
23 #include "net/base/mime_util.h" | |
24 #include "net/base/net_errors.h" | |
25 #include "net/base/net_util.h" | |
26 #include "third_party/WebKit/public/platform/WebWaitableEvent.h" | |
27 #include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h" | |
28 #include "ui/events/gestures/blink/web_gesture_curve_impl.h" | |
29 | |
30 namespace html_viewer { | |
31 namespace { | |
32 | |
33 // Allows overriding user agent scring. | |
34 const char kUserAgentSwitch[] = "user-agent"; | |
35 | |
36 // TODO(darin): Figure out what our UA should really be. | |
37 const char kDefaultUserAgentString[] = | |
38 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " | |
39 "Chrome/42.0.2311.68 Safari/537.36"; | |
40 | |
41 class WebWaitableEventImpl : public blink::WebWaitableEvent { | |
42 public: | |
43 WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {} | |
44 ~WebWaitableEventImpl() override {} | |
45 | |
46 void wait() override { impl_->Wait(); } | |
47 void signal() override { impl_->Signal(); } | |
48 | |
49 base::WaitableEvent* impl() { | |
50 return impl_.get(); | |
51 } | |
52 | |
53 private: | |
54 scoped_ptr<base::WaitableEvent> impl_; | |
55 DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl); | |
56 }; | |
57 | |
58 } // namespace | |
59 | |
60 BlinkPlatformImpl::BlinkPlatformImpl(mojo::ApplicationImpl* app) | |
61 : main_loop_(base::MessageLoop::current()), | |
62 shared_timer_func_(NULL), | |
63 shared_timer_fire_time_(0.0), | |
64 shared_timer_fire_time_was_set_while_suspended_(false), | |
65 shared_timer_suspended_(0), | |
66 current_thread_slot_(&DestroyCurrentThread), | |
67 scheduler_(main_loop_->message_loop_proxy()) { | |
68 if (app) { | |
69 app->ConnectToService("mojo:network_service", &network_service_); | |
70 | |
71 mojo::CookieStorePtr cookie_store; | |
72 network_service_->GetCookieStore(GetProxy(&cookie_store)); | |
73 cookie_jar_.reset(new WebCookieJarImpl(cookie_store.Pass())); | |
74 | |
75 mojo::ClipboardPtr clipboard; | |
76 app->ConnectToService("mojo:clipboard", &clipboard); | |
77 clipboard_.reset(new WebClipboardImpl(clipboard.Pass())); | |
78 } | |
79 } | |
80 | |
81 BlinkPlatformImpl::~BlinkPlatformImpl() { | |
82 } | |
83 | |
84 blink::WebCookieJar* BlinkPlatformImpl::cookieJar() { | |
85 return cookie_jar_.get(); | |
86 } | |
87 | |
88 blink::WebClipboard* BlinkPlatformImpl::clipboard() { | |
89 return clipboard_.get(); | |
90 } | |
91 | |
92 blink::WebMimeRegistry* BlinkPlatformImpl::mimeRegistry() { | |
93 return &mime_registry_; | |
94 } | |
95 | |
96 blink::WebThemeEngine* BlinkPlatformImpl::themeEngine() { | |
97 return &theme_engine_; | |
98 } | |
99 | |
100 blink::WebScheduler* BlinkPlatformImpl::scheduler() { | |
101 return &scheduler_; | |
102 } | |
103 | |
104 blink::WebString BlinkPlatformImpl::defaultLocale() { | |
105 return blink::WebString::fromUTF8("en-US"); | |
106 } | |
107 | |
108 blink::WebBlobRegistry* BlinkPlatformImpl::blobRegistry() { | |
109 return &blob_registry_; | |
110 } | |
111 | |
112 double BlinkPlatformImpl::currentTime() { | |
113 return base::Time::Now().ToDoubleT(); | |
114 } | |
115 | |
116 double BlinkPlatformImpl::monotonicallyIncreasingTime() { | |
117 return base::TimeTicks::Now().ToInternalValue() / | |
118 static_cast<double>(base::Time::kMicrosecondsPerSecond); | |
119 } | |
120 | |
121 void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer, | |
122 size_t length) { | |
123 base::RandBytes(buffer, length); | |
124 } | |
125 | |
126 void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) { | |
127 shared_timer_func_ = func; | |
128 } | |
129 | |
130 void BlinkPlatformImpl::setSharedTimerFireInterval( | |
131 double interval_seconds) { | |
132 shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime(); | |
133 if (shared_timer_suspended_) { | |
134 shared_timer_fire_time_was_set_while_suspended_ = true; | |
135 return; | |
136 } | |
137 | |
138 // By converting between double and int64 representation, we run the risk | |
139 // of losing precision due to rounding errors. Performing computations in | |
140 // microseconds reduces this risk somewhat. But there still is the potential | |
141 // of us computing a fire time for the timer that is shorter than what we | |
142 // need. | |
143 // As the event loop will check event deadlines prior to actually firing | |
144 // them, there is a risk of needlessly rescheduling events and of | |
145 // needlessly looping if sleep times are too short even by small amounts. | |
146 // This results in measurable performance degradation unless we use ceil() to | |
147 // always round up the sleep times. | |
148 int64 interval = static_cast<int64>( | |
149 ceil(interval_seconds * base::Time::kMillisecondsPerSecond) | |
150 * base::Time::kMicrosecondsPerMillisecond); | |
151 | |
152 if (interval < 0) | |
153 interval = 0; | |
154 | |
155 shared_timer_.Stop(); | |
156 shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval), | |
157 this, &BlinkPlatformImpl::DoTimeout); | |
158 } | |
159 | |
160 void BlinkPlatformImpl::stopSharedTimer() { | |
161 shared_timer_.Stop(); | |
162 } | |
163 | |
164 void BlinkPlatformImpl::callOnMainThread( | |
165 void (*func)(void*), void* context) { | |
166 main_loop_->PostTask(FROM_HERE, base::Bind(func, context)); | |
167 } | |
168 | |
169 bool BlinkPlatformImpl::isThreadedCompositingEnabled() { | |
170 return true; | |
171 } | |
172 | |
173 blink::WebCompositorSupport* BlinkPlatformImpl::compositorSupport() { | |
174 return &compositor_support_; | |
175 } | |
176 | |
177 void BlinkPlatformImpl::createMessageChannel( | |
178 blink::WebMessagePortChannel** channel1, | |
179 blink::WebMessagePortChannel** channel2) { | |
180 WebMessagePortChannelImpl::CreatePair(channel1, channel2); | |
181 } | |
182 | |
183 blink::WebScrollbarBehavior* BlinkPlatformImpl::scrollbarBehavior() { | |
184 return &scrollbar_behavior_; | |
185 } | |
186 | |
187 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag( | |
188 const char* category_name) { | |
189 static const unsigned char buf[] = "*"; | |
190 return buf; | |
191 } | |
192 | |
193 blink::WebData BlinkPlatformImpl::loadResource(const char* resource) { | |
194 for (size_t i = 0; i < arraysize(kDataResources); ++i) { | |
195 if (!strcmp(resource, kDataResources[i].name)) { | |
196 int length; | |
197 const unsigned char* data = | |
198 blink_resource_map_.GetResource(kDataResources[i].id, &length); | |
199 CHECK(data != nullptr && length > 0); | |
200 return blink::WebData(reinterpret_cast<const char*>(data), length); | |
201 } | |
202 } | |
203 NOTREACHED() << "Requested resource is unavailable: " << resource; | |
204 return blink::WebData(); | |
205 } | |
206 | |
207 blink::WebURLLoader* BlinkPlatformImpl::createURLLoader() { | |
208 return new WebURLLoaderImpl(network_service_.get(), &blob_registry_); | |
209 } | |
210 | |
211 blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() { | |
212 return new WebSocketHandleImpl(network_service_.get()); | |
213 } | |
214 | |
215 blink::WebString BlinkPlatformImpl::userAgent() { | |
216 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
217 if (command_line->HasSwitch(kUserAgentSwitch)) { | |
218 return blink::WebString::fromUTF8( | |
219 command_line->GetSwitchValueASCII(kUserAgentSwitch)); | |
220 } | |
221 return blink::WebString::fromUTF8(kDefaultUserAgentString); | |
222 } | |
223 | |
224 blink::WebData BlinkPlatformImpl::parseDataURL( | |
225 const blink::WebURL& url, | |
226 blink::WebString& mimetype_out, | |
227 blink::WebString& charset_out) { | |
228 std::string mimetype, charset, data; | |
229 if (net::DataURL::Parse(url, &mimetype, &charset, &data) | |
230 && net::IsSupportedMimeType(mimetype)) { | |
231 mimetype_out = blink::WebString::fromUTF8(mimetype); | |
232 charset_out = blink::WebString::fromUTF8(charset); | |
233 return data; | |
234 } | |
235 return blink::WebData(); | |
236 } | |
237 | |
238 blink::WebURLError BlinkPlatformImpl::cancelledError(const blink::WebURL& url) | |
239 const { | |
240 blink::WebURLError error; | |
241 error.domain = blink::WebString::fromUTF8(net::kErrorDomain); | |
242 error.reason = net::ERR_ABORTED; | |
243 error.unreachableURL = url; | |
244 error.staleCopyInCache = false; | |
245 error.isCancellation = true; | |
246 return error; | |
247 } | |
248 | |
249 bool BlinkPlatformImpl::isReservedIPAddress( | |
250 const blink::WebString& host) const { | |
251 net::IPAddressNumber address; | |
252 if (!net::ParseURLHostnameToNumber(host.utf8(), &address)) | |
253 return false; | |
254 return net::IsIPAddressReserved(address); | |
255 } | |
256 | |
257 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) { | |
258 return new WebThreadImpl(name); | |
259 } | |
260 | |
261 blink::WebThread* BlinkPlatformImpl::currentThread() { | |
262 WebThreadImplForMessageLoop* thread = | |
263 static_cast<WebThreadImplForMessageLoop*>(current_thread_slot_.Get()); | |
264 if (thread) | |
265 return (thread); | |
266 | |
267 scoped_refptr<base::MessageLoopProxy> message_loop = | |
268 base::MessageLoopProxy::current(); | |
269 if (!message_loop.get()) | |
270 return NULL; | |
271 | |
272 thread = new WebThreadImplForMessageLoop(message_loop.get()); | |
273 current_thread_slot_.Set(thread); | |
274 return thread; | |
275 } | |
276 | |
277 void BlinkPlatformImpl::yieldCurrentThread() { | |
278 base::PlatformThread::YieldCurrentThread(); | |
279 } | |
280 | |
281 blink::WebWaitableEvent* BlinkPlatformImpl::createWaitableEvent() { | |
282 return new WebWaitableEventImpl(); | |
283 } | |
284 | |
285 blink::WebWaitableEvent* BlinkPlatformImpl::waitMultipleEvents( | |
286 const blink::WebVector<blink::WebWaitableEvent*>& web_events) { | |
287 std::vector<base::WaitableEvent*> events; | |
288 for (size_t i = 0; i < web_events.size(); ++i) | |
289 events.push_back(static_cast<WebWaitableEventImpl*>(web_events[i])->impl()); | |
290 size_t idx = base::WaitableEvent::WaitMany( | |
291 vector_as_array(&events), events.size()); | |
292 DCHECK_LT(idx, web_events.size()); | |
293 return web_events[idx]; | |
294 } | |
295 | |
296 blink::WebGestureCurve* BlinkPlatformImpl::createFlingAnimationCurve( | |
297 blink::WebGestureDevice device_source, | |
298 const blink::WebFloatPoint& velocity, | |
299 const blink::WebSize& cumulative_scroll) { | |
300 const bool is_main_thread = true; | |
301 return ui::WebGestureCurveImpl::CreateFromDefaultPlatformCurve( | |
302 gfx::Vector2dF(velocity.x, velocity.y), | |
303 gfx::Vector2dF(cumulative_scroll.width, cumulative_scroll.height), | |
304 is_main_thread).release(); | |
305 } | |
306 | |
307 blink::WebCrypto* BlinkPlatformImpl::crypto() { | |
308 return &web_crypto_; | |
309 } | |
310 | |
311 blink::WebNotificationManager* | |
312 BlinkPlatformImpl::notificationManager() { | |
313 return &web_notification_manager_; | |
314 } | |
315 | |
316 // static | |
317 void BlinkPlatformImpl::DestroyCurrentThread(void* thread) { | |
318 WebThreadImplForMessageLoop* impl = | |
319 static_cast<WebThreadImplForMessageLoop*>(thread); | |
320 delete impl; | |
321 } | |
322 | |
323 } // namespace html_viewer | |
OLD | NEW |