1 // Copyright 2015 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/html_document_application_delegate.h"
8 #include "components/html_viewer/global_state.h"
9 #include "components/html_viewer/html_document_oopif.h"
10 #include "mojo/application/public/cpp/application_connection.h"
11 #include "mojo/application/public/cpp/application_delegate.h"
12 #include "mojo/application/public/cpp/connect.h"
14 namespace html_viewer
{
18 HTMLFrame
* CreateHTMLFrame(HTMLFrame::CreateParams
* params
) {
19 return new HTMLFrame(params
);
24 // ServiceConnectorQueue records all incoming service requests and processes
25 // them once PushRequestsTo() is called. This is useful if you need to delay
26 // processing incoming service requests.
27 class HTMLDocumentApplicationDelegate::ServiceConnectorQueue
28 : public mojo::ServiceConnector
{
30 ServiceConnectorQueue() {}
31 ~ServiceConnectorQueue() override
{}
33 void PushRequestsTo(mojo::ApplicationConnection
* connection
) {
34 ScopedVector
<Request
> requests
;
35 requests_
.swap(requests
);
36 for (Request
* request
: requests
) {
37 connection
->GetLocalServiceProvider()->ConnectToService(
38 request
->interface_name
, request
->handle
.Pass());
44 std::string interface_name
;
45 mojo::ScopedMessagePipeHandle handle
;
48 // mojo::ServiceConnector:
49 void ConnectToService(mojo::ApplicationConnection
* application_connection
,
50 const std::string
& interface_name
,
51 mojo::ScopedMessagePipeHandle handle
) override
{
52 scoped_ptr
<Request
> request(new Request
);
53 request
->interface_name
= interface_name
;
54 request
->handle
= handle
.Pass();
55 requests_
.push_back(request
.Pass());
58 ScopedVector
<Request
> requests_
;
60 DISALLOW_COPY_AND_ASSIGN(ServiceConnectorQueue
);
63 HTMLDocumentApplicationDelegate::HTMLDocumentApplicationDelegate(
64 mojo::InterfaceRequest
<mojo::Application
> request
,
65 mojo::URLResponsePtr response
,
66 GlobalState
* global_state
,
67 scoped_ptr
<mojo::AppRefCount
> parent_app_refcount
)
70 base::Bind(&HTMLDocumentApplicationDelegate::OnTerminate
,
71 base::Unretained(this))),
72 parent_app_refcount_(parent_app_refcount
.Pass()),
74 initial_response_(response
.Pass()),
75 global_state_(global_state
),
76 html_frame_creation_callback_(base::Bind(CreateHTMLFrame
)),
77 weak_factory_(this) {}
79 HTMLDocumentApplicationDelegate::~HTMLDocumentApplicationDelegate() {
80 // Deleting the documents is going to trigger a callback to
81 // OnHTMLDocumentDeleted() and remove from |documents_|. Copy the set so we
82 // don't have to worry about the set being modified out from under us.
83 std::set
<HTMLDocumentOOPIF
*> documents2(documents2_
);
84 for (HTMLDocumentOOPIF
* doc
: documents2
)
86 DCHECK(documents2_
.empty());
89 void HTMLDocumentApplicationDelegate::SetHTMLFrameCreationCallback(
90 const HTMLFrameCreationCallback
& callback
) {
91 html_frame_creation_callback_
= callback
;
94 // Callback from the quit closure. We key off this rather than
95 // ApplicationDelegate::Quit() as we don't want to shut down the messageloop
96 // when we quit (the messageloop is shared among multiple
97 // HTMLDocumentApplicationDelegates).
98 void HTMLDocumentApplicationDelegate::OnTerminate() {
102 // ApplicationDelegate;
103 void HTMLDocumentApplicationDelegate::Initialize(mojo::ApplicationImpl
* app
) {
104 mojo::URLRequestPtr
request(mojo::URLRequest::New());
105 request
->url
= mojo::String::From("mojo:network_service");
106 scoped_ptr
<mojo::ApplicationConnection
> connection
=
107 app_
.ConnectToApplication(request
.Pass());
108 connection
->ConnectToService(&url_loader_factory_
);
111 bool HTMLDocumentApplicationDelegate::ConfigureIncomingConnection(
112 mojo::ApplicationConnection
* connection
) {
113 if (initial_response_
) {
114 OnResponseReceived(mojo::URLLoaderPtr(), connection
, nullptr,
115 initial_response_
.Pass());
117 // HTMLDocument provides services, but is created asynchronously. Queue up
118 // requests until the HTMLDocument is created.
119 scoped_ptr
<ServiceConnectorQueue
> service_connector_queue(
120 new ServiceConnectorQueue
);
121 connection
->SetServiceConnector(service_connector_queue
.get());
123 mojo::URLLoaderPtr loader
;
124 url_loader_factory_
->CreateURLLoader(GetProxy(&loader
));
125 mojo::URLRequestPtr
request(mojo::URLRequest::New());
127 request
->auto_follow_redirects
= true;
129 // |loader| will be passed to the OnResponseReceived method through a
130 // callback. Because order of evaluation is undefined, a reference to the
131 // raw pointer is needed.
132 mojo::URLLoader
* raw_loader
= loader
.get();
135 base::Bind(&HTMLDocumentApplicationDelegate::OnResponseReceived
,
136 weak_factory_
.GetWeakPtr(), base::Passed(&loader
),
137 connection
, base::Passed(&service_connector_queue
)));
142 void HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2(
143 HTMLDocumentOOPIF
* document
) {
144 DCHECK(documents2_
.count(document
) > 0);
145 documents2_
.erase(document
);
148 void HTMLDocumentApplicationDelegate::OnResponseReceived(
149 mojo::URLLoaderPtr loader
,
150 mojo::ApplicationConnection
* connection
,
151 scoped_ptr
<ServiceConnectorQueue
> connector_queue
,
152 mojo::URLResponsePtr response
) {
153 // HTMLDocument is destroyed when the hosting view is destroyed, or
154 // explicitly from our destructor.
155 HTMLDocumentOOPIF
* document
= new HTMLDocumentOOPIF(
156 &app_
, connection
, response
.Pass(), global_state_
,
157 base::Bind(&HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2
,
158 base::Unretained(this)),
159 html_frame_creation_callback_
);
160 documents2_
.insert(document
);
162 if (connector_queue
) {
163 connector_queue
->PushRequestsTo(connection
);
164 connection
->SetServiceConnector(nullptr);
168 } // namespace html_viewer