[Telemetry] Always uploading browser log if enabled instead of wait for crash to...
[chromium-blink-merge.git] / components / html_viewer / html_document_oopif.cc
blobabe5392ebf8ef40d8a5cd9c68f380a935f8579bf
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.
5 #include "components/html_viewer/html_document_oopif.h"
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "components/devtools_service/public/cpp/switches.h"
14 #include "components/html_viewer/blink_url_request_type_converters.h"
15 #include "components/html_viewer/devtools_agent_impl.h"
16 #include "components/html_viewer/document_resource_waiter.h"
17 #include "components/html_viewer/global_state.h"
18 #include "components/html_viewer/html_frame.h"
19 #include "components/html_viewer/html_frame_tree_manager.h"
20 #include "components/html_viewer/test_html_viewer_impl.h"
21 #include "components/html_viewer/web_url_loader_impl.h"
22 #include "components/view_manager/ids.h"
23 #include "components/view_manager/public/cpp/view.h"
24 #include "components/view_manager/public/cpp/view_manager.h"
25 #include "mojo/application/public/cpp/application_impl.h"
26 #include "mojo/application/public/cpp/connect.h"
27 #include "mojo/application/public/interfaces/shell.mojom.h"
28 #include "mojo/converters/geometry/geometry_type_converters.h"
29 #include "third_party/WebKit/public/web/WebLocalFrame.h"
30 #include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h"
31 #include "ui/gfx/geometry/dip_util.h"
32 #include "ui/gfx/geometry/size.h"
34 using mojo::AxProvider;
35 using mojo::View;
37 namespace html_viewer {
38 namespace {
40 const char kEnableTestInterface[] = "enable-html-viewer-test-interface";
42 bool IsTestInterfaceEnabled() {
43 return base::CommandLine::ForCurrentProcess()->HasSwitch(
44 kEnableTestInterface);
47 bool EnableRemoteDebugging() {
48 return base::CommandLine::ForCurrentProcess()->HasSwitch(
49 devtools_service::kRemoteDebuggingPort);
52 } // namespace
54 HTMLDocumentOOPIF::BeforeLoadCache::BeforeLoadCache() {
57 HTMLDocumentOOPIF::BeforeLoadCache::~BeforeLoadCache() {
58 STLDeleteElements(&ax_provider_requests);
59 STLDeleteElements(&test_interface_requests);
62 HTMLDocumentOOPIF::HTMLDocumentOOPIF(mojo::ApplicationImpl* html_document_app,
63 mojo::ApplicationConnection* connection,
64 mojo::URLResponsePtr response,
65 GlobalState* global_state,
66 const DeleteCallback& delete_callback)
67 : app_refcount_(html_document_app->app_lifetime_helper()
68 ->CreateAppRefCount()),
69 html_document_app_(html_document_app),
70 connection_(connection),
71 view_manager_client_factory_(html_document_app->shell(), this),
72 global_state_(global_state),
73 frame_(nullptr),
74 delete_callback_(delete_callback) {
75 // TODO(sky): nuke headless. We're not going to care about it anymore.
76 DCHECK(!global_state_->is_headless());
78 connection->AddService(
79 static_cast<mojo::InterfaceFactory<mandoline::FrameTreeClient>*>(this));
80 connection->AddService(static_cast<InterfaceFactory<AxProvider>*>(this));
81 connection->AddService(&view_manager_client_factory_);
82 if (IsTestInterfaceEnabled()) {
83 connection->AddService(
84 static_cast<mojo::InterfaceFactory<TestHTMLViewer>*>(this));
87 resource_waiter_.reset(
88 new DocumentResourceWaiter(global_state_, response.Pass(), this));
89 LoadIfNecessary();
92 void HTMLDocumentOOPIF::Destroy() {
93 if (resource_waiter_) {
94 mojo::View* root = resource_waiter_->root();
95 if (root) {
96 root->RemoveObserver(this);
97 resource_waiter_.reset();
98 delete root->view_manager();
99 } else {
100 delete this;
102 } else {
103 // Closing the frame ends up destroying the ViewManager, which triggers
104 // deleting this (OnViewManagerDestroyed()).
105 frame_->Close();
109 HTMLDocumentOOPIF::~HTMLDocumentOOPIF() {
110 delete_callback_.Run(this);
112 STLDeleteElements(&ax_providers_);
115 void HTMLDocumentOOPIF::LoadIfNecessary() {
116 if (!frame_ && resource_waiter_->IsReady())
117 Load();
120 void HTMLDocumentOOPIF::Load() {
121 DCHECK(resource_waiter_ && resource_waiter_->IsReady());
123 mojo::View* view = resource_waiter_->root();
124 global_state_->InitIfNecessary(
125 view->viewport_metrics().size_in_pixels.To<gfx::Size>(),
126 view->viewport_metrics().device_pixel_ratio);
128 view->RemoveObserver(this);
130 WebURLRequestExtraData* extra_data = new WebURLRequestExtraData;
131 extra_data->synthetic_response =
132 resource_waiter_->ReleaseURLResponse().Pass();
134 frame_ = HTMLFrameTreeManager::CreateFrameAndAttachToTree(
135 global_state_, html_document_app_, view, resource_waiter_.Pass(), this);
137 // TODO(yzshen): http://crbug.com/498986 Creating DevToolsAgentImpl instances
138 // causes html_viewer_apptests flakiness currently. Before we fix that we
139 // cannot enable remote debugging (which is required by Telemetry tests) on
140 // the bots.
141 if (EnableRemoteDebugging() && !frame_->parent()) {
142 devtools_agent_.reset(new DevToolsAgentImpl(
143 frame_->web_frame()->toWebLocalFrame(), html_document_app_->shell()));
146 const GURL url(extra_data->synthetic_response->url);
148 blink::WebURLRequest web_request;
149 web_request.initialize();
150 web_request.setURL(url);
151 web_request.setExtraData(extra_data);
153 frame_->web_frame()->toWebLocalFrame()->loadRequest(web_request);
156 HTMLDocumentOOPIF::BeforeLoadCache* HTMLDocumentOOPIF::GetBeforeLoadCache() {
157 CHECK(!did_finish_local_frame_load_);
158 if (!before_load_cache_.get())
159 before_load_cache_.reset(new BeforeLoadCache);
160 return before_load_cache_.get();
163 void HTMLDocumentOOPIF::OnEmbed(View* root) {
164 // We're an observer until the document is loaded.
165 root->AddObserver(this);
166 resource_waiter_->set_root(root);
168 LoadIfNecessary();
171 void HTMLDocumentOOPIF::OnViewManagerDestroyed(
172 mojo::ViewManager* view_manager) {
173 delete this;
176 void HTMLDocumentOOPIF::OnViewViewportMetricsChanged(
177 mojo::View* view,
178 const mojo::ViewportMetrics& old_metrics,
179 const mojo::ViewportMetrics& new_metrics) {
180 LoadIfNecessary();
183 void HTMLDocumentOOPIF::OnViewDestroyed(View* view) {
184 resource_waiter_->root()->RemoveObserver(this);
185 resource_waiter_->set_root(nullptr);
188 bool HTMLDocumentOOPIF::ShouldNavigateLocallyInMainFrame() {
189 return devtools_agent_ && devtools_agent_->handling_page_navigate_request();
192 void HTMLDocumentOOPIF::OnFrameDidFinishLoad() {
193 did_finish_local_frame_load_ = true;
194 scoped_ptr<BeforeLoadCache> before_load_cache = before_load_cache_.Pass();
195 if (!before_load_cache)
196 return;
198 // Bind any pending AxProvider and TestHTMLViewer interface requests.
199 for (auto it : before_load_cache->ax_provider_requests) {
200 ax_providers_.insert(new AxProviderImpl(
201 frame_->frame_tree_manager()->GetWebView(), it->Pass()));
203 for (auto it : before_load_cache->test_interface_requests) {
204 CHECK(IsTestInterfaceEnabled());
205 test_html_viewers_.push_back(new TestHTMLViewerImpl(
206 frame_->web_frame()->toWebLocalFrame(), it->Pass()));
210 mojo::ApplicationImpl* HTMLDocumentOOPIF::GetApp() {
211 return html_document_app_;
214 void HTMLDocumentOOPIF::Create(mojo::ApplicationConnection* connection,
215 mojo::InterfaceRequest<AxProvider> request) {
216 if (!did_finish_local_frame_load_) {
217 // Cache AxProvider interface requests until the document finishes loading.
218 auto cached_request = new mojo::InterfaceRequest<AxProvider>();
219 *cached_request = request.Pass();
220 GetBeforeLoadCache()->ax_provider_requests.insert(cached_request);
221 } else {
222 ax_providers_.insert(
223 new AxProviderImpl(frame_->web_view(), request.Pass()));
227 void HTMLDocumentOOPIF::Create(mojo::ApplicationConnection* connection,
228 mojo::InterfaceRequest<TestHTMLViewer> request) {
229 CHECK(IsTestInterfaceEnabled());
230 if (!did_finish_local_frame_load_) {
231 auto cached_request = new mojo::InterfaceRequest<TestHTMLViewer>();
232 *cached_request = request.Pass();
233 GetBeforeLoadCache()->test_interface_requests.insert(cached_request);
234 } else {
235 test_html_viewers_.push_back(new TestHTMLViewerImpl(
236 frame_->web_frame()->toWebLocalFrame(), request.Pass()));
240 void HTMLDocumentOOPIF::Create(
241 mojo::ApplicationConnection* connection,
242 mojo::InterfaceRequest<mandoline::FrameTreeClient> request) {
243 if (frame_) {
244 DVLOG(1) << "Request for FrameTreeClient after one already vended.";
245 return;
247 resource_waiter_->Bind(request.Pass());
250 } // namespace html_viewer