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

Side by Side Diff: components/html_viewer/html_document.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 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.
4
5 #include "components/html_viewer/html_document.h"
6
7 #include <utility>
8
9 #include "base/command_line.h"
10 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "components/html_viewer/blink_url_request_type_converters.h"
18 #include "components/html_viewer/devtools_agent_impl.h"
19 #include "components/html_viewer/document_resource_waiter.h"
20 #include "components/html_viewer/global_state.h"
21 #include "components/html_viewer/html_frame.h"
22 #include "components/html_viewer/html_frame_tree_manager.h"
23 #include "components/html_viewer/test_html_viewer_impl.h"
24 #include "components/html_viewer/web_url_loader_impl.h"
25 #include "components/mus/public/cpp/window.h"
26 #include "components/mus/public/cpp/window_tree_connection.h"
27 #include "components/mus/ws/ids.h"
28 #include "mojo/converters/geometry/geometry_type_converters.h"
29 #include "mojo/public/cpp/system/data_pipe.h"
30 #include "mojo/shell/public/cpp/application_impl.h"
31 #include "mojo/shell/public/interfaces/shell.mojom.h"
32 #include "third_party/WebKit/public/web/WebLocalFrame.h"
33 #include "ui/gfx/geometry/dip_util.h"
34 #include "ui/gfx/geometry/size.h"
35
36 using mojo::AxProvider;
37 using mus::Window;
38
39 namespace html_viewer {
40 namespace {
41
42 const char kEnableTestInterface[] = "enable-html-viewer-test-interface";
43
44 bool IsTestInterfaceEnabled() {
45 return base::CommandLine::ForCurrentProcess()->HasSwitch(
46 kEnableTestInterface);
47 }
48
49 } // namespace
50
51 // A WindowTreeDelegate implementation that delegates to a (swappable) delegate.
52 // This is used when one HTMLDocument takes over for another delegate
53 // (OnSwap()).
54 class WindowTreeDelegateImpl : public mus::WindowTreeDelegate {
55 public:
56 explicit WindowTreeDelegateImpl(mus::WindowTreeDelegate* delegate)
57 : delegate_(delegate) {}
58 ~WindowTreeDelegateImpl() override {}
59
60 void set_delegate(mus::WindowTreeDelegate* delegate) { delegate_ = delegate; }
61
62 private:
63 // WindowTreeDelegate:
64 void OnEmbed(mus::Window* root) override { delegate_->OnEmbed(root); }
65 void OnUnembed(mus::Window* root) override { delegate_->OnUnembed(root); }
66 void OnConnectionLost(mus::WindowTreeConnection* connection) override {
67 delegate_->OnConnectionLost(connection);
68 }
69
70 mus::WindowTreeDelegate* delegate_;
71
72 DISALLOW_COPY_AND_ASSIGN(WindowTreeDelegateImpl);
73 };
74
75 HTMLDocument::BeforeLoadCache::BeforeLoadCache() {}
76
77 HTMLDocument::BeforeLoadCache::~BeforeLoadCache() {
78 STLDeleteElements(&ax_provider_requests);
79 STLDeleteElements(&test_interface_requests);
80 }
81
82 HTMLDocument::TransferableState::TransferableState()
83 : owns_window_tree_connection(false), root(nullptr) {}
84
85 HTMLDocument::TransferableState::~TransferableState() {}
86
87 void HTMLDocument::TransferableState::Move(TransferableState* other) {
88 owns_window_tree_connection = other->owns_window_tree_connection;
89 root = other->root;
90 window_tree_delegate_impl = std::move(other->window_tree_delegate_impl);
91
92 other->root = nullptr;
93 other->owns_window_tree_connection = false;
94 }
95
96 HTMLDocument::HTMLDocument(mojo::Shell* html_document_shell,
97 mojo::Connection* connection,
98 mojo::URLResponsePtr response,
99 GlobalState* global_state,
100 const DeleteCallback& delete_callback,
101 HTMLFactory* factory)
102 : app_refcount_(html_document_shell->CreateAppRefCount()),
103 html_document_shell_(html_document_shell),
104 connection_(connection),
105 global_state_(global_state),
106 frame_(nullptr),
107 delete_callback_(delete_callback),
108 factory_(factory) {
109 connection->AddService<web_view::mojom::FrameClient>(this);
110 connection->AddService<AxProvider>(this);
111 connection->AddService<mus::mojom::WindowTreeClient>(this);
112 connection->AddService<devtools_service::DevToolsAgent>(this);
113 if (IsTestInterfaceEnabled())
114 connection->AddService<TestHTMLViewer>(this);
115
116 resource_waiter_.reset(
117 new DocumentResourceWaiter(global_state_, std::move(response), this));
118 }
119
120 void HTMLDocument::Destroy() {
121 TRACE_EVENT0("html_viewer", "HTMLDocument::Destroy");
122 if (resource_waiter_) {
123 mus::Window* root = resource_waiter_->root();
124 if (root) {
125 resource_waiter_.reset();
126 delete root->connection();
127 } else {
128 delete this;
129 }
130 } else if (frame_) {
131 // Closing the frame ends up destroying the ViewManager, which triggers
132 // deleting this (OnConnectionLost()).
133 frame_->Close();
134 } else if (transferable_state_.root) {
135 // This triggers deleting us.
136 if (transferable_state_.owns_window_tree_connection)
137 delete transferable_state_.root->connection();
138 else
139 delete this;
140 } else {
141 delete this;
142 }
143 }
144
145 HTMLDocument::~HTMLDocument() {
146 delete_callback_.Run(this);
147
148 STLDeleteElements(&ax_providers_);
149 }
150
151 void HTMLDocument::Load() {
152 TRACE_EVENT0("html_viewer", "HTMLDocument::Load");
153 DCHECK(resource_waiter_ && resource_waiter_->is_ready());
154
155 // Note: |window| is null if we're taking over for an existing frame.
156 mus::Window* window = resource_waiter_->root();
157 if (window) {
158 global_state_->InitIfNecessary(
159 window->viewport_metrics().size_in_pixels.To<gfx::Size>(),
160 window->viewport_metrics().device_pixel_ratio);
161 }
162
163 scoped_ptr<WebURLRequestExtraData> extra_data(new WebURLRequestExtraData);
164 extra_data->synthetic_response = resource_waiter_->ReleaseURLResponse();
165
166 base::TimeTicks navigation_start_time =
167 resource_waiter_->navigation_start_time();
168 frame_ = HTMLFrameTreeManager::CreateFrameAndAttachToTree(
169 global_state_, window, std::move(resource_waiter_), this);
170
171 // If the frame wasn't created we can destroy ourself.
172 if (!frame_) {
173 Destroy();
174 return;
175 }
176
177 if (devtools_agent_request_.is_pending()) {
178 if (frame_->devtools_agent()) {
179 frame_->devtools_agent()->BindToRequest(
180 std::move(devtools_agent_request_));
181 } else {
182 devtools_agent_request_ =
183 mojo::InterfaceRequest<devtools_service::DevToolsAgent>();
184 }
185 }
186
187 const GURL url(extra_data->synthetic_response->url.get());
188
189 blink::WebURLRequest web_request;
190 web_request.initialize();
191 web_request.setURL(url);
192 web_request.setExtraData(extra_data.release());
193
194 frame_->LoadRequest(web_request, navigation_start_time);
195 }
196
197 HTMLDocument::BeforeLoadCache* HTMLDocument::GetBeforeLoadCache() {
198 CHECK(!did_finish_local_frame_load_);
199 if (!before_load_cache_.get())
200 before_load_cache_.reset(new BeforeLoadCache);
201 return before_load_cache_.get();
202 }
203
204 void HTMLDocument::OnEmbed(Window* root) {
205 transferable_state_.root = root;
206 resource_waiter_->SetRoot(root);
207 }
208
209 void HTMLDocument::OnConnectionLost(mus::WindowTreeConnection* connection) {
210 delete this;
211 }
212
213 void HTMLDocument::OnFrameDidFinishLoad() {
214 TRACE_EVENT0("html_viewer", "HTMLDocument::OnFrameDidFinishLoad");
215 did_finish_local_frame_load_ = true;
216 scoped_ptr<BeforeLoadCache> before_load_cache = std::move(before_load_cache_);
217 if (!before_load_cache)
218 return;
219
220 // Bind any pending AxProvider and TestHTMLViewer interface requests.
221 for (auto it : before_load_cache->ax_provider_requests) {
222 ax_providers_.insert(new AxProviderImpl(
223 frame_->frame_tree_manager()->GetWebView(), std::move(*it)));
224 }
225 for (auto it : before_load_cache->test_interface_requests) {
226 CHECK(IsTestInterfaceEnabled());
227 test_html_viewers_.push_back(new TestHTMLViewerImpl(
228 frame_->web_frame()->toWebLocalFrame(), std::move(*it)));
229 }
230 }
231
232 mojo::Shell* HTMLDocument::GetShell() {
233 return html_document_shell_;
234 }
235
236 HTMLFactory* HTMLDocument::GetHTMLFactory() {
237 return factory_;
238 }
239
240 void HTMLDocument::OnFrameSwappedToRemote() {
241 // When the frame becomes remote HTMLDocument is no longer needed.
242 frame_ = nullptr;
243 Destroy();
244 }
245
246 void HTMLDocument::OnSwap(HTMLFrame* frame, HTMLFrameDelegate* old_delegate) {
247 TRACE_EVENT0("html_viewer", "HTMLDocument::OnSwap");
248 DCHECK(frame->IsLocal());
249 DCHECK(frame->window());
250 DCHECK(!frame_);
251 DCHECK(!transferable_state_.root);
252 if (!old_delegate) {
253 // We're taking over a child of a local root that isn't associated with a
254 // delegate. In this case the frame's window is not the root of the
255 // WindowTreeConnection.
256 transferable_state_.owns_window_tree_connection = false;
257 transferable_state_.root = frame->window();
258 } else {
259 HTMLDocument* old_document = static_cast<HTMLDocument*>(old_delegate);
260 transferable_state_.Move(&old_document->transferable_state_);
261 if (transferable_state_.window_tree_delegate_impl)
262 transferable_state_.window_tree_delegate_impl->set_delegate(this);
263 old_document->frame_ = nullptr;
264 old_document->Destroy();
265 }
266 }
267
268 void HTMLDocument::OnFrameDestroyed() {
269 if (!transferable_state_.owns_window_tree_connection)
270 delete this;
271 }
272
273 void HTMLDocument::Create(mojo::Connection* connection,
274 mojo::InterfaceRequest<AxProvider> request) {
275 if (!did_finish_local_frame_load_) {
276 // Cache AxProvider interface requests until the document finishes loading.
277 auto cached_request = new mojo::InterfaceRequest<AxProvider>();
278 *cached_request = std::move(request);
279 GetBeforeLoadCache()->ax_provider_requests.insert(cached_request);
280 } else {
281 ax_providers_.insert(
282 new AxProviderImpl(frame_->web_view(), std::move(request)));
283 }
284 }
285
286 void HTMLDocument::Create(mojo::Connection* connection,
287 mojo::InterfaceRequest<TestHTMLViewer> request) {
288 CHECK(IsTestInterfaceEnabled());
289 if (!did_finish_local_frame_load_) {
290 auto cached_request = new mojo::InterfaceRequest<TestHTMLViewer>();
291 *cached_request = std::move(request);
292 GetBeforeLoadCache()->test_interface_requests.insert(cached_request);
293 } else {
294 test_html_viewers_.push_back(new TestHTMLViewerImpl(
295 frame_->web_frame()->toWebLocalFrame(), std::move(request)));
296 }
297 }
298
299 void HTMLDocument::Create(
300 mojo::Connection* connection,
301 mojo::InterfaceRequest<web_view::mojom::FrameClient> request) {
302 if (frame_) {
303 DVLOG(1) << "Request for FrameClient after one already vended.";
304 return;
305 }
306 resource_waiter_->Bind(std::move(request));
307 }
308
309 void HTMLDocument::Create(
310 mojo::Connection* connection,
311 mojo::InterfaceRequest<devtools_service::DevToolsAgent> request) {
312 if (frame_) {
313 if (frame_->devtools_agent())
314 frame_->devtools_agent()->BindToRequest(std::move(request));
315 } else {
316 devtools_agent_request_ = std::move(request);
317 }
318 }
319
320 void HTMLDocument::Create(
321 mojo::Connection* connection,
322 mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) {
323 DCHECK(!transferable_state_.window_tree_delegate_impl);
324 transferable_state_.window_tree_delegate_impl.reset(
325 new WindowTreeDelegateImpl(this));
326 transferable_state_.owns_window_tree_connection = true;
327 mus::WindowTreeConnection::Create(
328 transferable_state_.window_tree_delegate_impl.get(), std::move(request),
329 mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED);
330 }
331
332 } // namespace html_viewer
OLDNEW
« no previous file with comments | « components/html_viewer/html_document.h ('k') | components/html_viewer/html_document_application_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698