Inline NetLog IPv6 reachability events.
[chromium-blink-merge.git] / components / html_viewer / html_viewer.cc
blobd71d04355d7b965a547ae64c8d3ceecae647b2f2
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;
34 using mojo::Array;
35 using mojo::BindToRequest;
36 using mojo::ContentHandler;
37 using mojo::InterfaceRequest;
38 using mojo::ServiceProvider;
39 using mojo::ServiceProviderPtr;
40 using mojo::ShellPtr;
41 using mojo::String;
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;
61 class HTMLViewer;
63 class HTMLViewerApplication : public mojo::Application {
64 public:
65 HTMLViewerApplication(InterfaceRequest<Application> request,
66 URLResponsePtr response,
67 scoped_refptr<base::MessageLoopProxy> compositor_thread,
68 WebMediaPlayerFactory* web_media_player_factory,
69 bool is_headless)
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,
78 Array<String> args,
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());
94 } else {
95 URLLoaderPtr loader;
96 network_service_->CreateURLLoader(GetProxy(&loader));
97 mojo::URLRequestPtr request(mojo::URLRequest::New());
98 request->url = url_;
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();
105 raw_loader->Start(
106 request.Pass(),
107 base::Bind(&HTMLViewerApplication::OnResponseReceived,
108 base::Unretained(this), base::Passed(&loader),
109 base::Passed(&services)));
113 void RequestQuit() override {}
115 private:
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_,
121 is_headless_);
124 String url_;
125 mojo::StrongBinding<mojo::Application> binding_;
126 ShellPtr shell_;
127 mojo::NetworkServicePtr network_service_;
128 URLResponsePtr initial_response_;
129 scoped_refptr<base::MessageLoopProxy> compositor_thread_;
130 WebMediaPlayerFactory* web_media_player_factory_;
131 bool is_headless_;
134 class ContentHandlerImpl : public mojo::InterfaceImpl<ContentHandler> {
135 public:
136 ContentHandlerImpl(scoped_refptr<base::MessageLoopProxy> compositor_thread,
137 WebMediaPlayerFactory* web_media_player_factory,
138 bool is_headless)
139 : compositor_thread_(compositor_thread),
140 web_media_player_factory_(web_media_player_factory),
141 is_headless_(is_headless) {}
142 ~ContentHandlerImpl() override {}
144 private:
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_,
150 is_headless_);
153 scoped_refptr<base::MessageLoopProxy> compositor_thread_;
154 WebMediaPlayerFactory* web_media_player_factory_;
155 bool is_headless_;
157 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl);
160 class HTMLViewer : public mojo::ApplicationDelegate,
161 public mojo::InterfaceFactory<ContentHandler> {
162 public:
163 HTMLViewer()
164 : discardable_memory_allocator_(kDesiredMaxMemory),
165 compositor_thread_("compositor thread") {}
167 ~HTMLViewer() override { blink::shutdown(); }
169 private:
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();
179 #endif
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);
197 if (!is_headless_) {
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.
208 NOTIMPLEMENTED();
209 #else
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));
215 #endif
218 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
219 connection->AddService(this);
220 return true;
223 // Overridden from InterfaceFactory<ContentHandler>
224 void Create(ApplicationConnection* connection,
225 mojo::InterfaceRequest<ContentHandler> request) override {
226 BindToRequest(
227 new ContentHandlerImpl(compositor_thread_.message_loop_proxy(),
228 web_media_player_factory_.get(), is_headless_),
229 &request);
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.
244 bool is_headless_;
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);