Vectorize website settings icons in omnibox
[chromium-blink-merge.git] / components / view_manager / connection_manager.cc
blob9bbe5ae5c383833893506404efe14d327e3ef43c
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.
5 #include "components/view_manager/connection_manager.h"
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/focus_controller.h"
14 #include "components/view_manager/server_view.h"
15 #include "components/view_manager/view_coordinate_conversions.h"
16 #include "components/view_manager/view_tree_host_connection.h"
17 #include "components/view_manager/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"
23 using mojo::ConnectionSpecificId;
25 namespace view_manager {
26 namespace {
28 // Creates a copy of |view|. The copied view has |delegate| as its delegate.
29 // This does not recurse.
30 ServerView* CloneView(const ServerView* view, ServerViewDelegate* delegate) {
31 ServerView* clone = new ServerView(delegate, ClonedViewId());
32 clone->SetBounds(view->bounds());
33 clone->SetSurfaceId(view->surface_id());
34 clone->SetOpacity(view->opacity());
35 return clone;
38 // Creates copies of all the visible children of |parent|. Newly cloned views
39 // are added to |cloned_parent| and have |delegate| as their delegate. The
40 // stacking order of the cloned views is preseved.
41 void CloneViewTree(const ServerView* parent,
42 ServerView* cloned_parent,
43 ServerViewDelegate* delegate) {
44 DCHECK(parent->visible());
45 for (const ServerView* to_clone : parent->GetChildren()) {
46 if (to_clone->visible()) {
47 ServerView* cloned = CloneView(to_clone, delegate);
48 cloned_parent->Add(cloned);
49 CloneViewTree(to_clone, cloned, delegate);
54 // Recurses through all the children of |view| moving any cloned views to
55 // |new_parent| stacked above |stack_above|. |stack_above| is updated as views
56 // are moved.
57 void ReparentClonedViews(ServerView* new_parent,
58 ServerView** stack_above,
59 ServerView* view) {
60 if (view->id() == ClonedViewId()) {
61 const gfx::Rect new_bounds(ConvertRectBetweenViews(
62 view, new_parent, gfx::Rect(view->bounds().size())));
63 new_parent->Add(view);
64 new_parent->Reorder(view, *stack_above, mojo::ORDER_DIRECTION_ABOVE);
65 view->SetBounds(new_bounds);
66 *stack_above = view;
67 return;
70 for (ServerView* child : view->GetChildren())
71 ReparentClonedViews(new_parent, stack_above, child);
74 // Deletes |view| and all its descendants.
75 void DeleteViewTree(ServerView* view) {
76 for (ServerView* child : view->GetChildren())
77 DeleteViewTree(child);
79 delete view;
82 // TODO(sky): nuke, proof of concept.
83 bool DecrementAnimatingViewsOpacity(ServerView* view) {
84 if (view->id() == ClonedViewId()) {
85 const float new_opacity = view->opacity() - .05f;
86 if (new_opacity <= 0)
87 DeleteViewTree(view);
88 else
89 view->SetOpacity(new_opacity);
90 return true;
92 bool ret_value = false;
93 for (ServerView* child : view->GetChildren()) {
94 if (DecrementAnimatingViewsOpacity(child))
95 ret_value = true;
97 return ret_value;
100 } // namespace
102 ConnectionManager::ScopedChange::ScopedChange(
103 ViewTreeImpl* connection,
104 ConnectionManager* connection_manager,
105 bool is_delete_view)
106 : connection_manager_(connection_manager),
107 connection_id_(connection->id()),
108 is_delete_view_(is_delete_view) {
109 connection_manager_->PrepareForChange(this);
112 ConnectionManager::ScopedChange::~ScopedChange() {
113 connection_manager_->FinishChange();
116 ConnectionManager::ConnectionManager(
117 ConnectionManagerDelegate* delegate,
118 const scoped_refptr<surfaces::SurfacesState>& surfaces_state)
119 : delegate_(delegate),
120 surfaces_state_(surfaces_state),
121 next_connection_id_(1),
122 next_host_id_(0),
123 event_dispatcher_(this),
124 current_change_(nullptr),
125 in_destructor_(false),
126 animation_runner_(base::TimeTicks::Now()),
127 focus_controller_(new FocusController(this)) {
130 ConnectionManager::~ConnectionManager() {
131 in_destructor_ = true;
133 // Deleting views will attempt to advance focus. When we're being destroyed
134 // that is not necessary. Additionally |focus_controller_| needs to be
135 // destroyed before |host_|.
136 focus_controller_.reset();
138 // Copy the HostConnectionMap because it will be mutated as the connections
139 // are closed.
140 HostConnectionMap host_connection_map(host_connection_map_);
141 for (auto& pair : host_connection_map)
142 pair.second->CloseConnection();
144 STLDeleteValues(&connection_map_);
145 // All the connections should have been destroyed.
146 DCHECK(host_connection_map_.empty());
147 DCHECK(connection_map_.empty());
150 void ConnectionManager::AddHost(
151 ViewTreeHostConnection* host_connection) {
152 DCHECK_EQ(0u, host_connection_map_.count(host_connection->view_tree_host()));
153 host_connection_map_[host_connection->view_tree_host()] = host_connection;
156 ServerView* ConnectionManager::CreateServerView(const ViewId& id) {
157 ServerView* view = new ServerView(this, id);
158 view->AddObserver(this);
159 return view;
162 ConnectionSpecificId ConnectionManager::GetAndAdvanceNextConnectionId() {
163 const ConnectionSpecificId id = next_connection_id_++;
164 DCHECK_LT(id, next_connection_id_);
165 return id;
168 uint16_t ConnectionManager::GetAndAdvanceNextHostId() {
169 const uint16_t id = next_host_id_++;
170 DCHECK_LT(id, next_host_id_);
171 return id;
174 void ConnectionManager::OnConnectionError(ClientConnection* connection) {
175 // This will be null if the root has been destroyed.
176 const ViewId* view_id = connection->service()->root();
177 ServerView* view =
178 view_id ? GetView(*connection->service()->root()) : nullptr;
179 // If the ViewTree root is a viewport root, then we'll wait until
180 // the root connection goes away to cleanup.
181 if (view && (GetRootView(view) == view))
182 return;
184 scoped_ptr<ClientConnection> connection_owner(connection);
186 connection_map_.erase(connection->service()->id());
188 // TODO(sky): I may want to advance focus differently if focus is in
189 // |connection|.
191 // Notify remaining connections so that they can cleanup.
192 for (auto& pair : connection_map_) {
193 pair.second->service()->OnWillDestroyViewTreeImpl(
194 connection->service());
198 void ConnectionManager::OnHostConnectionClosed(
199 ViewTreeHostConnection* connection) {
200 auto it = host_connection_map_.find(connection->view_tree_host());
201 DCHECK(it != host_connection_map_.end());
203 // Clear focus if the focused view is in this viewport.
204 if (GetRootView(GetFocusedView()) == it->first->root_view())
205 SetFocusedView(nullptr);
207 // Get the ClientConnection by ViewTreeImpl ID.
208 ConnectionMap::iterator service_connection_it =
209 connection_map_.find(it->first->GetViewTree()->id());
210 DCHECK(service_connection_it != connection_map_.end());
212 // Tear down the associated ViewTree connection.
213 // TODO(fsamuel): I don't think this is quite right, we should tear down all
214 // connections within the root's viewport. We should probably employ an
215 // observer pattern to do this. Each ViewTreeImpl should track its
216 // parent's lifetime.
217 host_connection_map_.erase(it);
218 OnConnectionError(service_connection_it->second);
220 // If we have no more roots left, let the app know so it can terminate.
221 if (!host_connection_map_.size())
222 delegate_->OnNoMoreRootConnections();
225 void ConnectionManager::EmbedAtView(mojo::ConnectionSpecificId creator_id,
226 const ViewId& view_id,
227 mojo::URLRequestPtr request) {
228 mojo::ViewTreePtr service_ptr;
229 ClientConnection* client_connection =
230 delegate_->CreateClientConnectionForEmbedAtView(
231 this, GetProxy(&service_ptr), creator_id, request.Pass(), view_id);
232 AddConnection(client_connection);
233 client_connection->service()->Init(client_connection->client(),
234 service_ptr.Pass());
235 OnConnectionMessagedClient(client_connection->service()->id());
238 ViewTreeImpl* ConnectionManager::EmbedAtView(
239 mojo::ConnectionSpecificId creator_id,
240 const ViewId& view_id,
241 mojo::ViewTreeClientPtr client) {
242 mojo::ViewTreePtr service_ptr;
243 ClientConnection* client_connection =
244 delegate_->CreateClientConnectionForEmbedAtView(
245 this, GetProxy(&service_ptr), creator_id, view_id, client.Pass());
246 AddConnection(client_connection);
247 client_connection->service()->Init(client_connection->client(),
248 service_ptr.Pass());
249 OnConnectionMessagedClient(client_connection->service()->id());
251 return client_connection->service();
254 void ConnectionManager::OnAccelerator(ServerView* root,
255 uint32 id,
256 mojo::EventPtr event) {
257 for (auto& pair : host_connection_map_) {
258 if (root == pair.first->root_view()) {
259 pair.first->client()->OnAccelerator(id, event.Pass());
260 return;
265 ViewTreeImpl* ConnectionManager::GetConnection(
266 ConnectionSpecificId connection_id) {
267 ConnectionMap::iterator i = connection_map_.find(connection_id);
268 return i == connection_map_.end() ? nullptr : i->second->service();
271 ServerView* ConnectionManager::GetView(const ViewId& id) {
272 for (auto& pair : host_connection_map_) {
273 if (pair.first->root_view()->id() == id)
274 return pair.first->root_view();
276 ViewTreeImpl* service = GetConnection(id.connection_id);
277 return service ? service->GetView(id) : nullptr;
280 void ConnectionManager::SetFocusedView(ServerView* view) {
281 if (!focus_controller_)
282 return;
283 ServerView* old_focused = GetFocusedView();
284 if (old_focused == view)
285 return;
286 focus_controller_->SetFocusedView(view);
287 OnFocusChanged(old_focused, view);
290 ServerView* ConnectionManager::GetFocusedView() {
291 if (!focus_controller_)
292 return nullptr;
293 return focus_controller_->GetFocusedView();
296 bool ConnectionManager::IsViewAttachedToRoot(const ServerView* view) const {
297 for (auto& pair : host_connection_map_) {
298 if (pair.first->IsViewAttachedToRoot(view))
299 return true;
301 return false;
304 void ConnectionManager::SchedulePaint(const ServerView* view,
305 const gfx::Rect& bounds) {
306 for (auto& pair : host_connection_map_) {
307 if (pair.first->SchedulePaintIfInViewport(view, bounds))
308 return;
312 void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) {
313 if (current_change_)
314 current_change_->MarkConnectionAsMessaged(id);
317 bool ConnectionManager::DidConnectionMessageClient(
318 ConnectionSpecificId id) const {
319 return current_change_ && current_change_->DidMessageConnection(id);
322 mojo::ViewportMetricsPtr ConnectionManager::GetViewportMetricsForView(
323 const ServerView* view) {
324 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
325 if (host)
326 return host->GetViewportMetrics().Clone();
328 if (!host_connection_map_.empty())
329 return host_connection_map_.begin()->first->GetViewportMetrics().Clone();
331 mojo::ViewportMetricsPtr metrics = mojo::ViewportMetrics::New();
332 metrics->size_in_pixels = mojo::Size::New();
333 return metrics.Pass();
336 const ViewTreeImpl* ConnectionManager::GetConnectionWithRoot(
337 const ViewId& id) const {
338 for (auto& pair : connection_map_) {
339 if (pair.second->service()->IsRoot(id))
340 return pair.second->service();
342 return nullptr;
345 ViewTreeImpl* ConnectionManager::GetEmbedRoot(ViewTreeImpl* service) {
346 while (service) {
347 const ViewId* root_id = service->root();
348 if (!root_id || root_id->connection_id == service->id())
349 return nullptr;
351 ViewTreeImpl* parent_service = GetConnection(root_id->connection_id);
352 service = parent_service;
353 if (service && service->is_embed_root())
354 return service;
356 return nullptr;
359 bool ConnectionManager::CloneAndAnimate(const ViewId& view_id) {
360 ServerView* view = GetView(view_id);
361 if (!view || !view->IsDrawn() || (view->GetRoot() == view))
362 return false;
363 if (!animation_timer_.IsRunning()) {
364 animation_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(100),
365 this, &ConnectionManager::DoAnimation);
367 ServerView* clone = CloneView(view, this);
368 CloneViewTree(view, clone, this);
369 view->parent()->Add(clone);
370 view->parent()->Reorder(clone, view, mojo::ORDER_DIRECTION_ABOVE);
371 return true;
374 void ConnectionManager::DispatchInputEventToView(const ServerView* view,
375 mojo::EventPtr event) {
376 // If the view is an embed root, forward to the embedded view, not the owner.
377 ViewTreeImpl* connection = GetConnectionWithRoot(view->id());
378 if (!connection)
379 connection = GetConnection(view->id().connection_id);
380 CHECK(connection);
381 connection->client()->OnViewInputEvent(ViewIdToTransportId(view->id()),
382 event.Pass(),
383 base::Bind(&base::DoNothing));
386 void ConnectionManager::OnEvent(ViewTreeHostImpl* host,
387 mojo::EventPtr event) {
388 event_dispatcher_.OnEvent(host->root_view(), event.Pass());
391 void ConnectionManager::AddAccelerator(ViewTreeHostImpl* host,
392 uint32_t id,
393 mojo::KeyboardCode keyboard_code,
394 mojo::EventFlags flags) {
395 event_dispatcher_.AddAccelerator(id, keyboard_code, flags);
398 void ConnectionManager::RemoveAccelerator(ViewTreeHostImpl* host, uint32_t id) {
399 event_dispatcher_.RemoveAccelerator(id);
402 void ConnectionManager::SetImeVisibility(ServerView* view, bool visible) {
403 // Do not need to show or hide IME for unfocused view.
404 if (focus_controller_->GetFocusedView() != view)
405 return;
407 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
408 host->SetImeVisibility(visible);
411 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
412 const gfx::Rect& old_bounds,
413 const gfx::Rect& new_bounds) {
414 for (auto& pair : connection_map_) {
415 pair.second->service()->ProcessViewBoundsChanged(
416 view, old_bounds, new_bounds, IsChangeSource(pair.first));
420 void ConnectionManager::ProcessWillChangeViewHierarchy(
421 const ServerView* view,
422 const ServerView* new_parent,
423 const ServerView* old_parent) {
424 for (auto& pair : connection_map_) {
425 pair.second->service()->ProcessWillChangeViewHierarchy(
426 view, new_parent, old_parent, IsChangeSource(pair.first));
430 void ConnectionManager::ProcessViewHierarchyChanged(
431 const ServerView* view,
432 const ServerView* new_parent,
433 const ServerView* old_parent) {
434 for (auto& pair : connection_map_) {
435 pair.second->service()->ProcessViewHierarchyChanged(
436 view, new_parent, old_parent, IsChangeSource(pair.first));
440 void ConnectionManager::ProcessViewReorder(
441 const ServerView* view,
442 const ServerView* relative_view,
443 const mojo::OrderDirection direction) {
444 for (auto& pair : connection_map_) {
445 pair.second->service()->ProcessViewReorder(view, relative_view, direction,
446 IsChangeSource(pair.first));
450 void ConnectionManager::ProcessViewDeleted(const ViewId& view) {
451 for (auto& pair : connection_map_) {
452 pair.second->service()->ProcessViewDeleted(view,
453 IsChangeSource(pair.first));
457 void ConnectionManager::ProcessViewportMetricsChanged(
458 const mojo::ViewportMetrics& old_metrics,
459 const mojo::ViewportMetrics& new_metrics) {
460 for (auto& pair : connection_map_) {
461 pair.second->service()->ProcessViewportMetricsChanged(
462 old_metrics, new_metrics, IsChangeSource(pair.first));
466 void ConnectionManager::PrepareForChange(ScopedChange* change) {
467 // Should only ever have one change in flight.
468 CHECK(!current_change_);
469 current_change_ = change;
472 void ConnectionManager::FinishChange() {
473 // PrepareForChange/FinishChange should be balanced.
474 CHECK(current_change_);
475 current_change_ = NULL;
478 void ConnectionManager::DoAnimation() {
479 // TODO(fsamuel): This is probably not right. We probably want a per-root
480 // animation.
481 bool animating = false;
482 for (auto& pair : host_connection_map_)
483 animating |= DecrementAnimatingViewsOpacity(pair.first->root_view());
484 if (!animating)
485 animation_timer_.Stop();
488 void ConnectionManager::AddConnection(ClientConnection* connection) {
489 DCHECK_EQ(0u, connection_map_.count(connection->service()->id()));
490 connection_map_[connection->service()->id()] = connection;
493 ViewTreeHostImpl* ConnectionManager::GetViewTreeHostByView(
494 const ServerView* view) const {
495 while (view && view->parent())
496 view = view->parent();
497 for (auto& pair : host_connection_map_) {
498 if (view == pair.first->root_view())
499 return pair.first;
501 return nullptr;
504 scoped_ptr<cc::CompositorFrame>
505 ConnectionManager::UpdateViewTreeFromCompositorFrame(
506 const mojo::CompositorFramePtr& input) {
507 return ConvertToCompositorFrame(input, this);
510 surfaces::SurfacesState* ConnectionManager::GetSurfacesState() {
511 return surfaces_state_.get();
514 void ConnectionManager::PrepareToDestroyView(ServerView* view) {
515 if (!in_destructor_ && IsViewAttachedToRoot(view) &&
516 view->id() != ClonedViewId()) {
517 // We're about to destroy a view. Any cloned views need to be reparented
518 // else the animation would no longer be visible. By moving to a visible
519 // view, view->parent(), we ensure the animation is still visible.
520 ServerView* parent_above = view;
521 ReparentClonedViews(view->parent(), &parent_above, view);
524 animation_runner_.CancelAnimationForView(view);
527 void ConnectionManager::PrepareToChangeViewHierarchy(ServerView* view,
528 ServerView* new_parent,
529 ServerView* old_parent) {
530 if (view->id() == ClonedViewId() || in_destructor_)
531 return;
533 if (IsViewAttachedToRoot(view)) {
534 // We're about to reparent a view. Any cloned views need to be reparented
535 // else the animation may be effected in unusual ways. For example, the view
536 // could move to a new location such that the animation is entirely clipped.
537 // By moving to view->parent() we ensure the animation is still visible.
538 ServerView* parent_above = view;
539 ReparentClonedViews(view->parent(), &parent_above, view);
542 animation_runner_.CancelAnimationForView(view);
545 void ConnectionManager::PrepareToChangeViewVisibility(ServerView* view) {
546 if (in_destructor_)
547 return;
549 if (IsViewAttachedToRoot(view) && view->id() != ClonedViewId() &&
550 view->IsDrawn()) {
551 // We're about to hide |view|, this would implicitly make any cloned views
552 // hide too. Reparent so that animations are still visible.
553 ServerView* parent_above = view;
554 ReparentClonedViews(view->parent(), &parent_above, view);
557 const bool is_parent_drawn = view->parent() && view->parent()->IsDrawn();
558 if (!is_parent_drawn || !view->visible())
559 animation_runner_.CancelAnimationForView(view);
562 void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
563 if (!in_destructor_)
564 SchedulePaint(view, gfx::Rect(view->bounds().size()));
567 const ServerView* ConnectionManager::GetRootView(const ServerView* view) const {
568 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
569 return host ? host->root_view() : nullptr;
572 void ConnectionManager::OnViewDestroyed(ServerView* view) {
573 if (!in_destructor_)
574 ProcessViewDeleted(view->id());
577 void ConnectionManager::OnWillChangeViewHierarchy(ServerView* view,
578 ServerView* new_parent,
579 ServerView* old_parent) {
580 if (view->id() == ClonedViewId() || in_destructor_)
581 return;
583 ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
586 void ConnectionManager::OnViewHierarchyChanged(ServerView* view,
587 ServerView* new_parent,
588 ServerView* old_parent) {
589 if (in_destructor_)
590 return;
592 ProcessViewHierarchyChanged(view, new_parent, old_parent);
594 // TODO(beng): optimize.
595 if (old_parent)
596 SchedulePaint(old_parent, gfx::Rect(old_parent->bounds().size()));
597 if (new_parent)
598 SchedulePaint(new_parent, gfx::Rect(new_parent->bounds().size()));
601 void ConnectionManager::OnViewBoundsChanged(ServerView* view,
602 const gfx::Rect& old_bounds,
603 const gfx::Rect& new_bounds) {
604 if (in_destructor_)
605 return;
607 ProcessViewBoundsChanged(view, old_bounds, new_bounds);
608 if (!view->parent())
609 return;
611 // TODO(sky): optimize this.
612 SchedulePaint(view->parent(), old_bounds);
613 SchedulePaint(view->parent(), new_bounds);
616 void ConnectionManager::OnViewReordered(ServerView* view,
617 ServerView* relative,
618 mojo::OrderDirection direction) {
619 if (!in_destructor_)
620 SchedulePaint(view, gfx::Rect(view->bounds().size()));
623 void ConnectionManager::OnWillChangeViewVisibility(ServerView* view) {
624 if (in_destructor_)
625 return;
627 // Need to repaint if the view was drawn (which means it's in the process of
628 // hiding) or the view is transitioning to drawn.
629 if (view->parent() && (view->IsDrawn() ||
630 (!view->visible() && view->parent()->IsDrawn()))) {
631 SchedulePaint(view->parent(), view->bounds());
634 for (auto& pair : connection_map_) {
635 pair.second->service()->ProcessWillChangeViewVisibility(
636 view, IsChangeSource(pair.first));
640 void ConnectionManager::OnViewSharedPropertyChanged(
641 ServerView* view,
642 const std::string& name,
643 const std::vector<uint8_t>* new_data) {
644 for (auto& pair : connection_map_) {
645 pair.second->service()->ProcessViewPropertyChanged(
646 view, name, new_data, IsChangeSource(pair.first));
650 void ConnectionManager::OnViewTextInputStateChanged(
651 ServerView* view,
652 const ui::TextInputState& state) {
653 // Do not need to update text input for unfocused views.
654 if (focus_controller_->GetFocusedView() != view)
655 return;
657 ViewTreeHostImpl* host = GetViewTreeHostByView(view);
658 host->UpdateTextInputState(state);
661 void ConnectionManager::CloneAndAnimate(mojo::Id transport_view_id) {
662 CloneAndAnimate(ViewIdFromTransportId(transport_view_id));
665 void ConnectionManager::OnFocusChanged(ServerView* old_focused_view,
666 ServerView* new_focused_view) {
667 // There are up to four connections that need to be notified:
668 // . the connection containing |old_focused_view|.
669 // . the connection with |old_focused_view| as its root.
670 // . the connection containing |new_focused_view|.
671 // . the connection with |new_focused_view| as its root.
672 // Some of these connections may be the same. The following takes care to
673 // notify each only once.
674 ViewTreeImpl* owning_connection_old = nullptr;
675 ViewTreeImpl* embedded_connection_old = nullptr;
677 if (old_focused_view) {
678 owning_connection_old = GetConnection(old_focused_view->id().connection_id);
679 if (owning_connection_old) {
680 owning_connection_old->ProcessFocusChanged(old_focused_view,
681 new_focused_view);
683 embedded_connection_old = GetConnectionWithRoot(old_focused_view->id());
684 if (embedded_connection_old) {
685 DCHECK_NE(owning_connection_old, embedded_connection_old);
686 embedded_connection_old->ProcessFocusChanged(old_focused_view,
687 new_focused_view);
690 ViewTreeImpl* owning_connection_new = nullptr;
691 ViewTreeImpl* embedded_connection_new = nullptr;
692 if (new_focused_view) {
693 owning_connection_new = GetConnection(new_focused_view->id().connection_id);
694 if (owning_connection_new &&
695 owning_connection_new != owning_connection_old &&
696 owning_connection_new != embedded_connection_old) {
697 owning_connection_new->ProcessFocusChanged(old_focused_view,
698 new_focused_view);
700 embedded_connection_new = GetConnectionWithRoot(new_focused_view->id());
701 if (embedded_connection_new &&
702 embedded_connection_new != owning_connection_old &&
703 embedded_connection_new != embedded_connection_old) {
704 DCHECK_NE(owning_connection_new, embedded_connection_new);
705 embedded_connection_new->ProcessFocusChanged(old_focused_view,
706 new_focused_view);
710 for (auto& pair : host_connection_map_) {
711 ViewTreeImpl* service = pair.first->GetViewTree();
712 if (service != owning_connection_old &&
713 service != embedded_connection_old &&
714 service != owning_connection_new &&
715 service != embedded_connection_new) {
716 service->ProcessFocusChanged(old_focused_view, new_focused_view);
720 ViewTreeHostImpl* old_host =
721 old_focused_view ? GetViewTreeHostByView(old_focused_view) : nullptr;
723 ViewTreeHostImpl* new_host =
724 new_focused_view ? GetViewTreeHostByView(new_focused_view) : nullptr;
726 if (new_host)
727 new_host->UpdateTextInputState(new_focused_view->text_input_state());
728 else if (old_host)
729 old_host->UpdateTextInputState(ui::TextInputState());
732 bool ConnectionManager::ConvertSurfaceDrawQuad(const mojo::QuadPtr& input,
733 cc::SharedQuadState* sqs,
734 cc::RenderPass* render_pass) {
735 unsigned int id = static_cast<unsigned int>(
736 input->surface_quad_state->surface.To<cc::SurfaceId>().id);
737 // TODO(fsamuel): Security check.
738 ServerView* view = GetView(ViewIdFromTransportId(id));
739 // If a CompositorFrame message arrives late, say during a navigation, then
740 // it may contain view IDs that no longer exist.
741 if (!view)
742 return false;
743 gfx::Rect bounds(input->visible_rect.To<gfx::Rect>());
744 gfx::Point p;
745 sqs->quad_to_target_transform.TransformPoint(&p);
746 bounds.set_origin(p);
747 view->SetBounds(bounds);
748 return true;
751 } // namespace view_manager