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/logging.h"
7 #include "base/macros.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/threading/thread.h"
11 #include "gin/public/isolate_holder.h"
12 #include "mojo/application/application_runner_chromium.h"
13 #include "mojo/public/c/system/main.h"
14 #include "mojo/public/cpp/application/application_connection.h"
15 #include "mojo/public/cpp/application/application_delegate.h"
16 #include "mojo/public/cpp/application/application_impl.h"
17 #include "mojo/public/cpp/application/connect.h"
18 #include "mojo/public/cpp/application/interface_factory_impl.h"
19 #include "mojo/services/content_handler/public/interfaces/content_handler.mojom.h"
20 #include "mojo/services/html_viewer/html_document.h"
21 #include "mojo/services/html_viewer/mojo_blink_platform_impl.h"
22 #include "mojo/services/html_viewer/webmediaplayer_factory.h"
23 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
24 #include "third_party/WebKit/public/web/WebKit.h"
25 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
27 #if !defined(COMPONENT_BUILD)
28 #include "base/i18n/icu_util.h"
29 #include "base/path_service.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/base/ui_base_paths.h"
34 using mojo::ApplicationConnection
;
36 using mojo::ContentHandler
;
37 using mojo::ServiceProviderPtr
;
40 using mojo::URLLoaderPtr
;
41 using mojo::URLResponsePtr
;
43 namespace html_viewer
{
45 // Switches for html_viewer to be used with "--args-for". For example:
46 // --args-for='mojo:html_viewer --enable-mojo-media-renderer'
48 // Enable MediaRenderer in media pipeline instead of using the internal
49 // media::Renderer implementation.
50 const char kEnableMojoMediaRenderer
[] = "enable-mojo-media-renderer";
52 // Enables support for Encrypted Media Extensions (e.g. MediaKeys).
53 const char kEnableEncryptedMedia
[] = "enable-encrypted-media";
57 class HTMLViewerApplication
: public mojo::Application
{
59 HTMLViewerApplication(ShellPtr shell
,
60 URLResponsePtr response
,
61 scoped_refptr
<base::MessageLoopProxy
> compositor_thread
,
62 WebMediaPlayerFactory
* web_media_player_factory
)
63 : url_(response
->url
),
65 initial_response_(response
.Pass()),
66 compositor_thread_(compositor_thread
),
67 web_media_player_factory_(web_media_player_factory
) {
68 shell_
.set_client(this);
69 ServiceProviderPtr service_provider
;
70 shell_
->ConnectToApplication("mojo:network_service",
71 GetProxy(&service_provider
));
72 ConnectToService(service_provider
.get(), &network_service_
);
75 void Initialize(Array
<String
> args
) override
{}
77 void AcceptConnection(const String
& requestor_url
,
78 ServiceProviderPtr provider
) override
{
79 if (initial_response_
) {
80 OnResponseReceived(URLLoaderPtr(), provider
.Pass(),
81 initial_response_
.Pass());
84 network_service_
->CreateURLLoader(GetProxy(&loader
));
85 mojo::URLRequestPtr
request(mojo::URLRequest::New());
87 request
->auto_follow_redirects
= true;
89 // |loader| will be pass to the OnResponseReceived method through a
90 // callback. Because order of evaluation is undefined, a reference to the
91 // raw pointer is needed.
92 mojo::URLLoader
* raw_loader
= loader
.get();
95 base::Bind(&HTMLViewerApplication::OnResponseReceived
,
96 base::Unretained(this), base::Passed(&loader
),
97 base::Passed(&provider
)));
102 void OnResponseReceived(URLLoaderPtr loader
,
103 ServiceProviderPtr provider
,
104 URLResponsePtr response
) {
105 new HTMLDocument(provider
.Pass(), response
.Pass(), shell_
.get(),
106 compositor_thread_
, web_media_player_factory_
);
111 mojo::NetworkServicePtr network_service_
;
112 URLResponsePtr initial_response_
;
113 scoped_refptr
<base::MessageLoopProxy
> compositor_thread_
;
114 WebMediaPlayerFactory
* web_media_player_factory_
;
117 class ContentHandlerImpl
: public mojo::InterfaceImpl
<ContentHandler
> {
119 ContentHandlerImpl(scoped_refptr
<base::MessageLoopProxy
> compositor_thread
,
120 WebMediaPlayerFactory
* web_media_player_factory
)
121 : compositor_thread_(compositor_thread
),
122 web_media_player_factory_(web_media_player_factory
) {}
123 ~ContentHandlerImpl() override
{}
126 // Overridden from ContentHandler:
127 void StartApplication(ShellPtr shell
, URLResponsePtr response
) override
{
128 new HTMLViewerApplication(shell
.Pass(), response
.Pass(), compositor_thread_
,
129 web_media_player_factory_
);
132 scoped_refptr
<base::MessageLoopProxy
> compositor_thread_
;
133 WebMediaPlayerFactory
* web_media_player_factory_
;
135 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl
);
138 class HTMLViewer
: public mojo::ApplicationDelegate
,
139 public mojo::InterfaceFactory
<ContentHandler
> {
141 HTMLViewer() : compositor_thread_("compositor thread") {}
143 ~HTMLViewer() override
{ blink::shutdown(); }
146 // Overridden from ApplicationDelegate:
147 void Initialize(mojo::ApplicationImpl
* app
) override
{
148 blink_platform_
.reset(new MojoBlinkPlatformImpl(app
));
149 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
150 gin::IsolateHolder::LoadV8Snapshot();
152 blink::initialize(blink_platform_
.get());
153 #if !defined(COMPONENT_BUILD)
154 base::i18n::InitializeICU();
156 ui::RegisterPathProvider();
158 base::FilePath ui_test_pak_path
;
159 CHECK(PathService::Get(ui::UI_TEST_PAK
, &ui_test_pak_path
));
160 ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path
);
163 base::CommandLine::StringVector command_line_args
;
165 for (const auto& arg
: app
->args())
166 command_line_args
.push_back(base::UTF8ToUTF16(arg
));
167 #elif defined(OS_POSIX)
168 command_line_args
= app
->args();
171 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
172 command_line
->InitFromArgv(command_line_args
);
174 logging::LoggingSettings settings
;
175 settings
.logging_dest
= logging::LOG_TO_SYSTEM_DEBUG_LOG
;
176 logging::InitLogging(settings
);
177 // Display process ID, thread ID and timestamp in logs.
178 logging::SetLogItems(true, true, true, false);
180 bool enable_mojo_media_renderer
=
181 command_line
->HasSwitch(kEnableMojoMediaRenderer
);
183 if (command_line
->HasSwitch(kEnableEncryptedMedia
))
184 blink::WebRuntimeFeatures::enableEncryptedMedia(true);
186 compositor_thread_
.Start();
187 web_media_player_factory_
.reset(new WebMediaPlayerFactory(
188 compositor_thread_
.message_loop_proxy(), enable_mojo_media_renderer
));
191 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
192 connection
->AddService(this);
196 // Overridden from InterfaceFactory<ContentHandler>
197 void Create(ApplicationConnection
* connection
,
198 mojo::InterfaceRequest
<ContentHandler
> request
) override
{
200 new ContentHandlerImpl(compositor_thread_
.message_loop_proxy(),
201 web_media_player_factory_
.get()),
205 scoped_ptr
<MojoBlinkPlatformImpl
> blink_platform_
;
206 base::Thread compositor_thread_
;
207 scoped_ptr
<WebMediaPlayerFactory
> web_media_player_factory_
;
209 DISALLOW_COPY_AND_ASSIGN(HTMLViewer
);
212 } // namespace html_viewer
214 MojoResult
MojoMain(MojoHandle shell_handle
) {
215 mojo::ApplicationRunnerChromium
runner(new html_viewer::HTMLViewer
);
216 return runner
.Run(shell_handle
);