OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "services/ui/view_manager/view_registry.h" |
| 6 |
5 #include <algorithm> | 7 #include <algorithm> |
6 #include <utility> | 8 #include <utility> |
7 | 9 |
8 #include "base/bind.h" | 10 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
10 #include "services/ui/view_manager/surface_manager.h" | 12 #include "mojo/services/ui/views/cpp/logging.h" |
11 #include "services/ui/view_manager/view_host_impl.h" | 13 #include "services/ui/view_manager/view_host_impl.h" |
12 #include "services/ui/view_manager/view_registry.h" | |
13 #include "services/ui/view_manager/view_tree_host_impl.h" | 14 #include "services/ui/view_manager/view_tree_host_impl.h" |
14 | 15 |
15 namespace view_manager { | 16 namespace view_manager { |
16 | 17 |
17 static bool AreViewLayoutParamsValid(const mojo::ui::ViewLayoutParams* params) { | 18 static bool AreViewLayoutParamsValid(const mojo::ui::ViewLayoutParams* params) { |
18 return params && params->constraints && params->constraints->min_width >= 0 && | 19 return params && params->constraints && params->constraints->min_width >= 0 && |
19 params->constraints->max_width >= params->constraints->min_width && | 20 params->constraints->max_width >= params->constraints->min_width && |
20 params->constraints->min_height >= 0 && | 21 params->constraints->min_height >= 0 && |
21 params->constraints->max_height >= params->constraints->min_height && | 22 params->constraints->max_height >= params->constraints->min_height && |
22 params->device_pixel_ratio > 0; | 23 params->device_pixel_ratio > 0; |
23 } | 24 } |
24 | 25 |
25 static std::ostream& operator<<(std::ostream& os, const mojo::Size* size) { | 26 ViewRegistry::ViewRegistry(mojo::gfx::composition::CompositorPtr compositor) |
26 return size | 27 : compositor_(compositor.Pass()) {} |
27 ? os << "{width=" << size->width << ", height=" << size->height | |
28 << "}" | |
29 : os << "{null}"; | |
30 } | |
31 | |
32 static std::ostream& operator<<(std::ostream& os, | |
33 const mojo::SurfaceId* surface_id) { | |
34 return surface_id | |
35 ? os << "{id_namespace=" << surface_id->id_namespace | |
36 << ", local=" << surface_id->local << "}" | |
37 : os << "{null}"; | |
38 } | |
39 | |
40 static std::ostream& operator<<(std::ostream& os, | |
41 const mojo::ui::ViewToken* token) { | |
42 return token ? os << "{token=" << token->value << "}" : os << "{null}"; | |
43 } | |
44 | |
45 static std::ostream& operator<<(std::ostream& os, const ViewState* view_state) { | |
46 return view_state ? os << "{token=" << view_state->view_token_value() << "}" | |
47 : os << "{null}"; | |
48 } | |
49 | |
50 static std::ostream& operator<<(std::ostream& os, | |
51 const mojo::ui::BoxConstraints* constraints) { | |
52 return constraints | |
53 ? os << "{min_width=" << constraints->min_width | |
54 << ", max_width=" << constraints->max_width | |
55 << ", min_height=" << constraints->min_height | |
56 << ", max_height=" << constraints->max_height << "}" | |
57 : os << "{null}"; | |
58 }; | |
59 | |
60 static std::ostream& operator<<(std::ostream& os, | |
61 const mojo::ui::ViewLayoutParams* params) { | |
62 return params | |
63 ? os << "{constraints=" << params->constraints.get() | |
64 << ", device_pixel_ratio=" << params->device_pixel_ratio | |
65 << "}" | |
66 : os << "{null}"; | |
67 } | |
68 | |
69 static std::ostream& operator<<(std::ostream& os, | |
70 const mojo::ui::ViewLayoutInfo* info) { | |
71 return info | |
72 ? os << "{size=" << info->size.get() | |
73 << ", surface_id=" << info->surface_id.get() << "}" | |
74 : os << "{null}"; | |
75 } | |
76 | |
77 ViewRegistry::ViewRegistry(SurfaceManager* surface_manager) | |
78 : surface_manager_(surface_manager), next_view_token_value_(1u) {} | |
79 | 28 |
80 ViewRegistry::~ViewRegistry() {} | 29 ViewRegistry::~ViewRegistry() {} |
81 | 30 |
| 31 void ViewRegistry::ConnectAssociates( |
| 32 mojo::ApplicationImpl* app_impl, |
| 33 const std::vector<std::string>& urls, |
| 34 const AssociateConnectionErrorCallback& connection_error_callback) { |
| 35 associate_table_.ConnectAssociates(app_impl, this, urls, |
| 36 connection_error_callback); |
| 37 } |
| 38 |
82 mojo::ui::ViewTokenPtr ViewRegistry::RegisterView( | 39 mojo::ui::ViewTokenPtr ViewRegistry::RegisterView( |
83 mojo::ui::ViewPtr view, | 40 mojo::ui::ViewPtr view, |
84 mojo::InterfaceRequest<mojo::ui::ViewHost> view_host_request) { | 41 mojo::InterfaceRequest<mojo::ui::ViewHost> view_host_request, |
| 42 const mojo::String& label) { |
85 DCHECK(view); | 43 DCHECK(view); |
86 uint32_t view_token_value = next_view_token_value_++; | 44 |
87 DCHECK(!FindView(view_token_value)); | 45 auto view_token = mojo::ui::ViewToken::New(); |
| 46 view_token->value = next_view_token_value_++; |
| 47 CHECK(view_token->value); |
| 48 CHECK(!FindView(view_token->value)); |
88 | 49 |
89 // Create the state and bind host to it. | 50 // Create the state and bind host to it. |
90 ViewState* view_state = new ViewState(view.Pass(), view_token_value); | 51 std::string sanitized_label = |
| 52 label.get().substr(0, mojo::ui::kLabelMaxLength); |
| 53 ViewState* view_state = |
| 54 new ViewState(view.Pass(), view_token.Pass(), sanitized_label); |
91 ViewHostImpl* view_host = | 55 ViewHostImpl* view_host = |
92 new ViewHostImpl(this, view_state, view_host_request.Pass()); | 56 new ViewHostImpl(this, view_state, view_host_request.Pass()); |
93 view_state->set_view_host(view_host); | 57 view_state->set_view_host(view_host); |
94 view_state->set_view_connection_error_handler( | 58 view_state->set_view_connection_error_handler( |
95 base::Bind(&ViewRegistry::OnViewConnectionError, base::Unretained(this), | 59 base::Bind(&ViewRegistry::OnViewConnectionError, base::Unretained(this), |
96 view_state)); | 60 view_state)); |
97 view_host->set_view_host_connection_error_handler( | 61 view_host->set_view_host_connection_error_handler( |
98 base::Bind(&ViewRegistry::OnViewConnectionError, base::Unretained(this), | 62 base::Bind(&ViewRegistry::OnViewConnectionError, base::Unretained(this), |
99 view_state)); | 63 view_state)); |
100 | 64 |
101 // Add to registry and return token. | 65 // Add to registry and return token. |
102 views_by_token_.insert({view_token_value, view_state}); | 66 views_by_token_.insert({view_state->view_token()->value, view_state}); |
103 mojo::ui::ViewTokenPtr token = mojo::ui::ViewToken::New(); | |
104 token->value = view_state->view_token_value(); | |
105 DVLOG(1) << "RegisterView: view=" << view_state; | 67 DVLOG(1) << "RegisterView: view=" << view_state; |
106 return token; | 68 return view_state->view_token()->Clone(); |
107 } | 69 } |
108 | 70 |
109 void ViewRegistry::OnViewConnectionError(ViewState* view_state) { | 71 void ViewRegistry::OnViewConnectionError(ViewState* view_state) { |
110 DCHECK(IsViewStateRegisteredDebug(view_state)); | 72 DCHECK(IsViewStateRegisteredDebug(view_state)); |
111 DVLOG(1) << "OnViewConnectionError: view=" << view_state; | 73 DVLOG(1) << "OnViewConnectionError: view=" << view_state; |
112 | 74 |
113 UnregisterView(view_state); | 75 UnregisterView(view_state); |
114 } | 76 } |
115 | 77 |
116 void ViewRegistry::UnregisterView(ViewState* view_state) { | 78 void ViewRegistry::UnregisterView(ViewState* view_state) { |
117 DCHECK(IsViewStateRegisteredDebug(view_state)); | 79 DCHECK(IsViewStateRegisteredDebug(view_state)); |
118 DVLOG(1) << "UnregisterView: view=" << view_state; | 80 DVLOG(1) << "UnregisterView: view=" << view_state; |
119 | 81 |
120 // Remove from parent or roots. | 82 // Remove from parent or roots. |
121 HijackView(view_state); | 83 HijackView(view_state); |
122 | 84 |
123 // Remove from registry. | 85 // Remove from registry. |
124 views_by_token_.erase(view_state->view_token_value()); | 86 views_by_token_.erase(view_state->view_token()->value); |
125 delete view_state; | 87 delete view_state; |
126 } | 88 } |
127 | 89 |
128 void ViewRegistry::RegisterViewTree( | 90 mojo::ui::ViewTreeTokenPtr ViewRegistry::RegisterViewTree( |
129 mojo::ui::ViewTreePtr view_tree, | 91 mojo::ui::ViewTreePtr view_tree, |
130 mojo::InterfaceRequest<mojo::ui::ViewTreeHost> view_tree_host_request) { | 92 mojo::InterfaceRequest<mojo::ui::ViewTreeHost> view_tree_host_request, |
| 93 const mojo::String& label) { |
131 DCHECK(view_tree); | 94 DCHECK(view_tree); |
132 | 95 |
| 96 auto view_tree_token = mojo::ui::ViewTreeToken::New(); |
| 97 view_tree_token->value = next_view_tree_token_value_++; |
| 98 CHECK(view_tree_token->value); |
| 99 CHECK(!FindViewTree(view_tree_token->value)); |
| 100 |
133 // Create the state and bind host to it. | 101 // Create the state and bind host to it. |
134 ViewTreeState* tree_state = new ViewTreeState(view_tree.Pass()); | 102 std::string sanitized_label = |
| 103 label.get().substr(0, mojo::ui::kLabelMaxLength); |
| 104 ViewTreeState* tree_state = new ViewTreeState( |
| 105 view_tree.Pass(), view_tree_token.Pass(), sanitized_label); |
135 ViewTreeHostImpl* tree_host = | 106 ViewTreeHostImpl* tree_host = |
136 new ViewTreeHostImpl(this, tree_state, view_tree_host_request.Pass()); | 107 new ViewTreeHostImpl(this, tree_state, view_tree_host_request.Pass()); |
137 tree_state->set_view_tree_host(tree_host); | 108 tree_state->set_view_tree_host(tree_host); |
138 tree_state->set_view_tree_connection_error_handler( | 109 tree_state->set_view_tree_connection_error_handler( |
139 base::Bind(&ViewRegistry::OnViewTreeConnectionError, | 110 base::Bind(&ViewRegistry::OnViewTreeConnectionError, |
140 base::Unretained(this), tree_state)); | 111 base::Unretained(this), tree_state)); |
141 tree_host->set_view_tree_host_connection_error_handler( | 112 tree_host->set_view_tree_host_connection_error_handler( |
142 base::Bind(&ViewRegistry::OnViewTreeConnectionError, | 113 base::Bind(&ViewRegistry::OnViewTreeConnectionError, |
143 base::Unretained(this), tree_state)); | 114 base::Unretained(this), tree_state)); |
144 | 115 |
145 // Add to registry. | 116 // Add to registry. |
146 view_trees_.push_back(tree_state); | 117 view_trees_by_token_.insert( |
| 118 {tree_state->view_tree_token()->value, tree_state}); |
147 DVLOG(1) << "RegisterViewTree: tree=" << tree_state; | 119 DVLOG(1) << "RegisterViewTree: tree=" << tree_state; |
| 120 return tree_state->view_tree_token()->Clone(); |
148 } | 121 } |
149 | 122 |
150 void ViewRegistry::OnViewTreeConnectionError(ViewTreeState* tree_state) { | 123 void ViewRegistry::OnViewTreeConnectionError(ViewTreeState* tree_state) { |
151 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 124 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
152 DVLOG(1) << "OnViewTreeConnectionError: tree=" << tree_state; | 125 DVLOG(1) << "OnViewTreeConnectionError: tree=" << tree_state; |
153 | 126 |
154 UnregisterViewTree(tree_state); | 127 UnregisterViewTree(tree_state); |
155 } | 128 } |
156 | 129 |
157 void ViewRegistry::UnregisterViewTree(ViewTreeState* tree_state) { | 130 void ViewRegistry::UnregisterViewTree(ViewTreeState* tree_state) { |
158 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 131 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
159 DVLOG(1) << "UnregisterViewTree: tree=" << tree_state; | 132 DVLOG(1) << "UnregisterViewTree: tree=" << tree_state; |
160 | 133 |
161 // Unlink the root if needed. | 134 // Unlink the root if needed. |
162 if (tree_state->root()) | 135 if (tree_state->root()) |
163 UnlinkRoot(tree_state); | 136 UnlinkRoot(tree_state); |
164 | 137 |
165 // Remove from registry. | 138 // Remove from registry. |
166 view_trees_.erase(std::find_if( | 139 view_trees_by_token_.erase(tree_state->view_tree_token()->value); |
167 view_trees_.begin(), view_trees_.end(), | |
168 [tree_state](ViewTreeState* other) { return tree_state == other; })); | |
169 delete tree_state; | 140 delete tree_state; |
170 } | 141 } |
171 | 142 |
| 143 void ViewRegistry::CreateScene( |
| 144 ViewState* view_state, |
| 145 mojo::InterfaceRequest<mojo::gfx::composition::Scene> scene) { |
| 146 DCHECK(IsViewStateRegisteredDebug(view_state)); |
| 147 DVLOG(1) << "CreateScene: view=" << view_state; |
| 148 |
| 149 compositor_->CreateScene( |
| 150 scene.Pass(), view_state->label(), |
| 151 base::Bind(&ViewRegistry::OnSceneCreated, base::Unretained(this), |
| 152 view_state->GetWeakPtr())); |
| 153 } |
| 154 |
| 155 void ViewRegistry::OnSceneCreated( |
| 156 base::WeakPtr<ViewState> view_state_weak, |
| 157 mojo::gfx::composition::SceneTokenPtr scene_token) { |
| 158 DCHECK(scene_token); |
| 159 ViewState* view_state = view_state_weak.get(); |
| 160 if (view_state) { |
| 161 DVLOG(1) << "OnSceneCreated: scene_token=" << scene_token; |
| 162 |
| 163 view_state->set_scene_token(scene_token.Pass()); |
| 164 view_state->set_scene_changed_since_last_report(true); |
| 165 InvalidateLayout(view_state); |
| 166 } |
| 167 } |
| 168 |
172 void ViewRegistry::RequestLayout(ViewState* view_state) { | 169 void ViewRegistry::RequestLayout(ViewState* view_state) { |
173 DCHECK(IsViewStateRegisteredDebug(view_state)); | 170 DCHECK(IsViewStateRegisteredDebug(view_state)); |
174 DVLOG(1) << "RequestLayout: view=" << view_state; | 171 DVLOG(1) << "RequestLayout: view=" << view_state; |
175 | 172 |
176 InvalidateLayout(view_state); | 173 InvalidateLayout(view_state); |
177 } | 174 } |
178 | 175 |
179 void ViewRegistry::AddChild(ViewState* parent_state, | 176 void ViewRegistry::AddChild(ViewState* parent_state, |
180 uint32_t child_key, | 177 uint32_t child_key, |
181 mojo::ui::ViewTokenPtr child_view_token) { | 178 mojo::ui::ViewTokenPtr child_view_token) { |
182 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 179 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
183 DCHECK(child_view_token); | 180 DCHECK(child_view_token); |
184 DVLOG(1) << "AddChild: parent=" << parent_state << ", child_key=" << child_key | 181 DVLOG(1) << "AddChild: parent=" << parent_state << ", child_key=" << child_key |
185 << ", child=" << child_view_token.get(); | 182 << ", child=" << child_view_token; |
186 | 183 |
187 // Check for duplicate children. | 184 // Check for duplicate children. |
188 if (parent_state->children().find(child_key) != | 185 if (parent_state->children().find(child_key) != |
189 parent_state->children().end()) { | 186 parent_state->children().end()) { |
190 LOG(ERROR) << "View attempted to add a child with a duplicate key: " | 187 LOG(ERROR) << "View attempted to add a child with a duplicate key: " |
191 << "parent=" << parent_state << ", child_key=" << child_key | 188 << "parent=" << parent_state << ", child_key=" << child_key |
192 << ", child=" << child_view_token.get(); | 189 << ", child=" << child_view_token; |
193 UnregisterView(parent_state); | 190 UnregisterView(parent_state); |
194 return; | 191 return; |
195 } | 192 } |
196 | 193 |
197 // Check whether the desired child view still exists. | 194 // Check whether the desired child view still exists. |
198 // Adding a non-existent child still succeeds but the view manager will | 195 // Adding a non-existent child still succeeds but the view manager will |
199 // immediately report it as being unavailable. | 196 // immediately report it as being unavailable. |
200 ViewState* child_state = FindView(child_view_token->value); | 197 ViewState* child_state = FindView(child_view_token->value); |
201 if (!child_state) { | 198 if (!child_state) { |
202 LinkChildAsUnavailable(parent_state, child_key); | 199 LinkChildAsUnavailable(parent_state, child_key); |
(...skipping 30 matching lines...) Expand all Loading... |
233 void ViewRegistry::LayoutChild( | 230 void ViewRegistry::LayoutChild( |
234 ViewState* parent_state, | 231 ViewState* parent_state, |
235 uint32_t child_key, | 232 uint32_t child_key, |
236 mojo::ui::ViewLayoutParamsPtr child_layout_params, | 233 mojo::ui::ViewLayoutParamsPtr child_layout_params, |
237 const ViewLayoutCallback& callback) { | 234 const ViewLayoutCallback& callback) { |
238 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 235 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
239 DCHECK(child_layout_params); | 236 DCHECK(child_layout_params); |
240 DCHECK(child_layout_params->constraints); | 237 DCHECK(child_layout_params->constraints); |
241 DVLOG(1) << "LayoutChild: parent=" << parent_state | 238 DVLOG(1) << "LayoutChild: parent=" << parent_state |
242 << ", child_key=" << child_key | 239 << ", child_key=" << child_key |
243 << ", child_layout_params=" << child_layout_params.get(); | 240 << ", child_layout_params=" << child_layout_params; |
244 | 241 |
245 // Check whether the layout parameters are well-formed. | 242 // Check whether the layout parameters are well-formed. |
246 if (!AreViewLayoutParamsValid(child_layout_params.get())) { | 243 if (!AreViewLayoutParamsValid(child_layout_params.get())) { |
247 LOG(ERROR) << "View provided invalid child layout parameters: " | 244 LOG(ERROR) << "View provided invalid child layout parameters: " |
248 << "parent=" << parent_state << ", child_key=" << child_key | 245 << "parent=" << parent_state << ", child_key=" << child_key |
249 << ", child_layout_params=" << child_layout_params.get(); | 246 << ", child_layout_params=" << child_layout_params; |
250 UnregisterView(parent_state); | 247 UnregisterView(parent_state); |
251 callback.Run(nullptr); | 248 callback.Run(nullptr); |
252 return; | 249 return; |
253 } | 250 } |
254 | 251 |
255 // Check whether the child key exists in the parent. | 252 // Check whether the child key exists in the parent. |
256 auto child_it = parent_state->children().find(child_key); | 253 auto child_it = parent_state->children().find(child_key); |
257 if (child_it == parent_state->children().end()) { | 254 if (child_it == parent_state->children().end()) { |
258 LOG(ERROR) << "View attempted to layout a child with an invalid key: " | 255 LOG(ERROR) << "View attempted to layout a child with an invalid key: " |
259 << "parent=" << parent_state << ", child_key=" << child_key | 256 << "parent=" << parent_state << ", child_key=" << child_key |
260 << ", child_layout_params=" << child_layout_params.get(); | 257 << ", child_layout_params=" << child_layout_params; |
261 UnregisterView(parent_state); | 258 UnregisterView(parent_state); |
262 callback.Run(nullptr); | 259 callback.Run(nullptr); |
263 return; | 260 return; |
264 } | 261 } |
265 | 262 |
266 SetLayout(child_it->second, child_layout_params.Pass(), callback); | 263 SetLayout(child_it->second, child_layout_params.Pass(), callback); |
267 } | 264 } |
268 | 265 |
| 266 void ViewRegistry::ConnectToViewService( |
| 267 ViewState* view_state, |
| 268 const mojo::String& service_name, |
| 269 mojo::ScopedMessagePipeHandle client_handle) { |
| 270 DCHECK(IsViewStateRegisteredDebug(view_state)); |
| 271 |
| 272 associate_table_.ConnectToViewService(view_state->view_token()->Clone(), |
| 273 service_name, client_handle.Pass()); |
| 274 } |
| 275 |
269 void ViewRegistry::RequestLayout(ViewTreeState* tree_state) { | 276 void ViewRegistry::RequestLayout(ViewTreeState* tree_state) { |
270 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 277 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
271 DVLOG(1) << "RequestLayout: tree=" << tree_state; | 278 DVLOG(1) << "RequestLayout: tree=" << tree_state; |
272 | 279 |
273 InvalidateLayoutForRoot(tree_state); | 280 InvalidateLayoutForRoot(tree_state); |
274 } | 281 } |
275 | 282 |
276 void ViewRegistry::SetRoot(ViewTreeState* tree_state, | 283 void ViewRegistry::SetRoot(ViewTreeState* tree_state, |
277 uint32_t root_key, | 284 uint32_t root_key, |
278 mojo::ui::ViewTokenPtr root_view_token) { | 285 mojo::ui::ViewTokenPtr root_view_token) { |
279 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 286 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
280 DCHECK(root_view_token); | 287 DCHECK(root_view_token); |
281 DVLOG(1) << "SetRoot: tree=" << tree_state << ", root_key=" << root_key | 288 DVLOG(1) << "SetRoot: tree=" << tree_state << ", root_key=" << root_key |
282 << ", root=" << root_view_token.get(); | 289 << ", root=" << root_view_token; |
283 | 290 |
284 // Check whether the desired root view still exists. | 291 // Check whether the desired root view still exists. |
285 // Using a non-existent root view still succeeds but the view manager will | 292 // Using a non-existent root view still succeeds but the view manager will |
286 // immediately report it as being unavailable. | 293 // immediately report it as being unavailable. |
287 ViewState* root_state = FindView(root_view_token->value); | 294 ViewState* root_state = FindView(root_view_token->value); |
288 if (root_state) { | 295 if (root_state) { |
289 HijackView(root_state); | 296 HijackView(root_state); |
290 LinkRoot(tree_state, root_state, root_key); | 297 LinkRoot(tree_state, root_state, root_key); |
291 } else { | 298 } else { |
292 SendRootUnavailable(tree_state, root_key); | 299 SendRootUnavailable(tree_state, root_key); |
(...skipping 10 matching lines...) Expand all Loading... |
303 tree_state->set_explicit_root(false); | 310 tree_state->set_explicit_root(false); |
304 } | 311 } |
305 | 312 |
306 void ViewRegistry::LayoutRoot(ViewTreeState* tree_state, | 313 void ViewRegistry::LayoutRoot(ViewTreeState* tree_state, |
307 mojo::ui::ViewLayoutParamsPtr root_layout_params, | 314 mojo::ui::ViewLayoutParamsPtr root_layout_params, |
308 const ViewLayoutCallback& callback) { | 315 const ViewLayoutCallback& callback) { |
309 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 316 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
310 DCHECK(root_layout_params); | 317 DCHECK(root_layout_params); |
311 DCHECK(root_layout_params->constraints); | 318 DCHECK(root_layout_params->constraints); |
312 DVLOG(1) << "LayoutRoot: tree=" << tree_state | 319 DVLOG(1) << "LayoutRoot: tree=" << tree_state |
313 << ", root_layout_params=" << root_layout_params.get(); | 320 << ", root_layout_params=" << root_layout_params; |
314 | 321 |
315 // Check whether the layout parameters are well-formed. | 322 // Check whether the layout parameters are well-formed. |
316 if (!AreViewLayoutParamsValid(root_layout_params.get())) { | 323 if (!AreViewLayoutParamsValid(root_layout_params.get())) { |
317 LOG(ERROR) << "View tree provided invalid root layout parameters: " | 324 LOG(ERROR) << "View tree provided invalid root layout parameters: " |
318 << "tree=" << tree_state | 325 << "tree=" << tree_state |
319 << ", root_layout_params=" << root_layout_params.get(); | 326 << ", root_layout_params=" << root_layout_params; |
320 UnregisterViewTree(tree_state); | 327 UnregisterViewTree(tree_state); |
321 callback.Run(nullptr); | 328 callback.Run(nullptr); |
322 return; | 329 return; |
323 } | 330 } |
324 | 331 |
325 // Check whether the client called LayoutRoot without first having actually | 332 // Check whether the client called LayoutRoot without first having actually |
326 // set a root. | 333 // set a root. |
327 if (!tree_state->explicit_root()) { | 334 if (!tree_state->explicit_root()) { |
328 LOG(ERROR) << "View tree attempted to layout the rout without having " | 335 LOG(ERROR) << "View tree attempted to layout the rout without having " |
329 "set one first: tree=" | 336 "set one first: tree=" |
330 << tree_state | 337 << tree_state << ", root_layout_params=" << root_layout_params; |
331 << ", root_layout_params=" << root_layout_params.get(); | |
332 UnregisterViewTree(tree_state); | 338 UnregisterViewTree(tree_state); |
333 callback.Run(nullptr); | 339 callback.Run(nullptr); |
334 return; | 340 return; |
335 } | 341 } |
336 | 342 |
337 // Check whether the root is unavailable and therefore cannot be laid out. | 343 // Check whether the root is unavailable and therefore cannot be laid out. |
338 // This is not an error. | 344 // This is not an error. |
339 if (!tree_state->root()) { | 345 if (!tree_state->root()) { |
340 callback.Run(nullptr); | 346 callback.Run(nullptr); |
341 return; | 347 return; |
342 } | 348 } |
343 | 349 |
344 SetLayout(tree_state->root(), root_layout_params.Pass(), callback); | 350 SetLayout(tree_state->root(), root_layout_params.Pass(), callback); |
345 } | 351 } |
346 | 352 |
347 ViewState* ViewRegistry::FindView(uint32_t view_token) { | 353 void ViewRegistry::ConnectToViewTreeService( |
348 auto it = views_by_token_.find(view_token); | 354 ViewTreeState* tree_state, |
| 355 const mojo::String& service_name, |
| 356 mojo::ScopedMessagePipeHandle client_handle) { |
| 357 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
| 358 |
| 359 associate_table_.ConnectToViewTreeService( |
| 360 tree_state->view_tree_token()->Clone(), service_name, |
| 361 client_handle.Pass()); |
| 362 } |
| 363 |
| 364 ViewState* ViewRegistry::FindView(uint32_t view_token_value) { |
| 365 auto it = views_by_token_.find(view_token_value); |
349 return it != views_by_token_.end() ? it->second : nullptr; | 366 return it != views_by_token_.end() ? it->second : nullptr; |
350 } | 367 } |
351 | 368 |
352 void ViewRegistry::LinkChild(ViewState* parent_state, | 369 void ViewRegistry::LinkChild(ViewState* parent_state, |
353 uint32_t child_key, | 370 uint32_t child_key, |
354 ViewState* child_state) { | 371 ViewState* child_state) { |
355 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 372 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
356 DCHECK(parent_state->children().find(child_key) == | 373 DCHECK(parent_state->children().find(child_key) == |
357 parent_state->children().end()); | 374 parent_state->children().end()); |
358 DCHECK(IsViewStateRegisteredDebug(child_state)); | 375 DCHECK(IsViewStateRegisteredDebug(child_state)); |
359 | 376 |
360 DVLOG(2) << "Added child " << child_key << " {" | 377 DVLOG(2) << "Added child " << child_key << " {" << child_state->label() |
361 << child_state->view_token_value() << "} to parent {" | 378 << "} to parent {" << parent_state->label() << "}"; |
362 << parent_state->view_token_value() << "}"; | |
363 | 379 |
364 parent_state->children().insert({child_key, child_state}); | 380 parent_state->children().insert({child_key, child_state}); |
365 child_state->SetParent(parent_state, child_key); | 381 child_state->SetParent(parent_state, child_key); |
366 | 382 |
367 // Schedule layout of the parent on behalf of its newly added child. | 383 // Schedule layout of the parent on behalf of its newly added child. |
368 // We don't need to schedule layout of the child until the parent provides | 384 // We don't need to schedule layout of the child until the parent provides |
369 // new layout parameters. | 385 // new layout parameters. |
370 InvalidateLayoutForChild(parent_state, child_key); | 386 InvalidateLayoutForChild(parent_state, child_key); |
371 } | 387 } |
372 | 388 |
373 void ViewRegistry::LinkChildAsUnavailable(ViewState* parent_state, | 389 void ViewRegistry::LinkChildAsUnavailable(ViewState* parent_state, |
374 uint32_t child_key) { | 390 uint32_t child_key) { |
375 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 391 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
376 DCHECK(parent_state->children().find(child_key) == | 392 DCHECK(parent_state->children().find(child_key) == |
377 parent_state->children().end()); | 393 parent_state->children().end()); |
378 | 394 |
379 DVLOG(2) << "Added unavailable child " << child_key << " to parent {" | 395 DVLOG(2) << "Added unavailable child " << child_key << " to parent {" |
380 << parent_state->view_token_value() << "}"; | 396 << parent_state->label() << "}"; |
381 | 397 |
382 parent_state->children().insert({child_key, nullptr}); | 398 parent_state->children().insert({child_key, nullptr}); |
383 SendChildUnavailable(parent_state, child_key); | 399 SendChildUnavailable(parent_state, child_key); |
384 | 400 |
385 // Don't schedule layout for the parent just yet. Wait for it to | 401 // Don't schedule layout for the parent just yet. Wait for it to |
386 // remove its child in response to the OnChildUnavailable notification. | 402 // remove its child in response to the OnChildUnavailable notification. |
387 } | 403 } |
388 | 404 |
389 void ViewRegistry::MarkChildAsUnavailable(ViewState* parent_state, | 405 void ViewRegistry::MarkChildAsUnavailable(ViewState* parent_state, |
390 uint32_t child_key) { | 406 uint32_t child_key) { |
391 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 407 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
392 auto child_it = parent_state->children().find(child_key); | 408 auto child_it = parent_state->children().find(child_key); |
393 DCHECK(child_it != parent_state->children().end()); | 409 DCHECK(child_it != parent_state->children().end()); |
394 DCHECK(child_it->second); | 410 DCHECK(child_it->second); |
395 | 411 |
396 DVLOG(2) << "Marked unavailable child " << child_key << " {" | 412 DVLOG(2) << "Marked unavailable child " << child_key << " {" |
397 << child_it->second->view_token_value() << "} from parent {" | 413 << child_it->second->label() << "} from parent {" |
398 << parent_state->view_token_value() << "}"; | 414 << parent_state->label() << "}"; |
399 | 415 |
400 ResetStateWhenUnlinking(child_it->second); | 416 ResetStateWhenUnlinking(child_it->second); |
401 child_it->second->ResetContainer(); | 417 child_it->second->ResetContainer(); |
402 child_it->second = nullptr; | 418 child_it->second = nullptr; |
403 SendChildUnavailable(parent_state, child_key); | 419 SendChildUnavailable(parent_state, child_key); |
404 | 420 |
405 // Don't schedule layout for the parent just yet. Wait for it to | 421 // Don't schedule layout for the parent just yet. Wait for it to |
406 // remove its child in response to the OnChildUnavailable notification. | 422 // remove its child in response to the OnChildUnavailable notification. |
407 // We don't need to schedule layout for the child either since it will | 423 // We don't need to schedule layout for the child either since it will |
408 // retain its old layout parameters. | 424 // retain its old layout parameters. |
409 } | 425 } |
410 | 426 |
411 void ViewRegistry::UnlinkChild(ViewState* parent_state, | 427 void ViewRegistry::UnlinkChild(ViewState* parent_state, |
412 ViewState::ChildrenMap::iterator child_it) { | 428 ViewState::ChildrenMap::iterator child_it) { |
413 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 429 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
414 DCHECK(child_it != parent_state->children().end()); | 430 DCHECK(child_it != parent_state->children().end()); |
415 | 431 |
416 ViewState* child_state = child_it->second; | 432 ViewState* child_state = child_it->second; |
417 if (child_state) { | 433 if (child_state) { |
418 DVLOG(2) << "Removed child " << child_state->key() << " {" | 434 DVLOG(2) << "Removed child " << child_state->key() << " {" |
419 << child_state->view_token_value() << "} from parent {" | 435 << child_state->label() << "} from parent {" |
420 << parent_state->view_token_value() << "}"; | 436 << parent_state->label() << "}"; |
421 ResetStateWhenUnlinking(child_it->second); | 437 ResetStateWhenUnlinking(child_it->second); |
422 child_state->ResetContainer(); | 438 child_state->ResetContainer(); |
423 } else { | 439 } else { |
424 DVLOG(2) << "Removed unavailable child " << child_it->first | 440 DVLOG(2) << "Removed unavailable child " << child_it->first |
425 << "} from parent {" << parent_state->view_token_value() << "}"; | 441 << "} from parent {" << parent_state->label() << "}"; |
426 } | 442 } |
427 parent_state->children().erase(child_it); | 443 parent_state->children().erase(child_it); |
428 | 444 |
429 // Schedule layout for the parent now that it has lost its child. | 445 // Schedule layout for the parent now that it has lost its child. |
430 // We don't need to schedule layout for the child itself since it will | 446 // We don't need to schedule layout for the child itself since it will |
431 // retain its old layout parameters. | 447 // retain its old layout parameters. |
432 InvalidateLayout(parent_state); | 448 InvalidateLayout(parent_state); |
433 } | 449 } |
434 | 450 |
| 451 ViewTreeState* ViewRegistry::FindViewTree(uint32_t view_tree_token_value) { |
| 452 auto it = view_trees_by_token_.find(view_tree_token_value); |
| 453 return it != view_trees_by_token_.end() ? it->second : nullptr; |
| 454 } |
| 455 |
435 void ViewRegistry::LinkRoot(ViewTreeState* tree_state, | 456 void ViewRegistry::LinkRoot(ViewTreeState* tree_state, |
436 ViewState* root_state, | 457 ViewState* root_state, |
437 uint32_t root_key) { | 458 uint32_t root_key) { |
438 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 459 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
439 DCHECK(IsViewStateRegisteredDebug(root_state)); | 460 DCHECK(IsViewStateRegisteredDebug(root_state)); |
440 DCHECK(!tree_state->root()); | 461 DCHECK(!tree_state->root()); |
441 DCHECK(!root_state->parent()); | 462 DCHECK(!root_state->parent()); |
442 | 463 |
443 DVLOG(2) << "Linked view tree root " << root_key << " {" | 464 DVLOG(2) << "Linked view tree root " << root_key << " {" |
444 << root_state->view_token_value() << "}"; | 465 << root_state->label() << "}"; |
445 | 466 |
446 tree_state->SetRoot(root_state, root_key); | 467 tree_state->SetRoot(root_state, root_key); |
447 | 468 |
448 // Schedule layout of the tree on behalf of its newly added root. | 469 // Schedule layout of the tree on behalf of its newly added root. |
449 // We don't need to schedule layout of the root until the tree provides | 470 // We don't need to schedule layout of the root until the tree provides |
450 // new layout parameters. | 471 // new layout parameters. |
451 InvalidateLayoutForRoot(tree_state); | 472 InvalidateLayoutForRoot(tree_state); |
452 } | 473 } |
453 | 474 |
454 void ViewRegistry::UnlinkRoot(ViewTreeState* tree_state) { | 475 void ViewRegistry::UnlinkRoot(ViewTreeState* tree_state) { |
455 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 476 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
456 DCHECK(tree_state->root()); | 477 DCHECK(tree_state->root()); |
457 | 478 |
458 DVLOG(2) << "Unlinked view tree root " << tree_state->root()->key() << " {" | 479 DVLOG(2) << "Unlinked view tree root " << tree_state->root()->key() << " {" |
459 << tree_state->root()->view_token_value() << "}"; | 480 << tree_state->root()->label() << "}"; |
460 | 481 |
461 ResetStateWhenUnlinking(tree_state->root()); | 482 ResetStateWhenUnlinking(tree_state->root()); |
462 tree_state->ResetRoot(); | 483 tree_state->ResetRoot(); |
463 | 484 |
464 // We don't need to schedule layout for the root since it will retain | 485 // We don't need to schedule layout for the root since it will retain |
465 // its old layout parameters. | 486 // its old layout parameters. |
466 } | 487 } |
467 | 488 |
468 void ViewRegistry::HijackView(ViewState* view_state) { | 489 void ViewRegistry::HijackView(ViewState* view_state) { |
469 if (view_state->parent()) { | 490 if (view_state->parent()) { |
470 MarkChildAsUnavailable(view_state->parent(), view_state->key()); | 491 MarkChildAsUnavailable(view_state->parent(), view_state->key()); |
471 } else if (view_state->tree()) { | 492 } else if (view_state->tree()) { |
472 ViewTreeState* tree_state = view_state->tree(); | 493 ViewTreeState* tree_state = view_state->tree(); |
473 uint32_t root_key = tree_state->root()->key(); | 494 uint32_t root_key = tree_state->root()->key(); |
474 UnlinkRoot(tree_state); | 495 UnlinkRoot(tree_state); |
475 SendRootUnavailable(tree_state, root_key); | 496 SendRootUnavailable(tree_state, root_key); |
476 } | 497 } |
477 } | 498 } |
478 | 499 |
479 void ViewRegistry::InvalidateLayout(ViewState* view_state) { | 500 void ViewRegistry::InvalidateLayout(ViewState* view_state) { |
480 DCHECK(IsViewStateRegisteredDebug(view_state)); | 501 DCHECK(IsViewStateRegisteredDebug(view_state)); |
481 | 502 |
482 // We can consider the layout request to have been satisfied if | 503 // We can consider the layout request to have been satisfied if |
483 // there is already a pending layout request in the queue that has not | 504 // there is already a pending layout request in the queue that has not |
484 // yet been issued (this is coalescing). Otherwise we must manufacture | 505 // yet been issued (this is coalescing). Otherwise we must manufacture |
485 // a new one based on the current layout parameters. | 506 // a new one based on the current layout parameters. |
486 if (view_state->layout_params() && | 507 if (view_state->layout_params() && |
487 (view_state->pending_layout_requests().empty() || | 508 (view_state->pending_layout_requests().empty() || |
488 view_state->pending_layout_requests().back()->issued())) { | 509 view_state->pending_layout_requests().back()->issued())) { |
489 EnqueueLayoutRequest(view_state, view_state->layout_params().Clone()); | 510 EnqueueLayoutRequest(view_state, view_state->layout_params()->Clone()); |
490 IssueNextViewLayoutRequest(view_state); | 511 IssueNextViewLayoutRequest(view_state); |
491 } | 512 } |
492 } | 513 } |
493 | 514 |
494 void ViewRegistry::InvalidateLayoutForChild(ViewState* parent_state, | 515 void ViewRegistry::InvalidateLayoutForChild(ViewState* parent_state, |
495 uint32_t child_key) { | 516 uint32_t child_key) { |
496 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 517 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
497 DCHECK(parent_state->children().find(child_key) != | 518 DCHECK(parent_state->children().find(child_key) != |
498 parent_state->children().end()); | 519 parent_state->children().end()); |
499 | 520 |
(...skipping 12 matching lines...) Expand all Loading... |
512 | 533 |
513 void ViewRegistry::SetLayout(ViewState* view_state, | 534 void ViewRegistry::SetLayout(ViewState* view_state, |
514 mojo::ui::ViewLayoutParamsPtr layout_params, | 535 mojo::ui::ViewLayoutParamsPtr layout_params, |
515 const ViewLayoutCallback& callback) { | 536 const ViewLayoutCallback& callback) { |
516 DCHECK(IsViewStateRegisteredDebug(view_state)); | 537 DCHECK(IsViewStateRegisteredDebug(view_state)); |
517 DCHECK(AreViewLayoutParamsValid(layout_params.get())); | 538 DCHECK(AreViewLayoutParamsValid(layout_params.get())); |
518 | 539 |
519 // Check whether the currently cached layout parameters are the same | 540 // Check whether the currently cached layout parameters are the same |
520 // and we already have a result and we have no pending layout requests. | 541 // and we already have a result and we have no pending layout requests. |
521 if (view_state->pending_layout_requests().empty() && | 542 if (view_state->pending_layout_requests().empty() && |
522 view_state->layout_params() && view_state->layout_info() && | 543 view_state->layout_params() && |
523 view_state->layout_params()->Equals(*layout_params)) { | 544 view_state->layout_params()->Equals(*layout_params)) { |
524 DVLOG(2) << "Layout cache hit"; | 545 mojo::ui::ViewLayoutInfoPtr info = view_state->CreateLayoutInfo(); |
525 callback.Run(view_state->layout_info().Clone()); | 546 if (info) { |
526 return; | 547 DVLOG(2) << "Layout cache hit"; |
| 548 view_state->set_scene_changed_since_last_report(false); |
| 549 callback.Run(info.Pass()); |
| 550 return; |
| 551 } |
527 } | 552 } |
528 | 553 |
529 // Check whether the layout parameters are different from the most | 554 // Check whether the layout parameters are different from the most |
530 // recent pending layout request if we have one. | 555 // recent pending layout request if we have one. |
531 if (view_state->pending_layout_requests().empty() || | 556 if (view_state->pending_layout_requests().empty() || |
532 !view_state->pending_layout_requests().back()->layout_params()->Equals( | 557 !view_state->pending_layout_requests().back()->layout_params()->Equals( |
533 *layout_params)) { | 558 *layout_params)) { |
534 // Enqueue a new request for these parameters. | 559 // Enqueue a new request for these parameters. |
535 EnqueueLayoutRequest(view_state, layout_params.Pass()); | 560 EnqueueLayoutRequest(view_state, layout_params.Pass()); |
536 } | 561 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 tree_state->set_layout_request_issued(true); | 602 tree_state->set_layout_request_issued(true); |
578 SendViewTreeLayoutRequest(tree_state); | 603 SendViewTreeLayoutRequest(tree_state); |
579 } | 604 } |
580 } | 605 } |
581 | 606 |
582 void ViewRegistry::ResetStateWhenUnlinking(ViewState* view_state) { | 607 void ViewRegistry::ResetStateWhenUnlinking(ViewState* view_state) { |
583 // Clean up parent's recorded state for the child. | 608 // Clean up parent's recorded state for the child. |
584 if (view_state->parent()) { | 609 if (view_state->parent()) { |
585 view_state->parent()->children_needing_layout().erase(view_state->key()); | 610 view_state->parent()->children_needing_layout().erase(view_state->key()); |
586 } | 611 } |
587 | |
588 // Clean up child's recorded state for the parent or tree. | |
589 if (view_state->wrapped_surface()) { | |
590 surface_manager_->DestroySurface(view_state->wrapped_surface().Pass()); | |
591 } | |
592 } | 612 } |
593 | 613 |
594 void ViewRegistry::SendChildUnavailable(ViewState* parent_state, | 614 void ViewRegistry::SendChildUnavailable(ViewState* parent_state, |
595 uint32_t child_key) { | 615 uint32_t child_key) { |
596 DCHECK(IsViewStateRegisteredDebug(parent_state)); | 616 DCHECK(IsViewStateRegisteredDebug(parent_state)); |
597 | 617 |
598 // TODO: Detect ANRs | 618 // TODO: Detect ANRs |
599 DVLOG(1) << "SendChildUnavailable: child_key=" << child_key; | 619 DVLOG(1) << "SendChildUnavailable: child_key=" << child_key; |
600 parent_state->view()->OnChildUnavailable(child_key, | 620 parent_state->view()->OnChildUnavailable(child_key, |
601 base::Bind(&base::DoNothing)); | 621 base::Bind(&base::DoNothing)); |
602 } | 622 } |
603 | 623 |
604 void ViewRegistry::SendRootUnavailable(ViewTreeState* tree_state, | 624 void ViewRegistry::SendRootUnavailable(ViewTreeState* tree_state, |
605 uint32_t root_key) { | 625 uint32_t root_key) { |
606 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 626 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
607 | 627 |
608 // TODO: Detect ANRs | 628 // TODO: Detect ANRs |
609 DVLOG(1) << "SendRootUnavailable: root_key=" << root_key; | 629 DVLOG(1) << "SendRootUnavailable: root_key=" << root_key; |
610 tree_state->view_tree()->OnRootUnavailable(root_key, | 630 tree_state->view_tree()->OnRootUnavailable(root_key, |
611 base::Bind(&base::DoNothing)); | 631 base::Bind(&base::DoNothing)); |
612 } | 632 } |
613 | 633 |
614 void ViewRegistry::SendViewLayoutRequest(ViewState* view_state) { | 634 void ViewRegistry::SendViewLayoutRequest(ViewState* view_state) { |
615 DCHECK(IsViewStateRegisteredDebug(view_state)); | 635 DCHECK(IsViewStateRegisteredDebug(view_state)); |
616 DCHECK(!view_state->pending_layout_requests().empty()); | 636 DCHECK(!view_state->pending_layout_requests().empty()); |
617 DCHECK(view_state->pending_layout_requests().front()->issued()); | 637 DCHECK(view_state->pending_layout_requests().front()->issued()); |
618 | 638 |
619 // TODO: Detect ANRs | 639 // TODO: Detect ANRs |
620 DVLOG(1) << "SendViewLayoutRequest: view.token=" | 640 DVLOG(1) << "SendViewLayoutRequest: view.token=" << view_state->label(); |
621 << view_state->view_token_value(); | |
622 view_state->view()->OnLayout( | 641 view_state->view()->OnLayout( |
623 view_state->pending_layout_requests().front()->layout_params()->Clone(), | 642 view_state->pending_layout_requests().front()->layout_params()->Clone(), |
624 mojo::Array<uint32_t>::From(view_state->children_needing_layout()), | 643 mojo::Array<uint32_t>::From(view_state->children_needing_layout()), |
625 base::Bind(&ViewRegistry::OnViewLayoutResult, base::Unretained(this), | 644 base::Bind(&ViewRegistry::OnViewLayoutResult, base::Unretained(this), |
626 view_state->GetWeakPtr())); | 645 view_state->GetWeakPtr())); |
627 view_state->children_needing_layout().clear(); | 646 view_state->children_needing_layout().clear(); |
628 } | 647 } |
629 | 648 |
630 void ViewRegistry::SendViewTreeLayoutRequest(ViewTreeState* tree_state) { | 649 void ViewRegistry::SendViewTreeLayoutRequest(ViewTreeState* tree_state) { |
631 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); | 650 DCHECK(IsViewTreeStateRegisteredDebug(tree_state)); |
632 DCHECK(tree_state->layout_request_issued()); | 651 DCHECK(tree_state->layout_request_issued()); |
633 | 652 |
634 // TODO: Detect ANRs | 653 // TODO: Detect ANRs |
635 DVLOG(1) << "SendViewTreeLayoutRequest"; | 654 DVLOG(1) << "SendViewTreeLayoutRequest"; |
636 tree_state->view_tree()->OnLayout( | 655 tree_state->view_tree()->OnLayout( |
637 base::Bind(&ViewRegistry::OnViewTreeLayoutResult, base::Unretained(this), | 656 base::Bind(&ViewRegistry::OnViewTreeLayoutResult, base::Unretained(this), |
638 tree_state->GetWeakPtr())); | 657 tree_state->GetWeakPtr())); |
639 } | 658 } |
640 | 659 |
641 static bool IsSizeInBounds(mojo::ui::BoxConstraints* constraints, | 660 static bool IsSizeInBounds(mojo::ui::BoxConstraints* constraints, |
642 mojo::Size* size) { | 661 mojo::Size* size) { |
643 return size && size->width >= constraints->min_width && | 662 return size && size->width >= constraints->min_width && |
644 size->width <= constraints->max_width && | 663 size->width <= constraints->max_width && |
645 size->height >= constraints->min_height && | 664 size->height >= constraints->min_height && |
646 size->height <= constraints->max_height; | 665 size->height <= constraints->max_height; |
647 } | 666 } |
648 | 667 |
649 void ViewRegistry::OnViewLayoutResult(base::WeakPtr<ViewState> view_state_weak, | 668 void ViewRegistry::OnViewLayoutResult(base::WeakPtr<ViewState> view_state_weak, |
650 mojo::ui::ViewLayoutInfoPtr info) { | 669 mojo::ui::ViewLayoutResultPtr result) { |
651 DCHECK(info); | 670 DCHECK(result); |
652 DCHECK(info->surface_id); // checked by mojom | |
653 | 671 |
654 ViewState* view_state = view_state_weak.get(); | 672 ViewState* view_state = view_state_weak.get(); |
655 if (!view_state) | 673 if (!view_state) |
656 return; | 674 return; |
657 | 675 |
658 DCHECK(!view_state->pending_layout_requests().empty()); | 676 DCHECK(!view_state->pending_layout_requests().empty()); |
659 DCHECK(view_state->pending_layout_requests().front()->issued()); | 677 DCHECK(view_state->pending_layout_requests().front()->issued()); |
660 | 678 |
661 std::unique_ptr<ViewLayoutRequest> request( | 679 std::unique_ptr<ViewLayoutRequest> request( |
662 std::move(view_state->pending_layout_requests().front())); | 680 std::move(view_state->pending_layout_requests().front())); |
663 view_state->pending_layout_requests().erase( | 681 view_state->pending_layout_requests().erase( |
664 view_state->pending_layout_requests().begin()); | 682 view_state->pending_layout_requests().begin()); |
665 | 683 |
666 DVLOG(1) << "OnViewLayoutResult: view=" << view_state | 684 DVLOG(1) << "OnViewLayoutResult: view=" << view_state |
667 << ", params=" << request->layout_params() | 685 << ", params=" << request->layout_params() << ", result=" << result; |
668 << ", info=" << info.get(); | |
669 | 686 |
670 // Validate the layout info. | 687 // Validate the layout info. |
671 if (!IsSizeInBounds(request->layout_params()->constraints.get(), | 688 if (!IsSizeInBounds(request->layout_params()->constraints.get(), |
672 info->size.get())) { | 689 result->size.get())) { |
673 LOG(ERROR) << "View returned invalid size in its layout info: " | 690 LOG(ERROR) << "View returned invalid size in its layout info: " |
674 << "view=" << view_state | 691 << "view=" << view_state |
675 << ", params=" << request->layout_params() | 692 << ", params=" << request->layout_params() |
676 << ", info=" << info.get(); | 693 << ", result=" << result; |
677 UnregisterView(view_state); | 694 UnregisterView(view_state); |
678 return; | 695 return; |
679 } | 696 } |
680 | 697 |
681 // Assume the parent or root will not see the new layout information if | 698 // Assume the parent or root will not see the new layout information if |
682 // there are no callbacks so we need to inform it when things change. | 699 // there are no callbacks so we need to inform it when things change. |
683 const bool size_changed = | 700 const bool size_changed = |
684 !view_state->layout_info() || | 701 !view_state->layout_result() || |
685 !view_state->layout_info()->size->Equals(*info->size); | 702 !view_state->layout_result()->size->Equals(*result->size); |
686 const bool surface_changed = | |
687 !view_state->layout_info() || | |
688 !view_state->layout_info()->surface_id->Equals(*info->surface_id); | |
689 const bool recurse = | 703 const bool recurse = |
690 !request->has_callbacks() && (surface_changed || size_changed); | 704 !request->has_callbacks() && |
| 705 (size_changed || view_state->scene_changed_since_last_report()); |
691 | 706 |
692 view_state->layout_params() = request->TakeLayoutParams().Pass(); | 707 view_state->set_layout_params(request->TakeLayoutParams().Pass()); |
693 view_state->layout_info() = info.Pass(); | 708 view_state->set_layout_result(result.Pass()); |
694 | 709 |
695 if (surface_changed) { | 710 mojo::ui::ViewLayoutInfoPtr info = view_state->CreateLayoutInfo(); |
696 if (view_state->wrapped_surface()) | 711 if (info) { |
697 surface_manager_->DestroySurface(view_state->wrapped_surface().Pass()); | 712 view_state->set_scene_changed_since_last_report(false); |
698 view_state->wrapped_surface() = surface_manager_->CreateWrappedSurface( | 713 request->DispatchLayoutInfo(info.Pass()); |
699 view_state->layout_info()->surface_id.get()); | |
700 } | 714 } |
701 | 715 |
702 request->DispatchLayoutInfo(view_state->layout_info().get()); | |
703 | |
704 if (recurse) { | 716 if (recurse) { |
705 if (view_state->parent()) { | 717 if (view_state->parent()) { |
706 InvalidateLayoutForChild(view_state->parent(), view_state->key()); | 718 InvalidateLayoutForChild(view_state->parent(), view_state->key()); |
707 } else if (view_state->tree()) { | 719 } else if (view_state->tree()) { |
708 InvalidateLayoutForRoot(view_state->tree()); | 720 InvalidateLayoutForRoot(view_state->tree()); |
709 } | 721 } |
710 } | 722 } |
711 | 723 |
712 IssueNextViewLayoutRequest(view_state); | 724 IssueNextViewLayoutRequest(view_state); |
713 } | 725 } |
714 | 726 |
715 void ViewRegistry::OnViewTreeLayoutResult( | 727 void ViewRegistry::OnViewTreeLayoutResult( |
716 base::WeakPtr<ViewTreeState> tree_state_weak) { | 728 base::WeakPtr<ViewTreeState> tree_state_weak) { |
717 ViewTreeState* tree_state = tree_state_weak.get(); | 729 ViewTreeState* tree_state = tree_state_weak.get(); |
718 if (tree_state) { | 730 if (tree_state) { |
719 DCHECK(tree_state->layout_request_issued()); | 731 DCHECK(tree_state->layout_request_issued()); |
720 | 732 |
721 DVLOG(1) << "OnViewTreeLayoutResult"; | 733 DVLOG(1) << "OnViewTreeLayoutResult"; |
722 | 734 |
723 tree_state->set_layout_request_issued(false); | 735 tree_state->set_layout_request_issued(false); |
724 IssueNextViewTreeLayoutRequest(tree_state); | 736 IssueNextViewTreeLayoutRequest(tree_state); |
725 } | 737 } |
726 } | 738 } |
727 | 739 |
728 } // namespace view_manager | 740 } // namespace view_manager |
OLD | NEW |