Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: components/html_viewer/html_document_application_delegate.cc

Issue 1677293002: Bye bye Mandoline (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moar Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "components/html_viewer/html_document_application_delegate.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/macros.h"
11 #include "components/html_viewer/global_state.h"
12 #include "components/html_viewer/html_document.h"
13 #include "mojo/shell/public/cpp/shell_client.h"
14
15 namespace html_viewer {
16
17 // ServiceConnectorQueue records all incoming service requests and processes
18 // them once PushRequestsTo() is called. This is useful if you need to delay
19 // processing incoming service requests.
20 class HTMLDocumentApplicationDelegate::ServiceConnectorQueue
21 : public mojo::ServiceConnector {
22 public:
23 ServiceConnectorQueue() {}
24 ~ServiceConnectorQueue() override {}
25
26 void PushRequestsTo(mojo::Connection* connection) {
27 ScopedVector<Request> requests;
28 requests_.swap(requests);
29 for (Request* request : requests) {
30 connection->GetLocalServiceProvider()->ConnectToService(
31 request->interface_name, std::move(request->handle));
32 }
33 }
34
35 private:
36 struct Request {
37 std::string interface_name;
38 mojo::ScopedMessagePipeHandle handle;
39 };
40
41 // mojo::ServiceConnector:
42 void ConnectToService(mojo::Connection* connection,
43 const std::string& interface_name,
44 mojo::ScopedMessagePipeHandle handle) override {
45 scoped_ptr<Request> request(new Request);
46 request->interface_name = interface_name;
47 request->handle = std::move(handle);
48 requests_.push_back(std::move(request));
49 }
50
51 ScopedVector<Request> requests_;
52
53 DISALLOW_COPY_AND_ASSIGN(ServiceConnectorQueue);
54 };
55
56 HTMLDocumentApplicationDelegate::HTMLDocumentApplicationDelegate(
57 mojo::ApplicationRequest request,
58 mojo::URLResponsePtr response,
59 GlobalState* global_state,
60 scoped_ptr<mojo::AppRefCount> parent_app_refcount,
61 const mojo::Callback<void()>& destruct_callback)
62 : app_(this,
63 std::move(request),
64 base::Bind(&HTMLDocumentApplicationDelegate::OnTerminate,
65 base::Unretained(this))),
66 parent_app_refcount_(std::move(parent_app_refcount)),
67 url_(response->url),
68 initial_response_(std::move(response)),
69 global_state_(global_state),
70 html_factory_(this),
71 destruct_callback_(destruct_callback),
72 weak_factory_(this) {}
73
74 HTMLDocumentApplicationDelegate::~HTMLDocumentApplicationDelegate() {
75 // Deleting the documents is going to trigger a callback to
76 // OnHTMLDocumentDeleted() and remove from |documents_|. Copy the set so we
77 // don't have to worry about the set being modified out from under us.
78 std::set<HTMLDocument*> documents2(documents2_);
79 for (HTMLDocument* doc : documents2)
80 doc->Destroy();
81 DCHECK(documents2_.empty());
82 destruct_callback_.Run();
83 }
84
85 // Callback from the quit closure. We key off this rather than
86 // mojo::ShellClient::Quit() as we don't want to shut down the messageloop
87 // when we quit (the messageloop is shared among multiple
88 // HTMLDocumentApplicationDelegates).
89 void HTMLDocumentApplicationDelegate::OnTerminate() {
90 delete this;
91 }
92
93 // mojo::ShellClient;
94 void HTMLDocumentApplicationDelegate::Initialize(mojo::Shell* shell,
95 const std::string& url,
96 uint32_t id) {
97 app_.ConnectToService("mojo:network_service", &url_loader_factory_);
98 }
99
100 bool HTMLDocumentApplicationDelegate::AcceptConnection(
101 mojo::Connection* connection) {
102 if (initial_response_) {
103 OnResponseReceived(nullptr, mojo::URLLoaderPtr(), connection, nullptr,
104 std::move(initial_response_));
105 } else if (url_ == "about:blank") {
106 // This is a little unfortunate. At the browser side, when starting a new
107 // app for "about:blank", the application manager uses
108 // mojo::shell::AboutFetcher to construct a response for "about:blank".
109 // However, when an app for "about:blank" already exists, it is reused and
110 // we end up here. We cannot fetch the URL using mojo::URLLoader because it
111 // is not an actual Web resource.
112 // TODO(yzshen): find out a better approach.
113 mojo::URLResponsePtr response(mojo::URLResponse::New());
114 response->url = url_;
115 response->status_code = 200;
116 response->mime_type = "text/html";
117 OnResponseReceived(nullptr, mojo::URLLoaderPtr(), connection, nullptr,
118 std::move(response));
119 } else {
120 // HTMLDocument provides services, but is created asynchronously. Queue up
121 // requests until the HTMLDocument is created.
122 scoped_ptr<ServiceConnectorQueue> service_connector_queue(
123 new ServiceConnectorQueue);
124 connection->SetServiceConnector(service_connector_queue.get());
125
126 mojo::URLLoaderPtr loader;
127 url_loader_factory_->CreateURLLoader(GetProxy(&loader));
128 mojo::URLRequestPtr request(mojo::URLRequest::New());
129 request->url = url_;
130 request->auto_follow_redirects = true;
131
132 // |loader| will be passed to the OnResponseReceived method through a
133 // callback. Because order of evaluation is undefined, a reference to the
134 // raw pointer is needed.
135 mojo::URLLoader* raw_loader = loader.get();
136 // The app needs to stay alive while waiting for the response to be
137 // available.
138 scoped_ptr<mojo::AppRefCount> app_retainer(app_.CreateAppRefCount());
139 raw_loader->Start(
140 std::move(request),
141 base::Bind(&HTMLDocumentApplicationDelegate::OnResponseReceived,
142 weak_factory_.GetWeakPtr(), base::Passed(&app_retainer),
143 base::Passed(&loader), connection,
144 base::Passed(&service_connector_queue)));
145 }
146 return true;
147 }
148
149 void HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2(
150 HTMLDocument* document) {
151 DCHECK(documents2_.count(document) > 0);
152 documents2_.erase(document);
153 }
154
155 void HTMLDocumentApplicationDelegate::OnResponseReceived(
156 scoped_ptr<mojo::AppRefCount> app_refcount,
157 mojo::URLLoaderPtr loader,
158 mojo::Connection* connection,
159 scoped_ptr<ServiceConnectorQueue> connector_queue,
160 mojo::URLResponsePtr response) {
161 // HTMLDocument is destroyed when the hosting view is destroyed, or
162 // explicitly from our destructor.
163 HTMLDocument* document = new HTMLDocument(
164 &app_, connection, std::move(response), global_state_,
165 base::Bind(&HTMLDocumentApplicationDelegate::OnHTMLDocumentDeleted2,
166 base::Unretained(this)),
167 html_factory_);
168 documents2_.insert(document);
169
170 if (connector_queue) {
171 connector_queue->PushRequestsTo(connection);
172 connection->SetServiceConnector(nullptr);
173 }
174 }
175
176 HTMLFrame* HTMLDocumentApplicationDelegate::CreateHTMLFrame(
177 HTMLFrame::CreateParams* params) {
178 return new HTMLFrame(params);
179 }
180
181 HTMLWidgetRootLocal* HTMLDocumentApplicationDelegate::CreateHTMLWidgetRootLocal(
182 HTMLWidgetRootLocal::CreateParams* params) {
183 return new HTMLWidgetRootLocal(params);
184 }
185
186 } // namespace html_viewer
OLDNEW
« no previous file with comments | « components/html_viewer/html_document_application_delegate.h ('k') | components/html_viewer/html_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698