Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: components/view_manager/connection_manager.cc

Issue 1344573002: Mandoline: Rename components/view_manager to components/mus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "components/view_manager/connection_manager.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "cc/output/compositor_frame.h"
10 #include "cc/quads/shared_quad_state.h"
11 #include "components/view_manager/client_connection.h"
12 #include "components/view_manager/connection_manager_delegate.h"
13 #include "components/view_manager/server_view.h"
14 #include "components/view_manager/view_coordinate_conversions.h"
15 #include "components/view_manager/view_tree_host_connection.h"
16 #include "components/view_manager/view_tree_impl.h"
17 #include "mojo/application/public/cpp/application_connection.h"
18 #include "mojo/converters/geometry/geometry_type_converters.h"
19 #include "mojo/converters/input_events/input_events_type_converters.h"
20 #include "mojo/converters/surfaces/surfaces_type_converters.h"
21 #include "ui/gfx/geometry/size_conversions.h"
22
23 using mojo::ConnectionSpecificId;
24
25 namespace view_manager {
26
27 ConnectionManager::ScopedChange::ScopedChange(
28 ViewTreeImpl* connection,
29 ConnectionManager* connection_manager,
30 bool is_delete_view)
31 : connection_manager_(connection_manager),
32 connection_id_(connection->id()),
33 is_delete_view_(is_delete_view) {
34 connection_manager_->PrepareForChange(this);
35 }
36
37 ConnectionManager::ScopedChange::~ScopedChange() {
38 connection_manager_->FinishChange();
39 }
40
41 ConnectionManager::ConnectionManager(
42 ConnectionManagerDelegate* delegate,
43 const scoped_refptr<surfaces::SurfacesState>& surfaces_state)
44 : delegate_(delegate),
45 surfaces_state_(surfaces_state),
46 next_connection_id_(1),
47 next_host_id_(0),
48 current_change_(nullptr),
49 in_destructor_(false) {
50 }
51
52 ConnectionManager::~ConnectionManager() {
53 in_destructor_ = true;
54
55 // Copy the HostConnectionMap because it will be mutated as the connections
56 // are closed.
57 HostConnectionMap host_connection_map(host_connection_map_);
58 for (auto& pair : host_connection_map)
59 pair.second->CloseConnection();
60
61 STLDeleteValues(&connection_map_);
62 // All the connections should have been destroyed.
63 DCHECK(host_connection_map_.empty());
64 DCHECK(connection_map_.empty());
65 }
66
67 void ConnectionManager::AddHost(
68 ViewTreeHostConnection* host_connection) {
69 DCHECK_EQ(0u, host_connection_map_.count(host_connection->view_tree_host()));
70 host_connection_map_[host_connection->view_tree_host()] = host_connection;
71 }
72
73 ServerView* ConnectionManager::CreateServerView(const ViewId& id) {
74 ServerView* view = new ServerView(this, id);
75 view->AddObserver(this);
76 return view;
77 }
78
79 ConnectionSpecificId ConnectionManager::GetAndAdvanceNextConnectionId() {
80 const ConnectionSpecificId id = next_connection_id_++;
81 DCHECK_LT(id, next_connection_id_);
82 return id;
83 }
84
85 uint16_t ConnectionManager::GetAndAdvanceNextHostId() {
86 const uint16_t id = next_host_id_++;
87 DCHECK_LT(id, next_host_id_);
88 return id;
89 }
90
91 void ConnectionManager::OnConnectionError(ClientConnection* connection) {
92 // This will be null if the root has been destroyed.
93 const ViewId* view_id = connection->service()->root();
94 ServerView* view =
95 view_id ? GetView(*connection->service()->root()) : nullptr;
96 // If the ViewTree root is a viewport root, then we'll wait until
97 // the root connection goes away to cleanup.
98 if (view && (GetRootView(view) == view))
99 return;
100
101 scoped_ptr<ClientConnection> connection_owner(connection);
102
103 connection_map_.erase(connection->service()->id());
104
105 // Notify remaining connections so that they can cleanup.
106 for (auto& pair : connection_map_) {
107 pair.second->service()->OnWillDestroyViewTreeImpl(
108 connection->service());
109 }
110 }
111
112 void ConnectionManager::OnHostConnectionClosed(
113 ViewTreeHostConnection* connection) {
114 auto it = host_connection_map_.find(connection->view_tree_host());
115 DCHECK(it != host_connection_map_.end());
116
117 // Get the ClientConnection by ViewTreeImpl ID.
118 ConnectionMap::iterator service_connection_it =
119 connection_map_.find(it->first->GetViewTree()->id());
120 DCHECK(service_connection_it != connection_map_.end());
121
122 // Tear down the associated ViewTree connection.
123 // TODO(fsamuel): I don't think this is quite right, we should tear down all
124 // connections within the root's viewport. We should probably employ an
125 // observer pattern to do this. Each ViewTreeImpl should track its
126 // parent's lifetime.
127 host_connection_map_.erase(it);
128 OnConnectionError(service_connection_it->second);
129
130 // If we have no more roots left, let the app know so it can terminate.
131 if (!host_connection_map_.size())
132 delegate_->OnNoMoreRootConnections();
133 }
134
135 void ConnectionManager::EmbedAtView(mojo::ConnectionSpecificId creator_id,
136 const ViewId& view_id,
137 mojo::URLRequestPtr request) {
138 mojo::ViewTreePtr service_ptr;
139 ClientConnection* client_connection =
140 delegate_->CreateClientConnectionForEmbedAtView(
141 this, GetProxy(&service_ptr), creator_id, request.Pass(), view_id);
142 AddConnection(client_connection);
143 client_connection->service()->Init(client_connection->client(),
144 service_ptr.Pass());
145 OnConnectionMessagedClient(client_connection->service()->id());
146 }
147
148 ViewTreeImpl* ConnectionManager::EmbedAtView(
149 mojo::ConnectionSpecificId creator_id,
150 const ViewId& view_id,
151 mojo::ViewTreeClientPtr client) {
152 mojo::ViewTreePtr service_ptr;
153 ClientConnection* client_connection =
154 delegate_->CreateClientConnectionForEmbedAtView(
155 this, GetProxy(&service_ptr), creator_id, view_id, client.Pass());
156 AddConnection(client_connection);
157 client_connection->service()->Init(client_connection->client(),
158 service_ptr.Pass());
159 OnConnectionMessagedClient(client_connection->service()->id());
160
161 return client_connection->service();
162 }
163
164 ViewTreeImpl* ConnectionManager::GetConnection(
165 ConnectionSpecificId connection_id) {
166 ConnectionMap::iterator i = connection_map_.find(connection_id);
167 return i == connection_map_.end() ? nullptr : i->second->service();
168 }
169
170 ServerView* ConnectionManager::GetView(const ViewId& id) {
171 for (auto& pair : host_connection_map_) {
172 if (pair.first->root_view()->id() == id)
173 return pair.first->root_view();
174 }
175 ViewTreeImpl* service = GetConnection(id.connection_id);
176 return service ? service->GetView(id) : nullptr;
177 }
178
179 bool ConnectionManager::IsViewAttachedToRoot(const ServerView* view) const {
180 for (auto& pair : host_connection_map_) {
181 if (pair.first->IsViewAttachedToRoot(view))
182 return true;
183 }
184 return false;
185 }
186
187 void ConnectionManager::SchedulePaint(const ServerView* view,
188 const gfx::Rect& bounds) {
189 for (auto& pair : host_connection_map_) {
190 if (pair.first->SchedulePaintIfInViewport(view, bounds))
191 return;
192 }
193 }
194
195 void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) {
196 if (current_change_)
197 current_change_->MarkConnectionAsMessaged(id);
198 }
199
200 bool ConnectionManager::DidConnectionMessageClient(
201 ConnectionSpecificId id) const {
202 return current_change_ && current_change_->DidMessageConnection(id);
203 }
204
205 mojo::ViewportMetricsPtr ConnectionManager::GetViewportMetricsForView(
206 const ServerView* view) {
207 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
208 if (host)
209 return host->GetViewportMetrics().Clone();
210
211 if (!host_connection_map_.empty())
212 return host_connection_map_.begin()->first->GetViewportMetrics().Clone();
213
214 mojo::ViewportMetricsPtr metrics = mojo::ViewportMetrics::New();
215 metrics->size_in_pixels = mojo::Size::New();
216 return metrics.Pass();
217 }
218
219 const ViewTreeImpl* ConnectionManager::GetConnectionWithRoot(
220 const ViewId& id) const {
221 for (auto& pair : connection_map_) {
222 if (pair.second->service()->IsRoot(id))
223 return pair.second->service();
224 }
225 return nullptr;
226 }
227
228 ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView(
229 const ServerView* view) {
230 return const_cast<ViewTreeHostImpl*>(
231 static_cast<const ConnectionManager*>(this)->GetViewTreeHostByView(view));
232 }
233
234 const ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView(
235 const ServerView* view) const {
236 while (view && view->parent())
237 view = view->parent();
238 for (auto& pair : host_connection_map_) {
239 if (view == pair.first->root_view())
240 return pair.first;
241 }
242 return nullptr;
243 }
244
245 ViewTreeImpl* ConnectionManager::GetEmbedRoot(ViewTreeImpl* service) {
246 while (service) {
247 const ViewId* root_id = service->root();
248 if (!root_id || root_id->connection_id == service->id())
249 return nullptr;
250
251 ViewTreeImpl* parent_service = GetConnection(root_id->connection_id);
252 service = parent_service;
253 if (service && service->is_embed_root())
254 return service;
255 }
256 return nullptr;
257 }
258
259 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
260 const gfx::Rect& old_bounds,
261 const gfx::Rect& new_bounds) {
262 for (auto& pair : connection_map_) {
263 pair.second->service()->ProcessViewBoundsChanged(
264 view, old_bounds, new_bounds, IsChangeSource(pair.first));
265 }
266 }
267
268 void ConnectionManager::ProcessWillChangeViewHierarchy(
269 const ServerView* view,
270 const ServerView* new_parent,
271 const ServerView* old_parent) {
272 for (auto& pair : connection_map_) {
273 pair.second->service()->ProcessWillChangeViewHierarchy(
274 view, new_parent, old_parent, IsChangeSource(pair.first));
275 }
276 }
277
278 void ConnectionManager::ProcessViewHierarchyChanged(
279 const ServerView* view,
280 const ServerView* new_parent,
281 const ServerView* old_parent) {
282 for (auto& pair : connection_map_) {
283 pair.second->service()->ProcessViewHierarchyChanged(
284 view, new_parent, old_parent, IsChangeSource(pair.first));
285 }
286 }
287
288 void ConnectionManager::ProcessViewReorder(
289 const ServerView* view,
290 const ServerView* relative_view,
291 const mojo::OrderDirection direction) {
292 for (auto& pair : connection_map_) {
293 pair.second->service()->ProcessViewReorder(view, relative_view, direction,
294 IsChangeSource(pair.first));
295 }
296 }
297
298 void ConnectionManager::ProcessViewDeleted(const ViewId& view) {
299 for (auto& pair : connection_map_) {
300 pair.second->service()->ProcessViewDeleted(view,
301 IsChangeSource(pair.first));
302 }
303 }
304
305 void ConnectionManager::ProcessViewportMetricsChanged(
306 const mojo::ViewportMetrics& old_metrics,
307 const mojo::ViewportMetrics& new_metrics) {
308 for (auto& pair : connection_map_) {
309 pair.second->service()->ProcessViewportMetricsChanged(
310 old_metrics, new_metrics, IsChangeSource(pair.first));
311 }
312 }
313
314 void ConnectionManager::PrepareForChange(ScopedChange* change) {
315 // Should only ever have one change in flight.
316 CHECK(!current_change_);
317 current_change_ = change;
318 }
319
320 void ConnectionManager::FinishChange() {
321 // PrepareForChange/FinishChange should be balanced.
322 CHECK(current_change_);
323 current_change_ = NULL;
324 }
325
326 void ConnectionManager::AddConnection(ClientConnection* connection) {
327 DCHECK_EQ(0u, connection_map_.count(connection->service()->id()));
328 connection_map_[connection->service()->id()] = connection;
329 }
330
331 scoped_ptr<cc::CompositorFrame>
332 ConnectionManager::UpdateViewTreeFromCompositorFrame(
333 const mojo::CompositorFramePtr& input) {
334 return ConvertToCompositorFrame(input, this);
335 }
336
337 surfaces::SurfacesState* ConnectionManager::GetSurfacesState() {
338 return surfaces_state_.get();
339 }
340
341 void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
342 if (!in_destructor_)
343 SchedulePaint(view, gfx::Rect(view->bounds().size()));
344 }
345
346 const ServerView* ConnectionManager::GetRootView(const ServerView* view) const {
347 const ViewTreeHostImpl* host = GetViewTreeHostByView(view);
348 return host ? host->root_view() : nullptr;
349 }
350
351 void ConnectionManager::OnViewDestroyed(ServerView* view) {
352 if (!in_destructor_)
353 ProcessViewDeleted(view->id());
354 }
355
356 void ConnectionManager::OnWillChangeViewHierarchy(ServerView* view,
357 ServerView* new_parent,
358 ServerView* old_parent) {
359 if (in_destructor_)
360 return;
361
362 ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
363 }
364
365 void ConnectionManager::OnViewHierarchyChanged(ServerView* view,
366 ServerView* new_parent,
367 ServerView* old_parent) {
368 if (in_destructor_)
369 return;
370
371 ProcessViewHierarchyChanged(view, new_parent, old_parent);
372
373 // TODO(beng): optimize.
374 if (old_parent)
375 SchedulePaint(old_parent, gfx::Rect(old_parent->bounds().size()));
376 if (new_parent)
377 SchedulePaint(new_parent, gfx::Rect(new_parent->bounds().size()));
378 }
379
380 void ConnectionManager::OnViewBoundsChanged(ServerView* view,
381 const gfx::Rect& old_bounds,
382 const gfx::Rect& new_bounds) {
383 if (in_destructor_)
384 return;
385
386 ProcessViewBoundsChanged(view, old_bounds, new_bounds);
387 if (!view->parent())
388 return;
389
390 // TODO(sky): optimize this.
391 SchedulePaint(view->parent(), old_bounds);
392 SchedulePaint(view->parent(), new_bounds);
393 }
394
395 void ConnectionManager::OnViewReordered(ServerView* view,
396 ServerView* relative,
397 mojo::OrderDirection direction) {
398 if (!in_destructor_)
399 SchedulePaint(view, gfx::Rect(view->bounds().size()));
400 }
401
402 void ConnectionManager::OnWillChangeViewVisibility(ServerView* view) {
403 if (in_destructor_)
404 return;
405
406 // Need to repaint if the view was drawn (which means it's in the process of
407 // hiding) or the view is transitioning to drawn.
408 if (view->parent() && (view->IsDrawn() ||
409 (!view->visible() && view->parent()->IsDrawn()))) {
410 SchedulePaint(view->parent(), view->bounds());
411 }
412
413 for (auto& pair : connection_map_) {
414 pair.second->service()->ProcessWillChangeViewVisibility(
415 view, IsChangeSource(pair.first));
416 }
417 }
418
419 void ConnectionManager::OnViewSharedPropertyChanged(
420 ServerView* view,
421 const std::string& name,
422 const std::vector<uint8_t>* new_data) {
423 for (auto& pair : connection_map_) {
424 pair.second->service()->ProcessViewPropertyChanged(
425 view, name, new_data, IsChangeSource(pair.first));
426 }
427 }
428
429 void ConnectionManager::OnViewTextInputStateChanged(
430 ServerView* view,
431 const ui::TextInputState& state) {
432 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
433 host->UpdateTextInputState(view, state);
434 }
435
436 bool ConnectionManager::ConvertSurfaceDrawQuad(
437 const mojo::QuadPtr& input,
438 const mojo::CompositorFrameMetadataPtr& metadata,
439 cc::SharedQuadState* sqs,
440 cc::RenderPass* render_pass) {
441 unsigned int id = static_cast<unsigned int>(
442 input->surface_quad_state->surface.To<cc::SurfaceId>().id);
443 // TODO(fsamuel): Security checks:
444 // 1. We need to make sure the embedder can only position views it's allowed
445 // to access.
446 // 2. We need to make sure that the embedder cannot place views in areas
447 // outside of its own bounds.
448 ServerView* view = GetView(ViewIdFromTransportId(id));
449 // If a CompositorFrame message arrives late, say during a navigation, then
450 // it may contain view IDs that no longer exist.
451 if (!view)
452 return false;
453 gfx::Rect bounds(input->visible_rect.To<gfx::Rect>());
454 gfx::Point p;
455 sqs->quad_to_target_transform.TransformPoint(&p);
456 bounds.set_origin(p);
457 // TODO(fsamuel): This seems like a crude way to set the size that probably
458 // doesn't work correctly in the general case. We need to get transforms
459 // working correctly in the general case.
460 bounds.set_size(gfx::ToRoundedSize(
461 gfx::ScaleSize(bounds.size(), metadata->device_scale_factor)));
462 view->SetBounds(bounds);
463 return true;
464 }
465
466 } // namespace view_manager
OLDNEW
« no previous file with comments | « components/view_manager/connection_manager.h ('k') | components/view_manager/connection_manager_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698