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/view_manager/public/cpp/view.h"
12 using web_view::ViewConnectType
;
14 namespace html_viewer
{
16 DocumentResourceWaiter::DocumentResourceWaiter(GlobalState
* global_state
,
17 mojo::URLResponsePtr response
,
18 HTMLDocument
* document
)
19 : global_state_(global_state
),
21 response_(response
.Pass()),
25 view_connect_type_(web_view::VIEW_CONNECT_TYPE_USE_NEW
),
26 frame_tree_client_binding_(this),
28 waiting_for_change_id_(false),
29 target_frame_tree_(nullptr) {}
31 DocumentResourceWaiter::~DocumentResourceWaiter() {
33 root_
->RemoveObserver(this);
34 if (target_frame_tree_
)
35 target_frame_tree_
->RemoveObserver(this);
38 void DocumentResourceWaiter::Release(
39 mojo::InterfaceRequest
<web_view::FrameTreeClient
>*
40 frame_tree_client_request
,
41 web_view::FrameTreeServerPtr
* frame_tree_server
,
42 mojo::Array
<web_view::FrameDataPtr
>* frame_data
,
45 ViewConnectType
* view_connect_type
,
46 OnConnectCallback
* on_connect_callback
) {
48 *frame_tree_client_request
= frame_tree_client_request_
.Pass();
49 *frame_tree_server
= server_
.Pass();
50 *frame_data
= frame_data_
.Pass();
51 *change_id
= change_id_
;
53 *view_connect_type
= view_connect_type_
;
54 *on_connect_callback
= on_connect_callback_
;
57 mojo::URLResponsePtr
DocumentResourceWaiter::ReleaseURLResponse() {
58 return response_
.Pass();
61 void DocumentResourceWaiter::SetRoot(mojo::View
* root
) {
64 root_
->AddObserver(this);
68 void DocumentResourceWaiter::Bind(
69 mojo::InterfaceRequest
<web_view::FrameTreeClient
> request
) {
70 if (frame_tree_client_binding_
.is_bound() || !frame_data_
.is_null()) {
71 DVLOG(1) << "Request for FrameTreeClient after already supplied one";
74 frame_tree_client_binding_
.Bind(request
.Pass());
77 void DocumentResourceWaiter::UpdateIsReady() {
81 // See description of |waiting_for_change_id_| for details.
82 if (waiting_for_change_id_
) {
83 if (target_frame_tree_
->change_id() == change_id_
) {
85 waiting_for_change_id_
= false;
91 // The first portion of ready is when we have received OnConnect()
92 // (|frame_data_| is valid) and we have a view with valid metrics. The view
93 // is not necessary is ViewConnectType is USE_EXISTING, which means the
94 // application is not asked for a ViewTreeClient. The metrics are necessary
95 // to initialize ResourceBundle. If USE_EXISTING is true, it means a View has
96 // already been provided to another HTMLDocument and there is no need to wait
99 (!frame_data_
.is_null() &&
100 ((view_connect_type_
== web_view::VIEW_CONNECT_TYPE_USE_EXISTING
) ||
101 (root_
&& root_
->viewport_metrics().device_pixel_ratio
!= 0.0f
)));
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);
123 void DocumentResourceWaiter::OnConnect(
124 web_view::FrameTreeServerPtr server
,
127 ViewConnectType view_connect_type
,
128 mojo::Array
<web_view::FrameDataPtr
> frame_data
,
129 const OnConnectCallback
& callback
) {
130 DCHECK(frame_data_
.is_null());
131 change_id_
= change_id
;
133 view_connect_type_
= view_connect_type
;
134 server_
= server
.Pass();
135 frame_data_
= frame_data
.Pass();
136 on_connect_callback_
= callback
;
137 CHECK(frame_data_
.size() > 0u);
138 frame_tree_client_request_
= frame_tree_client_binding_
.Unbind();
142 void DocumentResourceWaiter::OnFrameAdded(uint32_t change_id
,
143 web_view::FrameDataPtr frame_data
) {
144 // It is assumed we receive OnConnect() (which unbinds) before anything else.
148 void DocumentResourceWaiter::OnFrameRemoved(uint32_t change_id
,
150 // It is assumed we receive OnConnect() (which unbinds) before anything else.
154 void DocumentResourceWaiter::OnFrameClientPropertyChanged(
156 const mojo::String
& name
,
157 mojo::Array
<uint8_t> new_value
) {
158 // It is assumed we receive OnConnect() (which unbinds) before anything else.
162 void DocumentResourceWaiter::OnPostMessageEvent(
163 uint32_t source_frame_id
,
164 uint32_t target_frame_id
,
165 web_view::HTMLMessageEventPtr event
) {
166 // It is assumed we receive OnConnect() (which unbinds) before anything else.
170 void DocumentResourceWaiter::OnWillNavigate(uint32_t target_frame_id
) {
171 // It is assumed we receive OnConnect() (which unbinds) before anything else.
175 void DocumentResourceWaiter::OnViewViewportMetricsChanged(
177 const mojo::ViewportMetrics
& old_metrics
,
178 const mojo::ViewportMetrics
& new_metrics
) {
182 void DocumentResourceWaiter::OnViewDestroyed(mojo::View
* view
) {
183 root_
->RemoveObserver(this);
187 void DocumentResourceWaiter::OnHTMLFrameTreeManagerChangeIdAdvanced() {
191 void DocumentResourceWaiter::OnHTMLFrameTreeManagerDestroyed() {
192 document_
->Destroy(); // This destroys us.
195 } // namespace html_viewer