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 "base/command_line.h"
6 #include "base/i18n/icu_util.h"
7 #include "base/logging.h"
8 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/thread.h"
13 #include "components/html_viewer/blink_platform_impl.h"
14 #include "components/html_viewer/discardable_memory_allocator.h"
15 #include "components/html_viewer/html_document.h"
16 #include "components/html_viewer/web_media_player_factory.h"
17 #include "gin/v8_initializer.h"
18 #include "mojo/application/application_runner_chromium.h"
19 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
20 #include "third_party/WebKit/public/web/WebKit.h"
21 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
22 #include "third_party/mojo/src/mojo/public/c/system/main.h"
23 #include "third_party/mojo/src/mojo/public/cpp/application/application_connection.h"
24 #include "third_party/mojo/src/mojo/public/cpp/application/application_delegate.h"
25 #include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h"
26 #include "third_party/mojo/src/mojo/public/cpp/application/connect.h"
27 #include "third_party/mojo/src/mojo/public/cpp/application/interface_factory_impl.h"
28 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
29 #include "third_party/mojo_services/src/content_handler/public/interfaces/content_handler.mojom.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/base/ui_base_paths.h"
33 using mojo::ApplicationConnection
;
35 using mojo::BindToRequest
;
36 using mojo::ContentHandler
;
37 using mojo::InterfaceRequest
;
38 using mojo::ServiceProvider
;
39 using mojo::ServiceProviderPtr
;
42 using mojo::URLLoaderPtr
;
43 using mojo::URLResponsePtr
;
45 namespace html_viewer
{
47 // Switches for html_viewer.
49 // Enable MediaRenderer in media pipeline instead of using the internal
50 // media::Renderer implementation.
51 const char kEnableMojoMediaRenderer
[] = "enable-mojo-media-renderer";
53 // Disables support for (unprefixed) Encrypted Media Extensions.
54 const char kDisableEncryptedMedia
[] = "disable-encrypted-media";
56 // Prevents creation of any output surface.
57 const char kIsHeadless
[] = "is-headless";
59 size_t kDesiredMaxMemory
= 20 * 1024 * 1024;
63 class HTMLViewerApplication
: public mojo::Application
{
65 HTMLViewerApplication(InterfaceRequest
<Application
> request
,
66 URLResponsePtr response
,
67 scoped_refptr
<base::MessageLoopProxy
> compositor_thread
,
68 WebMediaPlayerFactory
* web_media_player_factory
,
70 : url_(response
->url
),
71 binding_(this, request
.Pass()),
72 initial_response_(response
.Pass()),
73 compositor_thread_(compositor_thread
),
74 web_media_player_factory_(web_media_player_factory
),
75 is_headless_(is_headless
) {}
77 void Initialize(ShellPtr shell
,
79 const String
& url
) override
{
80 ServiceProviderPtr service_provider
;
81 shell_
= shell
.Pass();
82 shell_
->ConnectToApplication("mojo:network_service",
83 GetProxy(&service_provider
), nullptr);
84 ConnectToService(service_provider
.get(), &network_service_
);
87 void AcceptConnection(const String
& requestor_url
,
88 InterfaceRequest
<ServiceProvider
> services
,
89 ServiceProviderPtr exposed_services
,
90 const String
& url
) override
{
91 if (initial_response_
) {
92 OnResponseReceived(URLLoaderPtr(), services
.Pass(),
93 initial_response_
.Pass());
96 network_service_
->CreateURLLoader(GetProxy(&loader
));
97 mojo::URLRequestPtr
request(mojo::URLRequest::New());
99 request
->auto_follow_redirects
= true;
101 // |loader| will be pass to the OnResponseReceived method through a
102 // callback. Because order of evaluation is undefined, a reference to the
103 // raw pointer is needed.
104 mojo::URLLoader
* raw_loader
= loader
.get();
107 base::Bind(&HTMLViewerApplication::OnResponseReceived
,
108 base::Unretained(this), base::Passed(&loader
),
109 base::Passed(&services
)));
113 void RequestQuit() override
{}
116 void OnResponseReceived(URLLoaderPtr loader
,
117 InterfaceRequest
<ServiceProvider
> services
,
118 URLResponsePtr response
) {
119 new HTMLDocument(services
.Pass(), response
.Pass(), shell_
.get(),
120 compositor_thread_
, web_media_player_factory_
,
125 mojo::StrongBinding
<mojo::Application
> binding_
;
127 mojo::NetworkServicePtr network_service_
;
128 URLResponsePtr initial_response_
;
129 scoped_refptr
<base::MessageLoopProxy
> compositor_thread_
;
130 WebMediaPlayerFactory
* web_media_player_factory_
;
134 class ContentHandlerImpl
: public mojo::InterfaceImpl
<ContentHandler
> {
136 ContentHandlerImpl(scoped_refptr
<base::MessageLoopProxy
> compositor_thread
,
137 WebMediaPlayerFactory
* web_media_player_factory
,
139 : compositor_thread_(compositor_thread
),
140 web_media_player_factory_(web_media_player_factory
),
141 is_headless_(is_headless
) {}
142 ~ContentHandlerImpl() override
{}
145 // Overridden from ContentHandler:
146 void StartApplication(InterfaceRequest
<mojo::Application
> request
,
147 URLResponsePtr response
) override
{
148 new HTMLViewerApplication(request
.Pass(), response
.Pass(),
149 compositor_thread_
, web_media_player_factory_
,
153 scoped_refptr
<base::MessageLoopProxy
> compositor_thread_
;
154 WebMediaPlayerFactory
* web_media_player_factory_
;
157 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl
);
160 class HTMLViewer
: public mojo::ApplicationDelegate
,
161 public mojo::InterfaceFactory
<ContentHandler
> {
164 : discardable_memory_allocator_(kDesiredMaxMemory
),
165 compositor_thread_("compositor thread") {}
167 ~HTMLViewer() override
{ blink::shutdown(); }
170 // Overridden from ApplicationDelegate:
171 void Initialize(mojo::ApplicationImpl
* app
) override
{
172 base::DiscardableMemoryAllocator::SetInstance(
173 &discardable_memory_allocator_
);
175 blink_platform_
.reset(new BlinkPlatformImpl(app
));
176 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
177 // Note: this requires file system access.
178 gin::V8Initializer::LoadV8Snapshot();
180 blink::initialize(blink_platform_
.get());
181 base::i18n::InitializeICU();
183 ui::RegisterPathProvider();
185 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
187 logging::LoggingSettings settings
;
188 settings
.logging_dest
= logging::LOG_TO_SYSTEM_DEBUG_LOG
;
189 logging::InitLogging(settings
);
190 // Display process ID, thread ID and timestamp in logs.
191 logging::SetLogItems(true, true, true, false);
193 if (command_line
->HasSwitch(kDisableEncryptedMedia
))
194 blink::WebRuntimeFeatures::enableEncryptedMedia(false);
196 is_headless_
= command_line
->HasSwitch(kIsHeadless
);
198 // TODO(sky): consider putting this into the .so so that we don't need
199 // file system access.
200 base::FilePath ui_test_pak_path
;
201 CHECK(PathService::Get(ui::UI_TEST_PAK
, &ui_test_pak_path
));
202 ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path
);
205 compositor_thread_
.Start();
206 #if defined(OS_ANDROID)
207 // TODO(sky): Get WebMediaPlayerFactory working on android.
210 bool enable_mojo_media_renderer
=
211 command_line
->HasSwitch(kEnableMojoMediaRenderer
);
213 web_media_player_factory_
.reset(new WebMediaPlayerFactory(
214 compositor_thread_
.message_loop_proxy(), enable_mojo_media_renderer
));
218 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
219 connection
->AddService(this);
223 // Overridden from InterfaceFactory<ContentHandler>
224 void Create(ApplicationConnection
* connection
,
225 mojo::InterfaceRequest
<ContentHandler
> request
) override
{
227 new ContentHandlerImpl(compositor_thread_
.message_loop_proxy(),
228 web_media_player_factory_
.get(), is_headless_
),
232 // Skia requires that we have one of these. Unlike the one used in chrome,
233 // this doesn't use purgable shared memory. Instead, it tries to free the
234 // oldest unlocked chunks on allocation.
236 // TODO(erg): In the long run, delete this allocator and get the real shared
237 // memory based purging allocator working here.
238 DiscardableMemoryAllocator discardable_memory_allocator_
;
240 scoped_ptr
<BlinkPlatformImpl
> blink_platform_
;
241 base::Thread compositor_thread_
;
242 scoped_ptr
<WebMediaPlayerFactory
> web_media_player_factory_
;
243 // Set if the content will never be displayed.
246 DISALLOW_COPY_AND_ASSIGN(HTMLViewer
);
249 } // namespace html_viewer
251 MojoResult
MojoMain(MojoHandle shell_handle
) {
252 mojo::ApplicationRunnerChromium
runner(new html_viewer::HTMLViewer
);
253 return runner
.Run(shell_handle
);