Add GN isolate support for a bunch of unittests.
[chromium-blink-merge.git] / components / html_viewer / html_document_application_delegate.cc
blob8638640167463b9cce2f6cacbe8d720b6d9a74d0
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"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "components/html_viewer/global_state.h"
10 #include "components/html_viewer/html_document_oopif.h"
11 #include "components/html_viewer/html_viewer_switches.h"
12 #include "mojo/application/public/cpp/application_connection.h"
13 #include "mojo/application/public/cpp/application_delegate.h"
14 #include "mojo/application/public/cpp/connect.h"
16 namespace html_viewer {
18 namespace {
20 bool EnableOOPIFs() {
21 return base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kOOPIF);
24 HTMLDocument* CreateHTMLDocument(HTMLDocument::CreateParams* params) {
25 return new HTMLDocument(params);
28 } // namespace
30 // ServiceConnectorQueue records all incoming service requests and processes
31 // them once PushRequestsTo() is called. This is useful if you need to delay
32 // processing incoming service requests.
33 class HTMLDocumentApplicationDelegate::ServiceConnectorQueue
34 : public mojo::ServiceConnector {
35 public:
36 ServiceConnectorQueue() {}
37 ~ServiceConnectorQueue() override {}
39 void PushRequestsTo(mojo::ApplicationConnection* connection) {
40 ScopedVector<Request> requests;
41 requests_.swap(requests);
42 for (Request* request : requests) {
43 connection->GetLocalServiceProvider()->ConnectToService(
44 request->interface_name, request->handle.Pass());
48 private:
49 struct Request {
50 std::string interface_name;
51 mojo::ScopedMessagePipeHandle handle;
54 // mojo::ServiceConnector:
55 void ConnectToService(mojo::ApplicationConnection* application_connection,
56 const std::string& interface_name,
57 mojo::ScopedMessagePipeHandle handle) override {
58 scoped_ptr<Request> request(new Request);
59 request->interface_name = interface_name;
60 request->handle = handle.Pass();
61 requests_.push_back(request.Pass());
64 ScopedVector<Request> requests_;
66 DISALLOW_COPY_AND_ASSIGN(ServiceConnectorQueue);
69 HTMLDocumentApplicationDelegate::HTMLDocumentApplicationDelegate(
70 mojo::InterfaceRequest<mojo::Application> request,
71 mojo::URLResponsePtr response,
72 GlobalState* global_state,
73 scoped_ptr<mojo::AppRefCount> parent_app_refcount)
74 : app_(this,
75 request.Pass(),
76 base::Bind(&HTMLDocumentApplicationDelegate::OnTerminate,
77 base::Unretained(this))),
78 parent_app_refcount_(parent_app_refcount.Pass()),
79 url_(response->url),
80 initial_response_(response.Pass()),
81 global_state_(global_state),
82 html_document_creation_callback_(base::Bind(CreateHTMLDocument)) {
85 HTMLDocumentApplicationDelegate::~HTMLDocumentApplicationDelegate() {
86 // Deleting the documents is going to trigger a callback to
87 // OnHTMLDocumentDeleted() and remove from |documents_|. Copy the set so we
88 // don't have to worry about the set being modified out from under us.
89 std::set<HTMLDocument*> documents(documents_);
90 for (HTMLDocument* doc : documents)
91 doc->Destroy();
92 DCHECK(documents_.empty());
94 std::set<HTMLDocumentOOPIF*> documents2(documents2_);
95 for (HTMLDocumentOOPIF* doc : documents2)
96 doc->Destroy();
97 DCHECK(documents2_.empty());
100 void HTMLDocumentApplicationDelegate::SetHTMLDocumentCreationCallback(
101 const HTMLDocumentCreationCallback& callback) {
102 html_document_creation_callback_ = callback;
105 // Callback from the quit closure. We key off this rather than
106 // ApplicationDelegate::Quit() as we don't want to shut down the messageloop
107 // when we quit (the messageloop is shared among multiple
108 // HTMLDocumentApplicationDelegates).
109 void HTMLDocumentApplicationDelegate::OnTerminate() {
110 delete this;
113 // ApplicationDelegate;
114 void HTMLDocumentApplicationDelegate::Initialize(mojo::ApplicationImpl* app) {
115 mojo::URLRequestPtr request(mojo::URLRequest::New());
116 request->url = mojo::String::From("mojo:network_service");
117 mojo::ApplicationConnection* connection =
118 app_.ConnectToApplication(request.Pass());
119 connection->ConnectToService(&network_service_);
120 connection->ConnectToService(&url_loader_factory_);
123 bool HTMLDocumentApplicationDelegate::ConfigureIncomingConnection(
124 mojo::ApplicationConnection* connection) {
125 if (initial_response_) {
126 OnResponseReceived(mojo::URLLoaderPtr(), connection, nullptr,
127 initial_response_.Pass());
128 } else {
129 // HTMLDocument provides services, but is created asynchronously. Queue up
130 // requests until the HTMLDocument is created.
131 scoped_ptr<ServiceConnectorQueue> service_connector_queue(
132 new ServiceConnectorQueue);
133 connection->SetServiceConnector(service_connector_queue.get());
135 mojo::URLLoaderPtr loader;
136 url_loader_factory_->CreateURLLoader(GetProxy(&loader));
137 mojo::URLRequestPtr request(mojo::URLRequest::New());
138 request->url = url_;
139 request->auto_follow_redirects = true;
141 // |loader| will be passed to the OnResponseReceived method through a
142 // callback. Because order of evaluation is undefined, a reference to the
143 // raw pointer is needed.
144 mojo::URLLoader* raw_loader = loader.get();
145 raw_loader->Start(
146 request.Pass(),
147 base::Bind(&HTMLDocumentApplicationDelegate::OnResponseReceived,
148 base::Unretained(this), base::Passed(&loader), connection,
149 base::Passed(&service_connector_queue)));
151 return true;
154 void HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted(
155 HTMLDocument* document) {
156 DCHECK(documents_.count(document) > 0);
157 documents_.erase(document);
160 void HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2(
161 HTMLDocumentOOPIF* document) {
162 DCHECK(documents2_.count(document) > 0);
163 documents2_.erase(document);
166 void HTMLDocumentApplicationDelegate::OnResponseReceived(
167 mojo::URLLoaderPtr loader,
168 mojo::ApplicationConnection* connection,
169 scoped_ptr<ServiceConnectorQueue> connector_queue,
170 mojo::URLResponsePtr response) {
171 // HTMLDocument is destroyed when the hosting view is destroyed, or
172 // explicitly from our destructor.
173 if (EnableOOPIFs()) {
174 HTMLDocumentOOPIF* document = new HTMLDocumentOOPIF(
175 &app_, connection, response.Pass(), global_state_,
176 base::Bind(&HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2,
177 base::Unretained(this)));
178 documents2_.insert(document);
179 } else {
180 HTMLDocument::CreateParams params(
181 &app_, connection, response.Pass(), global_state_,
182 base::Bind(&HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted,
183 base::Unretained(this)));
184 HTMLDocument* document = html_document_creation_callback_.Run(&params);
185 documents_.insert(document);
188 if (connector_queue) {
189 connector_queue->PushRequestsTo(connection);
190 connection->SetServiceConnector(nullptr);
194 } // namespace html_viewer