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.
6 #include "base/command_line.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 "components/html_viewer/html_document.h"
13 #include "components/html_viewer/setup.h"
14 #include "mojo/application/public/cpp/application_connection.h"
15 #include "mojo/application/public/cpp/application_delegate.h"
16 #include "mojo/application/public/cpp/application_impl.h"
17 #include "mojo/application/public/cpp/application_runner.h"
18 #include "mojo/application/public/cpp/connect.h"
19 #include "mojo/application/public/cpp/interface_factory_impl.h"
20 #include "mojo/application/public/interfaces/content_handler.mojom.h"
21 #include "mojo/common/common_type_converters.h"
22 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
23 #include "mojo/services/network/public/interfaces/url_loader_factory.mojom.h"
24 #include "third_party/WebKit/public/web/WebKit.h"
25 #include "third_party/mojo/src/mojo/public/c/system/main.h"
26 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
28 using mojo::ApplicationConnection
;
30 using mojo::BindToRequest
;
31 using mojo::ContentHandler
;
32 using mojo::InterfaceRequest
;
33 using mojo::ServiceProvider
;
34 using mojo::ServiceProviderPtr
;
37 using mojo::URLLoaderPtr
;
38 using mojo::URLResponsePtr
;
40 namespace html_viewer
{
44 // ApplicationDelegate created by the content handler for a specific url.
45 class HTMLDocumentApplicationDelegate
: public mojo::ApplicationDelegate
{
47 HTMLDocumentApplicationDelegate(
48 mojo::InterfaceRequest
<mojo::Application
> request
,
49 mojo::URLResponsePtr response
,
51 scoped_ptr
<mojo::AppRefCount
> parent_app_refcount
)
54 base::Bind(&HTMLDocumentApplicationDelegate::OnTerminate
,
55 base::Unretained(this))),
56 parent_app_refcount_(parent_app_refcount
.Pass()),
58 initial_response_(response
.Pass()),
62 ~HTMLDocumentApplicationDelegate() override
{}
64 // Callback from the quit closure. We key off this rather than
65 // ApplicationDelegate::Quit() as we don't want to shut down the messageloop
66 // when we quit (the messageloop is shared among multiple
67 // HTMLDocumentApplicationDelegates).
72 // ApplicationDelegate;
73 void Initialize(mojo::ApplicationImpl
* app
) override
{
74 mojo::URLRequestPtr
request(mojo::URLRequest::New());
75 request
->url
= mojo::String::From("mojo:network_service");
76 mojo::ApplicationConnection
* connection
=
77 app_
.ConnectToApplication(request
.Pass());
78 connection
->ConnectToService(&network_service_
);
79 connection
->ConnectToService(&url_loader_factory_
);
81 bool ConfigureIncomingConnection(
82 mojo::ApplicationConnection
* connection
) override
{
83 if (initial_response_
) {
84 OnResponseReceived(URLLoaderPtr(), connection
, initial_response_
.Pass());
87 url_loader_factory_
->CreateURLLoader(GetProxy(&loader
));
88 mojo::URLRequestPtr
request(mojo::URLRequest::New());
90 request
->auto_follow_redirects
= true;
92 // |loader| will be passed to the OnResponseReceived method through a
93 // callback. Because order of evaluation is undefined, a reference to the
94 // raw pointer is needed.
95 mojo::URLLoader
* raw_loader
= loader
.get();
98 base::Bind(&HTMLDocumentApplicationDelegate::OnResponseReceived
,
99 base::Unretained(this), base::Passed(&loader
),
105 void OnResponseReceived(URLLoaderPtr loader
,
106 mojo::ApplicationConnection
* connection
,
107 URLResponsePtr response
) {
108 // HTMLDocument is destroyed when the hosting view is destroyed.
109 // TODO(sky): when headless, this leaks.
110 // TODO(sky): this needs to delete if serviceprovider goes away too.
111 new HTMLDocument(&app_
, connection
, response
.Pass(), setup_
);
114 mojo::ApplicationImpl app_
;
115 // AppRefCount of the parent (HTMLViewer).
116 scoped_ptr
<mojo::AppRefCount
> parent_app_refcount_
;
118 mojo::NetworkServicePtr network_service_
;
119 mojo::URLLoaderFactoryPtr url_loader_factory_
;
120 URLResponsePtr initial_response_
;
123 DISALLOW_COPY_AND_ASSIGN(HTMLDocumentApplicationDelegate
);
126 class ContentHandlerImpl
: public mojo::ContentHandler
{
128 ContentHandlerImpl(Setup
* setup
,
129 mojo::ApplicationImpl
* app
,
130 mojo::InterfaceRequest
<ContentHandler
> request
)
131 : setup_(setup
), app_(app
), binding_(this, request
.Pass()) {}
132 ~ContentHandlerImpl() override
{}
135 // Overridden from ContentHandler:
136 void StartApplication(InterfaceRequest
<mojo::Application
> request
,
137 URLResponsePtr response
) override
{
138 // HTMLDocumentApplicationDelegate deletes itself.
139 new HTMLDocumentApplicationDelegate(
140 request
.Pass(), response
.Pass(), setup_
,
141 app_
->app_lifetime_helper()->CreateAppRefCount());
145 mojo::ApplicationImpl
* app_
;
146 mojo::StrongBinding
<mojo::ContentHandler
> binding_
;
148 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl
);
151 class HTMLViewer
: public mojo::ApplicationDelegate
,
152 public mojo::InterfaceFactory
<ContentHandler
> {
154 HTMLViewer() : app_(nullptr) {}
155 ~HTMLViewer() override
{}
158 // Overridden from ApplicationDelegate:
159 void Initialize(mojo::ApplicationImpl
* app
) override
{
161 setup_
.reset(new Setup(app
));
164 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
165 connection
->AddService(this);
169 // Overridden from InterfaceFactory<ContentHandler>
170 void Create(ApplicationConnection
* connection
,
171 mojo::InterfaceRequest
<ContentHandler
> request
) override
{
172 new ContentHandlerImpl(setup_
.get(), app_
, request
.Pass());
175 scoped_ptr
<Setup
> setup_
;
176 mojo::ApplicationImpl
* app_
;
178 DISALLOW_COPY_AND_ASSIGN(HTMLViewer
);
181 } // namespace html_viewer
183 MojoResult
MojoMain(MojoHandle shell_handle
) {
184 mojo::ApplicationRunner
runner(new html_viewer::HTMLViewer
);
185 return runner
.Run(shell_handle
);