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
),
21 response_(response
.Pass()),
25 view_connect_type_(web_view::mojom::VIEW_CONNECT_TYPE_USE_NEW
),
26 frame_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::mojom::FrameClient
>* frame_client_request
,
40 web_view::mojom::FramePtr
* frame
,
41 mojo::Array
<web_view::mojom::FrameDataPtr
>* frame_data
,
44 ViewConnectType
* view_connect_type
,
45 OnConnectCallback
* on_connect_callback
) {
47 *frame_client_request
= frame_client_request_
.Pass();
48 *frame
= frame_
.Pass();
49 *frame_data
= frame_data_
.Pass();
50 *change_id
= change_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
) {
63 root_
->AddObserver(this);
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";
73 frame_client_binding_
.Bind(request
.Pass());
76 void DocumentResourceWaiter::UpdateIsReady() {
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_
) {
84 waiting_for_change_id_
= false;
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
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
)));
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::mojom::FramePtr frame
,
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
;
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();
142 void DocumentResourceWaiter::OnFrameAdded(
144 web_view::mojom::FrameDataPtr frame_data
) {
145 // It is assumed we receive OnConnect() (which unbinds) before anything else.
149 void DocumentResourceWaiter::OnFrameRemoved(uint32_t change_id
,
151 // It is assumed we receive OnConnect() (which unbinds) before anything else.
155 void DocumentResourceWaiter::OnFrameClientPropertyChanged(
157 const mojo::String
& name
,
158 mojo::Array
<uint8_t> new_value
) {
159 // It is assumed we receive OnConnect() (which unbinds) before anything else.
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.
171 void DocumentResourceWaiter::OnWillNavigate() {
172 // It is assumed we receive OnConnect() (which unbinds) before anything else.
176 void DocumentResourceWaiter::OnFrameLoadingStateChanged(uint32_t frame_id
,
178 // It is assumed we receive OnConnect() (which unbinds) before anything else.
182 void DocumentResourceWaiter::OnDispatchFrameLoadEvent(uint32_t frame_id
) {
183 // It is assumed we receive OnConnect() (which unbinds) before anything else.
187 void DocumentResourceWaiter::OnViewViewportMetricsChanged(
189 const mojo::ViewportMetrics
& old_metrics
,
190 const mojo::ViewportMetrics
& new_metrics
) {
194 void DocumentResourceWaiter::OnViewDestroyed(mus::View
* view
) {
195 root_
->RemoveObserver(this);
199 void DocumentResourceWaiter::OnHTMLFrameTreeManagerChangeIdAdvanced() {
203 void DocumentResourceWaiter::OnHTMLFrameTreeManagerDestroyed() {
204 document_
->Destroy(); // This destroys us.
207 } // namespace html_viewer