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 "components/html_viewer/blink_platform_impl.h"
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/thread_task_runner_handle.h"
14 #include "base/threading/platform_thread.h"
15 #include "base/time/time.h"
16 #include "base/trace_event/trace_event.h"
17 #include "components/html_viewer/blink_resource_constants.h"
18 #include "components/html_viewer/web_clipboard_impl.h"
19 #include "components/html_viewer/web_cookie_jar_impl.h"
20 #include "components/html_viewer/web_socket_handle_impl.h"
21 #include "components/html_viewer/web_url_loader_impl.h"
22 #include "components/message_port/web_message_port_channel_impl.h"
23 #include "components/mime_util/mime_util.h"
24 #include "components/scheduler/child/webthread_impl_for_worker_scheduler.h"
25 #include "components/scheduler/renderer/renderer_scheduler.h"
26 #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
27 #include "mojo/application/public/cpp/application_impl.h"
28 #include "mojo/application/public/cpp/connect.h"
29 #include "mojo/common/user_agent.h"
30 #include "net/base/data_url.h"
31 #include "net/base/ip_address_number.h"
32 #include "net/base/net_errors.h"
33 #include "net/base/net_util.h"
34 #include "third_party/WebKit/public/platform/WebWaitableEvent.h"
35 #include "ui/base/resource/resource_bundle.h"
36 #include "ui/events/gestures/blink/web_gesture_curve_impl.h"
38 namespace html_viewer
{
41 // Allows overriding user agent scring.
42 const char kUserAgentSwitch
[] = "user-agent";
44 class WebWaitableEventImpl
: public blink::WebWaitableEvent
{
46 WebWaitableEventImpl(ResetPolicy policy
, InitialState state
) {
47 bool manual_reset
= policy
== ResetPolicy::Manual
;
48 bool initially_signaled
= state
== InitialState::Signaled
;
49 impl_
.reset(new base::WaitableEvent(manual_reset
, initially_signaled
));
51 virtual ~WebWaitableEventImpl() {}
53 virtual void reset() { impl_
->Reset(); }
54 virtual void wait() { impl_
->Wait(); }
55 virtual void signal() { impl_
->Signal(); }
57 base::WaitableEvent
* impl() {
62 scoped_ptr
<base::WaitableEvent
> impl_
;
63 DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl
);
68 BlinkPlatformImpl::BlinkPlatformImpl(
69 mojo::ApplicationImpl
* app
,
70 scheduler::RendererScheduler
* renderer_scheduler
)
71 : main_thread_task_runner_(renderer_scheduler
->DefaultTaskRunner()),
72 main_thread_(new scheduler::WebThreadImplForRendererScheduler(
73 renderer_scheduler
)) {
75 mojo::URLRequestPtr
request(mojo::URLRequest::New());
76 request
->url
= mojo::String::From("mojo:network_service");
77 mojo::ApplicationConnection
* connection
=
78 app
->ConnectToApplication(request
.Pass());
79 connection
->ConnectToService(&network_service_
);
80 connection
->ConnectToService(&url_loader_factory_
);
82 mojo::CookieStorePtr cookie_store
;
83 network_service_
->GetCookieStore(GetProxy(&cookie_store
));
84 cookie_jar_
.reset(new WebCookieJarImpl(cookie_store
.Pass()));
86 mojo::ClipboardPtr clipboard
;
87 mojo::URLRequestPtr
request2(mojo::URLRequest::New());
88 request2
->url
= mojo::String::From("mojo:clipboard");
89 app
->ConnectToService(request2
.Pass(), &clipboard
);
90 clipboard_
.reset(new WebClipboardImpl(clipboard
.Pass()));
94 BlinkPlatformImpl::~BlinkPlatformImpl() {
97 blink::WebCookieJar
* BlinkPlatformImpl::cookieJar() {
98 return cookie_jar_
.get();
101 blink::WebClipboard
* BlinkPlatformImpl::clipboard() {
102 return clipboard_
.get();
105 blink::WebMimeRegistry
* BlinkPlatformImpl::mimeRegistry() {
106 return &mime_registry_
;
109 blink::WebThemeEngine
* BlinkPlatformImpl::themeEngine() {
110 return &theme_engine_
;
113 blink::WebString
BlinkPlatformImpl::defaultLocale() {
114 return blink::WebString::fromUTF8("en-US");
117 blink::WebBlobRegistry
* BlinkPlatformImpl::blobRegistry() {
118 return &blob_registry_
;
121 double BlinkPlatformImpl::currentTime() {
122 return base::Time::Now().ToDoubleT();
125 double BlinkPlatformImpl::monotonicallyIncreasingTime() {
126 return base::TimeTicks::Now().ToInternalValue() /
127 static_cast<double>(base::Time::kMicrosecondsPerSecond
);
130 void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer
,
132 base::RandBytes(buffer
, length
);
135 bool BlinkPlatformImpl::isThreadedCompositingEnabled() {
139 blink::WebCompositorSupport
* BlinkPlatformImpl::compositorSupport() {
140 return &compositor_support_
;
143 uint32_t BlinkPlatformImpl::getUniqueIdForProcess() {
144 // TODO(rickyz): Replace this with base::GetUniqueIdForProcess when that's
146 return base::trace_event::TraceLog::GetInstance()->process_id();
149 void BlinkPlatformImpl::createMessageChannel(
150 blink::WebMessagePortChannel
** channel1
,
151 blink::WebMessagePortChannel
** channel2
) {
152 message_port::WebMessagePortChannelImpl::CreatePair(channel1
, channel2
);
155 blink::WebScrollbarBehavior
* BlinkPlatformImpl::scrollbarBehavior() {
156 return &scrollbar_behavior_
;
159 const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
160 const char* category_name
) {
161 static const unsigned char buf
[] = "*";
165 blink::WebData
BlinkPlatformImpl::loadResource(const char* resource
) {
166 for (size_t i
= 0; i
< arraysize(kDataResources
); ++i
) {
167 if (!strcmp(resource
, kDataResources
[i
].name
)) {
168 base::StringPiece data
=
169 ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
170 kDataResources
[i
].id
, ui::SCALE_FACTOR_100P
);
171 return blink::WebData(data
.data(), data
.size());
174 NOTREACHED() << "Requested resource is unavailable: " << resource
;
175 return blink::WebData();
178 blink::WebURLLoader
* BlinkPlatformImpl::createURLLoader() {
179 return new WebURLLoaderImpl(url_loader_factory_
.get(), &blob_registry_
);
182 blink::WebSocketHandle
* BlinkPlatformImpl::createWebSocketHandle() {
183 return new WebSocketHandleImpl(network_service_
.get());
186 blink::WebString
BlinkPlatformImpl::userAgent() {
187 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
188 if (command_line
->HasSwitch(kUserAgentSwitch
)) {
189 return blink::WebString::fromUTF8(
190 command_line
->GetSwitchValueASCII(kUserAgentSwitch
));
192 return blink::WebString::fromUTF8(mojo::common::GetUserAgent());
195 blink::WebData
BlinkPlatformImpl::parseDataURL(
196 const blink::WebURL
& url
,
197 blink::WebString
& mimetype_out
,
198 blink::WebString
& charset_out
) {
199 std::string mimetype
, charset
, data
;
200 if (net::DataURL::Parse(url
, &mimetype
, &charset
, &data
) &&
201 mime_util::IsSupportedMimeType(mimetype
)) {
202 mimetype_out
= blink::WebString::fromUTF8(mimetype
);
203 charset_out
= blink::WebString::fromUTF8(charset
);
206 return blink::WebData();
209 blink::WebURLError
BlinkPlatformImpl::cancelledError(const blink::WebURL
& url
)
211 blink::WebURLError error
;
212 error
.domain
= blink::WebString::fromUTF8(net::kErrorDomain
);
213 error
.reason
= net::ERR_ABORTED
;
214 error
.unreachableURL
= url
;
215 error
.staleCopyInCache
= false;
216 error
.isCancellation
= true;
220 bool BlinkPlatformImpl::isReservedIPAddress(
221 const blink::WebString
& host
) const {
222 net::IPAddressNumber address
;
223 if (!net::ParseURLHostnameToNumber(host
.utf8(), &address
))
225 return net::IsIPAddressReserved(address
);
228 blink::WebThread
* BlinkPlatformImpl::createThread(const char* name
) {
229 scheduler::WebThreadImplForWorkerScheduler
* thread
=
230 new scheduler::WebThreadImplForWorkerScheduler(name
);
231 thread
->TaskRunner()->PostTask(
232 FROM_HERE
, base::Bind(&BlinkPlatformImpl::UpdateWebThreadTLS
,
233 base::Unretained(this), thread
));
237 blink::WebThread
* BlinkPlatformImpl::currentThread() {
238 if (main_thread_
->isCurrentThread())
239 return main_thread_
.get();
240 return static_cast<blink::WebThread
*>(current_thread_slot_
.Get());
243 void BlinkPlatformImpl::yieldCurrentThread() {
244 base::PlatformThread::YieldCurrentThread();
247 blink::WebWaitableEvent
* BlinkPlatformImpl::createWaitableEvent(
248 blink::WebWaitableEvent::ResetPolicy policy
,
249 blink::WebWaitableEvent::InitialState state
) {
250 return new WebWaitableEventImpl(policy
, state
);
253 blink::WebWaitableEvent
* BlinkPlatformImpl::waitMultipleEvents(
254 const blink::WebVector
<blink::WebWaitableEvent
*>& web_events
) {
255 std::vector
<base::WaitableEvent
*> events
;
256 for (size_t i
= 0; i
< web_events
.size(); ++i
)
257 events
.push_back(static_cast<WebWaitableEventImpl
*>(web_events
[i
])->impl());
258 size_t idx
= base::WaitableEvent::WaitMany(
259 vector_as_array(&events
), events
.size());
260 DCHECK_LT(idx
, web_events
.size());
261 return web_events
[idx
];
264 blink::WebGestureCurve
* BlinkPlatformImpl::createFlingAnimationCurve(
265 blink::WebGestureDevice device_source
,
266 const blink::WebFloatPoint
& velocity
,
267 const blink::WebSize
& cumulative_scroll
) {
268 const bool is_main_thread
= true;
269 return ui::WebGestureCurveImpl::CreateFromDefaultPlatformCurve(
270 gfx::Vector2dF(velocity
.x
, velocity
.y
),
271 gfx::Vector2dF(cumulative_scroll
.width
, cumulative_scroll
.height
),
272 is_main_thread
).release();
275 blink::WebCrypto
* BlinkPlatformImpl::crypto() {
279 blink::WebNotificationManager
*
280 BlinkPlatformImpl::notificationManager() {
281 return &web_notification_manager_
;
284 void BlinkPlatformImpl::UpdateWebThreadTLS(blink::WebThread
* thread
) {
285 DCHECK(!current_thread_slot_
.Get());
286 current_thread_slot_
.Set(thread
);
289 } // namespace html_viewer