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

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

Issue 1531403003: Delete the ViewManager and WindowManager services. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-3
Patch Set: rebase Created 4 years, 10 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 "services/view_manager/connection_manager.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "mojo/converters/geometry/geometry_type_converters.h"
10 #include "mojo/converters/input_events/input_events_type_converters.h"
11 #include "mojo/public/interfaces/application/service_provider.mojom.h"
12 #include "services/view_manager/client_connection.h"
13 #include "services/view_manager/connection_manager_delegate.h"
14 #include "services/view_manager/display_manager.h"
15 #include "services/view_manager/server_view.h"
16 #include "services/view_manager/view_coordinate_conversions.h"
17 #include "services/view_manager/view_manager_service_impl.h"
18
19 using mojo::ConnectionSpecificId;
20
21 namespace view_manager {
22 namespace {
23
24 // Creates a copy of |view|. The copied view has |delegate| as its delegate.
25 // This does not recurse.
26 ServerView* CloneView(const ServerView* view, ServerViewDelegate* delegate) {
27 ServerView* clone = new ServerView(delegate, ClonedViewId());
28 clone->SetBounds(view->bounds());
29 clone->SetSurfaceId(view->surface_id());
30 clone->SetOpacity(view->opacity());
31 return clone;
32 }
33
34 // Creates copies of all the visible children of |parent|. Newly cloned views
35 // are added to |cloned_parent| and have |delegate| as their delegate. The
36 // stacking order of the cloned views is preseved.
37 void CloneViewTree(const ServerView* parent,
38 ServerView* cloned_parent,
39 ServerViewDelegate* delegate) {
40 DCHECK(parent->visible());
41 for (const ServerView* to_clone : parent->GetChildren()) {
42 if (to_clone->visible()) {
43 ServerView* cloned = CloneView(to_clone, delegate);
44 cloned_parent->Add(cloned);
45 CloneViewTree(to_clone, cloned, delegate);
46 }
47 }
48 }
49
50 // Recurses through all the children of |view| moving any cloned views to
51 // |new_parent| stacked above |stack_above|. |stack_above| is updated as views
52 // are moved.
53 void ReparentClonedViews(ServerView* new_parent,
54 ServerView** stack_above,
55 ServerView* view) {
56 if (view->id() == ClonedViewId()) {
57 const gfx::Rect new_bounds(ConvertRectBetweenViews(
58 view, new_parent, gfx::Rect(view->bounds().size())));
59 new_parent->Add(view);
60 new_parent->Reorder(view, *stack_above, mojo::OrderDirection::ABOVE);
61 view->SetBounds(new_bounds);
62 *stack_above = view;
63 return;
64 }
65
66 for (ServerView* child : view->GetChildren())
67 ReparentClonedViews(new_parent, stack_above, child);
68 }
69
70 // Deletes |view| and all its descendants.
71 void DeleteViewTree(ServerView* view) {
72 for (ServerView* child : view->GetChildren())
73 DeleteViewTree(child);
74
75 delete view;
76 }
77
78 // TODO(sky): nuke, proof of concept.
79 bool DecrementAnimatingViewsOpacity(ServerView* view) {
80 if (view->id() == ClonedViewId()) {
81 const float new_opacity = view->opacity() - .05f;
82 if (new_opacity <= 0)
83 DeleteViewTree(view);
84 else
85 view->SetOpacity(new_opacity);
86 return true;
87 }
88 bool ret_value = false;
89 for (ServerView* child : view->GetChildren()) {
90 if (DecrementAnimatingViewsOpacity(child))
91 ret_value = true;
92 }
93 return ret_value;
94 }
95
96 } // namespace
97
98 ConnectionManager::ScopedChange::ScopedChange(
99 ViewManagerServiceImpl* connection,
100 ConnectionManager* connection_manager,
101 bool is_delete_view)
102 : connection_manager_(connection_manager),
103 connection_id_(connection->id()),
104 is_delete_view_(is_delete_view) {
105 connection_manager_->PrepareForChange(this);
106 }
107
108 ConnectionManager::ScopedChange::~ScopedChange() {
109 connection_manager_->FinishChange();
110 }
111
112 ConnectionManager::ConnectionManager(ConnectionManagerDelegate* delegate,
113 scoped_ptr<DisplayManager> display_manager,
114 mojo::WindowManagerInternal* wm_internal)
115 : delegate_(delegate),
116 window_manager_client_connection_(nullptr),
117 next_connection_id_(1),
118 display_manager_(display_manager.Pass()),
119 root_(CreateServerView(RootViewId())),
120 wm_internal_(wm_internal),
121 current_change_(nullptr),
122 in_destructor_(false),
123 animation_runner_(base::TimeTicks::Now()) {
124 root_->SetBounds(gfx::Rect(800, 600));
125 root_->SetVisible(true);
126 display_manager_->Init(this);
127 }
128
129 ConnectionManager::~ConnectionManager() {
130 in_destructor_ = true;
131
132 STLDeleteValues(&connection_map_);
133 // All the connections should have been destroyed.
134 DCHECK(connection_map_.empty());
135 root_.reset();
136 }
137
138 ServerView* ConnectionManager::CreateServerView(const ViewId& id) {
139 ServerView* view = new ServerView(this, id);
140 view->AddObserver(this);
141 return view;
142 }
143
144 ConnectionSpecificId ConnectionManager::GetAndAdvanceNextConnectionId() {
145 const ConnectionSpecificId id = next_connection_id_++;
146 DCHECK_LT(id, next_connection_id_);
147 return id;
148 }
149
150 void ConnectionManager::OnConnectionError(ClientConnection* connection) {
151 if (connection == window_manager_client_connection_) {
152 window_manager_client_connection_ = nullptr;
153 delegate_->OnLostConnectionToWindowManager();
154 // Assume we've been destroyed.
155 return;
156 }
157
158 scoped_ptr<ClientConnection> connection_owner(connection);
159
160 connection_map_.erase(connection->service()->id());
161
162 // Notify remaining connections so that they can cleanup.
163 for (auto& pair : connection_map_) {
164 pair.second->service()->OnWillDestroyViewManagerServiceImpl(
165 connection->service());
166 }
167 }
168
169 void ConnectionManager::EmbedAtView(
170 ConnectionSpecificId creator_id,
171 const std::string& url,
172 const ViewId& view_id,
173 mojo::InterfaceRequest<mojo::ServiceProvider> services,
174 mojo::ServiceProviderPtr exposed_services) {
175 std::string creator_url;
176 ConnectionMap::const_iterator it = connection_map_.find(creator_id);
177 if (it != connection_map_.end())
178 creator_url = it->second->service()->url();
179
180 mojo::ViewManagerServicePtr service_ptr;
181 ClientConnection* client_connection =
182 delegate_->CreateClientConnectionForEmbedAtView(
183 this, GetProxy(&service_ptr), creator_id, creator_url, url, view_id);
184 AddConnection(client_connection);
185 client_connection->service()->Init(client_connection->client(),
186 service_ptr.Pass(), services.Pass(),
187 exposed_services.Pass());
188 OnConnectionMessagedClient(client_connection->service()->id());
189 }
190
191 void ConnectionManager::EmbedAtView(mojo::ConnectionSpecificId creator_id,
192 const ViewId& view_id,
193 mojo::ViewManagerClientPtr client) {
194 std::string creator_url;
195 ConnectionMap::const_iterator it = connection_map_.find(creator_id);
196 if (it != connection_map_.end())
197 creator_url = it->second->service()->url();
198
199 mojo::ViewManagerServicePtr service_ptr;
200 ClientConnection* client_connection =
201 delegate_->CreateClientConnectionForEmbedAtView(
202 this, GetProxy(&service_ptr), creator_id, creator_url, view_id,
203 client.Pass());
204 AddConnection(client_connection);
205 client_connection->service()->Init(client_connection->client(),
206 service_ptr.Pass(), nullptr, nullptr);
207 OnConnectionMessagedClient(client_connection->service()->id());
208 }
209
210 ViewManagerServiceImpl* ConnectionManager::GetConnection(
211 ConnectionSpecificId connection_id) {
212 ConnectionMap::iterator i = connection_map_.find(connection_id);
213 return i == connection_map_.end() ? nullptr : i->second->service();
214 }
215
216 ServerView* ConnectionManager::GetView(const ViewId& id) {
217 if (id == root_->id())
218 return root_.get();
219 ViewManagerServiceImpl* service = GetConnection(id.connection_id);
220 return service ? service->GetView(id) : nullptr;
221 }
222
223 void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) {
224 if (current_change_)
225 current_change_->MarkConnectionAsMessaged(id);
226 }
227
228 bool ConnectionManager::DidConnectionMessageClient(
229 ConnectionSpecificId id) const {
230 return current_change_ && current_change_->DidMessageConnection(id);
231 }
232
233 const ViewManagerServiceImpl* ConnectionManager::GetConnectionWithRoot(
234 const ViewId& id) const {
235 for (auto& pair : connection_map_) {
236 if (pair.second->service()->IsRoot(id))
237 return pair.second->service();
238 }
239 return nullptr;
240 }
241
242 void ConnectionManager::SetWindowManagerClientConnection(
243 scoped_ptr<ClientConnection> connection) {
244 CHECK(!window_manager_client_connection_);
245 window_manager_client_connection_ = connection.release();
246 AddConnection(window_manager_client_connection_);
247 window_manager_client_connection_->service()->Init(
248 window_manager_client_connection_->client(), nullptr, nullptr, nullptr);
249 }
250
251 mojo::ViewManagerClient*
252 ConnectionManager::GetWindowManagerViewManagerClient() {
253 CHECK(window_manager_client_connection_);
254 return window_manager_client_connection_->client();
255 }
256
257 bool ConnectionManager::CloneAndAnimate(const ViewId& view_id) {
258 ServerView* view = GetView(view_id);
259 if (!view || !view->IsDrawn(root_.get()) || view == root_.get())
260 return false;
261 if (!animation_timer_.IsRunning()) {
262 animation_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(100),
263 this, &ConnectionManager::DoAnimation);
264 }
265 ServerView* clone = CloneView(view, this);
266 CloneViewTree(view, clone, this);
267 view->parent()->Add(clone);
268 view->parent()->Reorder(clone, view, mojo::OrderDirection::ABOVE);
269 return true;
270 }
271
272 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
273 const gfx::Rect& old_bounds,
274 const gfx::Rect& new_bounds) {
275 for (auto& pair : connection_map_) {
276 pair.second->service()->ProcessViewBoundsChanged(
277 view, old_bounds, new_bounds, IsChangeSource(pair.first));
278 }
279 }
280
281 void ConnectionManager::ProcessViewportMetricsChanged(
282 const mojo::ViewportMetrics& old_metrics,
283 const mojo::ViewportMetrics& new_metrics) {
284 for (auto& pair : connection_map_) {
285 pair.second->service()->ProcessViewportMetricsChanged(
286 old_metrics, new_metrics, IsChangeSource(pair.first));
287 }
288 }
289
290 void ConnectionManager::ProcessWillChangeViewHierarchy(
291 const ServerView* view,
292 const ServerView* new_parent,
293 const ServerView* old_parent) {
294 for (auto& pair : connection_map_) {
295 pair.second->service()->ProcessWillChangeViewHierarchy(
296 view, new_parent, old_parent, IsChangeSource(pair.first));
297 }
298 }
299
300 void ConnectionManager::ProcessViewHierarchyChanged(
301 const ServerView* view,
302 const ServerView* new_parent,
303 const ServerView* old_parent) {
304 for (auto& pair : connection_map_) {
305 pair.second->service()->ProcessViewHierarchyChanged(
306 view, new_parent, old_parent, IsChangeSource(pair.first));
307 }
308 }
309
310 void ConnectionManager::ProcessViewReorder(
311 const ServerView* view,
312 const ServerView* relative_view,
313 const mojo::OrderDirection direction) {
314 for (auto& pair : connection_map_) {
315 pair.second->service()->ProcessViewReorder(view, relative_view, direction,
316 IsChangeSource(pair.first));
317 }
318 }
319
320 void ConnectionManager::ProcessViewDeleted(const ViewId& view) {
321 for (auto& pair : connection_map_) {
322 pair.second->service()->ProcessViewDeleted(view,
323 IsChangeSource(pair.first));
324 }
325 }
326
327 void ConnectionManager::PrepareForChange(ScopedChange* change) {
328 // Should only ever have one change in flight.
329 CHECK(!current_change_);
330 current_change_ = change;
331 }
332
333 void ConnectionManager::FinishChange() {
334 // PrepareForChange/FinishChange should be balanced.
335 CHECK(current_change_);
336 current_change_ = NULL;
337 }
338
339 void ConnectionManager::DoAnimation() {
340 if (!DecrementAnimatingViewsOpacity(root()))
341 animation_timer_.Stop();
342 }
343
344 void ConnectionManager::AddConnection(ClientConnection* connection) {
345 DCHECK_EQ(0u, connection_map_.count(connection->service()->id()));
346 connection_map_[connection->service()->id()] = connection;
347 }
348
349 void ConnectionManager::PrepareToDestroyView(ServerView* view) {
350 if (!in_destructor_ && root_->Contains(view) && view != root_.get() &&
351 view->id() != ClonedViewId()) {
352 // We're about to destroy a view. Any cloned views need to be reparented
353 // else the animation would no longer be visible. By moving to a visible
354 // view, view->parent(), we ensure the animation is still visible.
355 ServerView* parent_above = view;
356 ReparentClonedViews(view->parent(), &parent_above, view);
357 }
358
359 animation_runner_.CancelAnimationForView(view);
360 }
361
362 void ConnectionManager::PrepareToChangeViewHierarchy(ServerView* view,
363 ServerView* new_parent,
364 ServerView* old_parent) {
365 if (view->id() == ClonedViewId() || in_destructor_)
366 return;
367
368 if (root_->Contains(view) && view != root_.get()) {
369 // We're about to reparent a view. Any cloned views need to be reparented
370 // else the animation may be effected in unusual ways. For example, the view
371 // could move to a new location such that the animation is entirely clipped.
372 // By moving to view->parent() we ensure the animation is still visible.
373 ServerView* parent_above = view;
374 ReparentClonedViews(view->parent(), &parent_above, view);
375 }
376
377 animation_runner_.CancelAnimationForView(view);
378 }
379
380 void ConnectionManager::PrepareToChangeViewVisibility(ServerView* view) {
381 if (in_destructor_)
382 return;
383
384 if (view != root_.get() && view->id() != ClonedViewId() &&
385 root_->Contains(view) && view->IsDrawn(root_.get())) {
386 // We're about to hide |view|, this would implicitly make any cloned views
387 // hide too. Reparent so that animations are still visible.
388 ServerView* parent_above = view;
389 ReparentClonedViews(view->parent(), &parent_above, view);
390 }
391
392 const bool is_parent_drawn =
393 view->parent() && view->parent()->IsDrawn(root_.get());
394 if (!is_parent_drawn || !view->visible())
395 animation_runner_.CancelAnimationForView(view);
396 }
397
398 void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
399 if (!in_destructor_)
400 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
401 }
402
403 void ConnectionManager::OnViewDestroyed(ServerView* view) {
404 if (!in_destructor_)
405 ProcessViewDeleted(view->id());
406 }
407
408 void ConnectionManager::OnWillChangeViewHierarchy(ServerView* view,
409 ServerView* new_parent,
410 ServerView* old_parent) {
411 if (view->id() == ClonedViewId() || in_destructor_)
412 return;
413
414 ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
415 }
416
417 void ConnectionManager::OnViewHierarchyChanged(ServerView* view,
418 ServerView* new_parent,
419 ServerView* old_parent) {
420 if (in_destructor_)
421 return;
422
423 ProcessViewHierarchyChanged(view, new_parent, old_parent);
424
425 // TODO(beng): optimize.
426 if (old_parent) {
427 display_manager_->SchedulePaint(old_parent,
428 gfx::Rect(old_parent->bounds().size()));
429 }
430 if (new_parent) {
431 display_manager_->SchedulePaint(new_parent,
432 gfx::Rect(new_parent->bounds().size()));
433 }
434 }
435
436 void ConnectionManager::OnViewBoundsChanged(ServerView* view,
437 const gfx::Rect& old_bounds,
438 const gfx::Rect& new_bounds) {
439 if (in_destructor_)
440 return;
441
442 ProcessViewBoundsChanged(view, old_bounds, new_bounds);
443 if (!view->parent())
444 return;
445
446 // TODO(sky): optimize this.
447 display_manager_->SchedulePaint(view->parent(), old_bounds);
448 display_manager_->SchedulePaint(view->parent(), new_bounds);
449 }
450
451 void ConnectionManager::OnViewReordered(ServerView* view,
452 ServerView* relative,
453 mojo::OrderDirection direction) {
454 if (!in_destructor_)
455 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
456 }
457
458 void ConnectionManager::OnWillChangeViewVisibility(ServerView* view) {
459 if (in_destructor_)
460 return;
461
462 // Need to repaint if the view was drawn (which means it's in the process of
463 // hiding) or the view is transitioning to drawn.
464 if (view->IsDrawn(root_.get()) || (!view->visible() && view->parent() &&
465 view->parent()->IsDrawn(root_.get()))) {
466 display_manager_->SchedulePaint(view->parent(), view->bounds());
467 }
468
469 for (auto& pair : connection_map_) {
470 pair.second->service()->ProcessWillChangeViewVisibility(
471 view, IsChangeSource(pair.first));
472 }
473 }
474
475 void ConnectionManager::OnViewSharedPropertyChanged(
476 ServerView* view,
477 const std::string& name,
478 const std::vector<uint8_t>* new_data) {
479 for (auto& pair : connection_map_) {
480 pair.second->service()->ProcessViewPropertyChanged(
481 view, name, new_data, IsChangeSource(pair.first));
482 }
483 }
484
485 void ConnectionManager::DispatchInputEventToView(mojo::Id transport_view_id,
486 mojo::EventPtr event) {
487 const ViewId view_id(ViewIdFromTransportId(transport_view_id));
488
489 ViewManagerServiceImpl* connection = GetConnectionWithRoot(view_id);
490 if (!connection)
491 connection = GetConnection(view_id.connection_id);
492 if (connection) {
493 connection->client()->OnViewInputEvent(
494 transport_view_id, event.Pass(), base::Bind(&base::DoNothing));
495 }
496 }
497
498 void ConnectionManager::SetViewportSize(mojo::SizePtr size) {
499 gfx::Size new_size = size.To<gfx::Size>();
500 display_manager_->SetViewportSize(new_size);
501 }
502
503 void ConnectionManager::CloneAndAnimate(mojo::Id transport_view_id) {
504 CloneAndAnimate(ViewIdFromTransportId(transport_view_id));
505 }
506
507 } // namespace view_manager
OLDNEW
« no previous file with comments | « services/view_manager/connection_manager.h ('k') | services/view_manager/connection_manager_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698