Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / html_viewer / document_resource_waiter.cc
blobf0b061864e16e08d59dfcbd51fae7863d772fb05
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/document_resource_waiter.h"
7 #include "components/html_viewer/global_state.h"
8 #include "components/html_viewer/html_document.h"
9 #include "components/html_viewer/html_frame_tree_manager.h"
10 #include "components/mus/public/cpp/view.h"
12 using web_view::mojom::ViewConnectType;
14 namespace html_viewer {
16 DocumentResourceWaiter::DocumentResourceWaiter(GlobalState* global_state,
17 mojo::URLResponsePtr response,
18 HTMLDocument* document)
19 : global_state_(global_state),
20 document_(document),
21 response_(response.Pass()),
22 root_(nullptr),
23 change_id_(0u),
24 view_id_(0u),
25 view_connect_type_(web_view::mojom::VIEW_CONNECT_TYPE_USE_NEW),
26 frame_client_binding_(this),
27 is_ready_(false),
28 waiting_for_change_id_(false),
29 target_frame_tree_(nullptr) {}
31 DocumentResourceWaiter::~DocumentResourceWaiter() {
32 if (root_)
33 root_->RemoveObserver(this);
34 if (target_frame_tree_)
35 target_frame_tree_->RemoveObserver(this);
38 void DocumentResourceWaiter::Release(
39 mojo::InterfaceRequest<web_view::mojom::FrameClient>* frame_client_request,
40 web_view::mojom::FramePtr* frame,
41 mojo::Array<web_view::mojom::FrameDataPtr>* frame_data,
42 uint32_t* change_id,
43 uint32_t* view_id,
44 ViewConnectType* view_connect_type,
45 OnConnectCallback* on_connect_callback) {
46 DCHECK(is_ready_);
47 *frame_client_request = frame_client_request_.Pass();
48 *frame = frame_.Pass();
49 *frame_data = frame_data_.Pass();
50 *change_id = change_id_;
51 *view_id = view_id_;
52 *view_connect_type = view_connect_type_;
53 *on_connect_callback = on_connect_callback_;
56 mojo::URLResponsePtr DocumentResourceWaiter::ReleaseURLResponse() {
57 return response_.Pass();
60 void DocumentResourceWaiter::SetRoot(mus::View* root) {
61 DCHECK(!root_);
62 root_ = root;
63 root_->AddObserver(this);
64 UpdateIsReady();
67 void DocumentResourceWaiter::Bind(
68 mojo::InterfaceRequest<web_view::mojom::FrameClient> request) {
69 if (frame_client_binding_.is_bound() || !frame_data_.is_null()) {
70 DVLOG(1) << "Request for FrameClient after already supplied one";
71 return;
73 frame_client_binding_.Bind(request.Pass());
76 void DocumentResourceWaiter::UpdateIsReady() {
77 if (is_ready_)
78 return;
80 // See description of |waiting_for_change_id_| for details.
81 if (waiting_for_change_id_) {
82 if (target_frame_tree_->change_id() == change_id_) {
83 is_ready_ = true;
84 waiting_for_change_id_ = false;
85 document_->Load();
87 return;
90 // The first portion of ready is when we have received OnConnect()
91 // (|frame_data_| is valid) and we have a view with valid metrics. The view
92 // is not necessary is ViewConnectType is USE_EXISTING, which means the
93 // application is not asked for a ViewTreeClient. The metrics are necessary
94 // to initialize ResourceBundle. If USE_EXISTING is true, it means a View has
95 // already been provided to another HTMLDocument and there is no need to wait
96 // for metrics.
97 bool is_ready =
98 (!frame_data_.is_null() &&
99 ((view_connect_type_ ==
100 web_view::mojom::VIEW_CONNECT_TYPE_USE_EXISTING) ||
101 (root_ && root_->viewport_metrics().device_pixel_ratio != 0.0f)));
102 if (is_ready) {
103 HTMLFrameTreeManager* frame_tree =
104 HTMLFrameTreeManager::FindFrameTreeWithRoot(frame_data_[0]->frame_id);
105 // Once we've received OnConnect() and the view (if necessary), we determine
106 // which HTMLFrameTreeManager the new frame ends up in. If there is an
107 // existing HTMLFrameTreeManager then we must wait for the change_id
108 // supplied to OnConnect() to be <= that of the HTMLFrameTreeManager's
109 // change_id. If we did not wait for the change id to be <= then the
110 // structure of the tree is not in the expected state and it's possible the
111 // frame communicated in OnConnect() does not exist yet.
112 if (frame_tree && change_id_ > frame_tree->change_id()) {
113 waiting_for_change_id_ = true;
114 target_frame_tree_ = frame_tree;
115 target_frame_tree_->AddObserver(this);
116 } else {
117 is_ready_ = true;
118 document_->Load();
123 void DocumentResourceWaiter::OnConnect(
124 web_view::mojom::FramePtr frame,
125 uint32_t change_id,
126 uint32_t view_id,
127 ViewConnectType view_connect_type,
128 mojo::Array<web_view::mojom::FrameDataPtr> frame_data,
129 const OnConnectCallback& callback) {
130 DCHECK(frame_data_.is_null());
131 change_id_ = change_id;
132 view_id_ = view_id;
133 view_connect_type_ = view_connect_type;
134 frame_ = frame.Pass();
135 frame_data_ = frame_data.Pass();
136 on_connect_callback_ = callback;
137 CHECK(frame_data_.size() > 0u);
138 frame_client_request_ = frame_client_binding_.Unbind();
139 UpdateIsReady();
142 void DocumentResourceWaiter::OnFrameAdded(
143 uint32_t change_id,
144 web_view::mojom::FrameDataPtr frame_data) {
145 // It is assumed we receive OnConnect() (which unbinds) before anything else.
146 NOTREACHED();
149 void DocumentResourceWaiter::OnFrameRemoved(uint32_t change_id,
150 uint32_t frame_id) {
151 // It is assumed we receive OnConnect() (which unbinds) before anything else.
152 NOTREACHED();
155 void DocumentResourceWaiter::OnFrameClientPropertyChanged(
156 uint32_t frame_id,
157 const mojo::String& name,
158 mojo::Array<uint8_t> new_value) {
159 // It is assumed we receive OnConnect() (which unbinds) before anything else.
160 NOTREACHED();
163 void DocumentResourceWaiter::OnPostMessageEvent(
164 uint32_t source_frame_id,
165 uint32_t target_frame_id,
166 web_view::mojom::HTMLMessageEventPtr event) {
167 // It is assumed we receive OnConnect() (which unbinds) before anything else.
168 NOTREACHED();
171 void DocumentResourceWaiter::OnWillNavigate() {
172 // It is assumed we receive OnConnect() (which unbinds) before anything else.
173 NOTIMPLEMENTED();
176 void DocumentResourceWaiter::OnFrameLoadingStateChanged(uint32_t frame_id,
177 bool loading) {
178 // It is assumed we receive OnConnect() (which unbinds) before anything else.
179 NOTREACHED();
182 void DocumentResourceWaiter::OnDispatchFrameLoadEvent(uint32_t frame_id) {
183 // It is assumed we receive OnConnect() (which unbinds) before anything else.
184 NOTREACHED();
187 void DocumentResourceWaiter::OnViewViewportMetricsChanged(
188 mus::View* view,
189 const mojo::ViewportMetrics& old_metrics,
190 const mojo::ViewportMetrics& new_metrics) {
191 UpdateIsReady();
194 void DocumentResourceWaiter::OnViewDestroyed(mus::View* view) {
195 root_->RemoveObserver(this);
196 root_ = nullptr;
199 void DocumentResourceWaiter::OnHTMLFrameTreeManagerChangeIdAdvanced() {
200 UpdateIsReady();
203 void DocumentResourceWaiter::OnHTMLFrameTreeManagerDestroyed() {
204 document_->Destroy(); // This destroys us.
207 } // namespace html_viewer