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

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

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

Powered by Google App Engine
This is Rietveld 408576698