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/mus/view_tree_impl.h"
8 #include "base/stl_util.h"
9 #include "components/mus/connection_manager.h"
10 #include "components/mus/default_access_policy.h"
11 #include "components/mus/display_manager.h"
12 #include "components/mus/server_view.h"
13 #include "components/mus/view_tree_host_impl.h"
14 #include "components/mus/window_manager_access_policy.h"
15 #include "mojo/converters/geometry/geometry_type_converters.h"
16 #include "mojo/converters/ime/ime_type_converters.h"
17 #include "mojo/converters/input_events/input_events_type_converters.h"
18 #include "mojo/converters/surfaces/surfaces_type_converters.h"
19 #include "ui/platform_window/text_input_state.h"
23 using mojo::InterfaceRequest
;
24 using mojo::OrderDirection
;
26 using mojo::ServiceProvider
;
27 using mojo::ServiceProviderPtr
;
29 using mojo::ViewDataPtr
;
33 ViewTreeImpl::ViewTreeImpl(ConnectionManager
* connection_manager
,
34 ConnectionSpecificId creator_id
,
35 const ViewId
& root_id
,
36 uint32_t policy_bitmask
)
37 : connection_manager_(connection_manager
),
38 id_(connection_manager_
->GetAndAdvanceNextConnectionId()),
39 creator_id_(creator_id
),
41 is_embed_root_(false) {
42 ServerView
* view
= GetView(root_id
);
44 root_
.reset(new ViewId(root_id
));
45 if (view
->GetRoot() == view
) {
46 access_policy_
.reset(new WindowManagerAccessPolicy(id_
, this));
47 is_embed_root_
= true;
49 access_policy_
.reset(new DefaultAccessPolicy(id_
, this));
50 is_embed_root_
= (policy_bitmask
& ViewTree::ACCESS_POLICY_EMBED_ROOT
) != 0;
54 ViewTreeImpl::~ViewTreeImpl() {
58 void ViewTreeImpl::Init(mojo::ViewTreeClient
* client
, mojo::ViewTreePtr tree
) {
61 std::vector
<const ServerView
*> to_send
;
63 GetUnknownViewsFrom(GetView(*root_
), &to_send
);
65 // TODO(beng): verify that host can actually be nullptr here.
66 ViewTreeHostImpl
* host
= GetHost();
67 const ServerView
* focused_view
= host
? host
->GetFocusedView() : nullptr;
69 focused_view
= access_policy_
->GetViewForFocusChange(focused_view
);
70 const Id
focused_view_transport_id(
71 ViewIdToTransportId(focused_view
? focused_view
->id() : ViewId()));
73 client
->OnEmbed(id_
, ViewToViewData(to_send
.front()), tree
.Pass(),
74 focused_view_transport_id
,
75 is_embed_root_
? ViewTree::ACCESS_POLICY_EMBED_ROOT
76 : ViewTree::ACCESS_POLICY_DEFAULT
);
79 const ServerView
* ViewTreeImpl::GetView(const ViewId
& id
) const {
80 if (id_
== id
.connection_id
) {
81 ViewMap::const_iterator i
= view_map_
.find(id
.view_id
);
82 return i
== view_map_
.end() ? NULL
: i
->second
;
84 return connection_manager_
->GetView(id
);
87 bool ViewTreeImpl::IsRoot(const ViewId
& id
) const {
88 return root_
.get() && *root_
== id
;
91 ViewTreeHostImpl
* ViewTreeImpl::GetHost() {
93 ? connection_manager_
->GetViewTreeHostByView(GetView(*root_
))
97 void ViewTreeImpl::OnWillDestroyViewTreeImpl(ViewTreeImpl
* connection
) {
98 if (creator_id_
== connection
->id())
99 creator_id_
= kInvalidConnectionId
;
100 const ServerView
* connection_root
=
101 connection
->root_
? connection
->GetView(*connection
->root_
) : nullptr;
102 if (connection_root
&&
103 ((connection_root
->id().connection_id
== id_
&&
104 view_map_
.count(connection_root
->id().view_id
) > 0) ||
105 (is_embed_root_
&& IsViewKnown(connection_root
)))) {
106 client()->OnEmbeddedAppDisconnected(
107 ViewIdToTransportId(*connection
->root_
));
109 if (root_
.get() && root_
->connection_id
== connection
->id())
113 mojo::ErrorCode
ViewTreeImpl::CreateView(const ViewId
& view_id
) {
114 if (view_id
.connection_id
!= id_
)
115 return mojo::ERROR_CODE_ILLEGAL_ARGUMENT
;
116 if (view_map_
.find(view_id
.view_id
) != view_map_
.end())
117 return mojo::ERROR_CODE_VALUE_IN_USE
;
118 view_map_
[view_id
.view_id
] = connection_manager_
->CreateServerView(view_id
);
119 known_views_
.insert(ViewIdToTransportId(view_id
));
120 return mojo::ERROR_CODE_NONE
;
123 bool ViewTreeImpl::AddView(const ViewId
& parent_id
, const ViewId
& child_id
) {
124 ServerView
* parent
= GetView(parent_id
);
125 ServerView
* child
= GetView(child_id
);
126 if (parent
&& child
&& child
->parent() != parent
&&
127 !child
->Contains(parent
) && access_policy_
->CanAddView(parent
, child
)) {
128 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
135 std::vector
<const ServerView
*> ViewTreeImpl::GetViewTree(
136 const ViewId
& view_id
) const {
137 const ServerView
* view
= GetView(view_id
);
138 std::vector
<const ServerView
*> views
;
140 GetViewTreeImpl(view
, &views
);
144 bool ViewTreeImpl::SetViewVisibility(const ViewId
& view_id
, bool visible
) {
145 ServerView
* view
= GetView(view_id
);
146 if (!view
|| view
->visible() == visible
||
147 !access_policy_
->CanChangeViewVisibility(view
)) {
150 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
151 view
->SetVisible(visible
);
155 bool ViewTreeImpl::Embed(const ViewId
& view_id
,
156 mojo::ViewTreeClientPtr client
,
157 uint32_t policy_bitmask
,
158 ConnectionSpecificId
* connection_id
) {
159 *connection_id
= kInvalidConnectionId
;
160 if (!client
.get() || !CanEmbed(view_id
, policy_bitmask
))
162 PrepareForEmbed(view_id
);
163 ViewTreeImpl
* new_connection
= connection_manager_
->EmbedAtView(
164 id_
, view_id
, policy_bitmask
, client
.Pass());
166 *connection_id
= new_connection
->id();
170 void ViewTreeImpl::Embed(const ViewId
& view_id
, mojo::URLRequestPtr request
) {
171 if (!CanEmbed(view_id
, ViewTree::ACCESS_POLICY_DEFAULT
))
173 PrepareForEmbed(view_id
);
174 connection_manager_
->EmbedAtView(
175 id_
, view_id
, mojo::ViewTree::ACCESS_POLICY_DEFAULT
, request
.Pass());
178 void ViewTreeImpl::ProcessViewBoundsChanged(const ServerView
* view
,
179 const gfx::Rect
& old_bounds
,
180 const gfx::Rect
& new_bounds
,
181 bool originated_change
) {
182 if (originated_change
|| !IsViewKnown(view
))
184 client()->OnViewBoundsChanged(ViewIdToTransportId(view
->id()),
185 Rect::From(old_bounds
), Rect::From(new_bounds
));
188 void ViewTreeImpl::ProcessViewportMetricsChanged(
189 const mojo::ViewportMetrics
& old_metrics
,
190 const mojo::ViewportMetrics
& new_metrics
,
191 bool originated_change
) {
192 client()->OnViewViewportMetricsChanged(old_metrics
.Clone(),
193 new_metrics
.Clone());
196 void ViewTreeImpl::ProcessWillChangeViewHierarchy(const ServerView
* view
,
197 const ServerView
* new_parent
,
198 const ServerView
* old_parent
,
199 bool originated_change
) {
200 if (originated_change
)
203 const bool old_drawn
= view
->IsDrawn();
204 const bool new_drawn
= view
->visible() && new_parent
&& new_parent
->IsDrawn();
205 if (old_drawn
== new_drawn
)
208 NotifyDrawnStateChanged(view
, new_drawn
);
211 void ViewTreeImpl::ProcessViewPropertyChanged(
212 const ServerView
* view
,
213 const std::string
& name
,
214 const std::vector
<uint8_t>* new_data
,
215 bool originated_change
) {
216 if (originated_change
)
221 data
= Array
<uint8_t>::From(*new_data
);
223 client()->OnViewSharedPropertyChanged(ViewIdToTransportId(view
->id()),
224 String(name
), data
.Pass());
227 void ViewTreeImpl::ProcessViewHierarchyChanged(const ServerView
* view
,
228 const ServerView
* new_parent
,
229 const ServerView
* old_parent
,
230 bool originated_change
) {
231 if (originated_change
&& !IsViewKnown(view
) && new_parent
&&
232 IsViewKnown(new_parent
)) {
233 std::vector
<const ServerView
*> unused
;
234 GetUnknownViewsFrom(view
, &unused
);
236 if (originated_change
|| connection_manager_
->is_processing_delete_view() ||
237 connection_manager_
->DidConnectionMessageClient(id_
)) {
241 if (!access_policy_
->ShouldNotifyOnHierarchyChange(view
, &new_parent
,
245 // Inform the client of any new views and update the set of views we know
247 std::vector
<const ServerView
*> to_send
;
248 if (!IsViewKnown(view
))
249 GetUnknownViewsFrom(view
, &to_send
);
250 const ViewId
new_parent_id(new_parent
? new_parent
->id() : ViewId());
251 const ViewId
old_parent_id(old_parent
? old_parent
->id() : ViewId());
252 client()->OnViewHierarchyChanged(
253 ViewIdToTransportId(view
->id()), ViewIdToTransportId(new_parent_id
),
254 ViewIdToTransportId(old_parent_id
), ViewsToViewDatas(to_send
));
255 connection_manager_
->OnConnectionMessagedClient(id_
);
258 void ViewTreeImpl::ProcessViewReorder(const ServerView
* view
,
259 const ServerView
* relative_view
,
260 OrderDirection direction
,
261 bool originated_change
) {
262 if (originated_change
|| !IsViewKnown(view
) || !IsViewKnown(relative_view
))
265 client()->OnViewReordered(ViewIdToTransportId(view
->id()),
266 ViewIdToTransportId(relative_view
->id()),
270 void ViewTreeImpl::ProcessViewDeleted(const ViewId
& view
,
271 bool originated_change
) {
272 if (view
.connection_id
== id_
)
273 view_map_
.erase(view
.view_id
);
275 const bool in_known
= known_views_
.erase(ViewIdToTransportId(view
)) > 0;
280 if (originated_change
)
284 client()->OnViewDeleted(ViewIdToTransportId(view
));
285 connection_manager_
->OnConnectionMessagedClient(id_
);
289 void ViewTreeImpl::ProcessWillChangeViewVisibility(const ServerView
* view
,
290 bool originated_change
) {
291 if (originated_change
)
294 if (IsViewKnown(view
)) {
295 client()->OnViewVisibilityChanged(ViewIdToTransportId(view
->id()),
300 bool view_target_drawn_state
;
301 if (view
->visible()) {
302 // View is being hidden, won't be drawn.
303 view_target_drawn_state
= false;
305 // View is being shown. View will be drawn if its parent is drawn.
306 view_target_drawn_state
= view
->parent() && view
->parent()->IsDrawn();
309 NotifyDrawnStateChanged(view
, view_target_drawn_state
);
312 void ViewTreeImpl::ProcessFocusChanged(const ServerView
* old_focused_view
,
313 const ServerView
* new_focused_view
) {
314 const ServerView
* view
=
315 new_focused_view
? access_policy_
->GetViewForFocusChange(new_focused_view
)
317 client()->OnViewFocused(view
? ViewIdToTransportId(view
->id())
318 : ViewIdToTransportId(ViewId()));
321 bool ViewTreeImpl::IsViewKnown(const ServerView
* view
) const {
322 return known_views_
.count(ViewIdToTransportId(view
->id())) > 0;
325 bool ViewTreeImpl::CanReorderView(const ServerView
* view
,
326 const ServerView
* relative_view
,
327 OrderDirection direction
) const {
328 if (!view
|| !relative_view
)
331 if (!view
->parent() || view
->parent() != relative_view
->parent())
334 if (!access_policy_
->CanReorderView(view
, relative_view
, direction
))
337 std::vector
<const ServerView
*> children
= view
->parent()->GetChildren();
338 const size_t child_i
=
339 std::find(children
.begin(), children
.end(), view
) - children
.begin();
340 const size_t target_i
=
341 std::find(children
.begin(), children
.end(), relative_view
) -
343 if ((direction
== mojo::ORDER_DIRECTION_ABOVE
&& child_i
== target_i
+ 1) ||
344 (direction
== mojo::ORDER_DIRECTION_BELOW
&& child_i
+ 1 == target_i
)) {
351 bool ViewTreeImpl::DeleteViewImpl(ViewTreeImpl
* source
, ServerView
* view
) {
353 DCHECK_EQ(view
->id().connection_id
, id_
);
354 ConnectionManager::ScopedChange
change(source
, connection_manager_
, true);
359 void ViewTreeImpl::GetUnknownViewsFrom(const ServerView
* view
,
360 std::vector
<const ServerView
*>* views
) {
361 if (IsViewKnown(view
) || !access_policy_
->CanGetViewTree(view
))
363 views
->push_back(view
);
364 known_views_
.insert(ViewIdToTransportId(view
->id()));
365 if (!access_policy_
->CanDescendIntoViewForViewTree(view
))
367 std::vector
<const ServerView
*> children(view
->GetChildren());
368 for (size_t i
= 0; i
< children
.size(); ++i
)
369 GetUnknownViewsFrom(children
[i
], views
);
372 void ViewTreeImpl::RemoveFromKnown(const ServerView
* view
,
373 std::vector
<ServerView
*>* local_views
) {
374 if (view
->id().connection_id
== id_
) {
376 local_views
->push_back(GetView(view
->id()));
379 known_views_
.erase(ViewIdToTransportId(view
->id()));
380 std::vector
<const ServerView
*> children
= view
->GetChildren();
381 for (size_t i
= 0; i
< children
.size(); ++i
)
382 RemoveFromKnown(children
[i
], local_views
);
385 void ViewTreeImpl::RemoveRoot() {
387 const ViewId
root_id(*root_
);
389 // No need to do anything if we created the view.
390 if (root_id
.connection_id
== id_
)
393 client()->OnUnembed();
394 client()->OnViewDeleted(ViewIdToTransportId(root_id
));
395 connection_manager_
->OnConnectionMessagedClient(id_
);
397 // This connection no longer knows about the view. Unparent any views that
398 // were parented to views in the root.
399 std::vector
<ServerView
*> local_views
;
400 RemoveFromKnown(GetView(root_id
), &local_views
);
401 for (size_t i
= 0; i
< local_views
.size(); ++i
)
402 local_views
[i
]->parent()->Remove(local_views
[i
]);
405 Array
<ViewDataPtr
> ViewTreeImpl::ViewsToViewDatas(
406 const std::vector
<const ServerView
*>& views
) {
407 Array
<ViewDataPtr
> array(views
.size());
408 for (size_t i
= 0; i
< views
.size(); ++i
)
409 array
[i
] = ViewToViewData(views
[i
]).Pass();
413 ViewDataPtr
ViewTreeImpl::ViewToViewData(const ServerView
* view
) {
414 DCHECK(IsViewKnown(view
));
415 const ServerView
* parent
= view
->parent();
416 // If the parent isn't known, it means the parent is not visible to us (not
417 // in roots), and should not be sent over.
418 if (parent
&& !IsViewKnown(parent
))
420 ViewDataPtr
view_data(mojo::ViewData::New());
421 view_data
->parent_id
= ViewIdToTransportId(parent
? parent
->id() : ViewId());
422 view_data
->view_id
= ViewIdToTransportId(view
->id());
423 view_data
->bounds
= Rect::From(view
->bounds());
424 view_data
->properties
=
425 mojo::Map
<String
, Array
<uint8_t>>::From(view
->properties());
426 view_data
->visible
= view
->visible();
427 view_data
->drawn
= view
->IsDrawn();
428 view_data
->viewport_metrics
=
429 connection_manager_
->GetViewportMetricsForView(view
);
430 return view_data
.Pass();
433 void ViewTreeImpl::GetViewTreeImpl(
434 const ServerView
* view
,
435 std::vector
<const ServerView
*>* views
) const {
438 if (!access_policy_
->CanGetViewTree(view
))
441 views
->push_back(view
);
443 if (!access_policy_
->CanDescendIntoViewForViewTree(view
))
446 std::vector
<const ServerView
*> children(view
->GetChildren());
447 for (size_t i
= 0; i
< children
.size(); ++i
)
448 GetViewTreeImpl(children
[i
], views
);
451 void ViewTreeImpl::NotifyDrawnStateChanged(const ServerView
* view
,
452 bool new_drawn_value
) {
453 // Even though we don't know about view, it may be an ancestor of our root, in
454 // which case the change may effect our roots drawn state.
458 const ServerView
* root
= GetView(*root_
);
460 if (view
->Contains(root
) && (new_drawn_value
!= root
->IsDrawn())) {
461 client()->OnViewDrawnStateChanged(ViewIdToTransportId(root
->id()),
466 void ViewTreeImpl::DestroyViews() {
467 if (!view_map_
.empty()) {
468 ConnectionManager::ScopedChange
change(this, connection_manager_
, true);
469 // If we get here from the destructor we're not going to get
470 // ProcessViewDeleted(). Copy the map and delete from the copy so that we
471 // don't have to worry about whether |view_map_| changes or not.
472 ViewMap view_map_copy
;
473 view_map_
.swap(view_map_copy
);
474 STLDeleteValues(&view_map_copy
);
478 bool ViewTreeImpl::CanEmbed(const ViewId
& view_id
,
479 uint32_t policy_bitmask
) const {
480 const ServerView
* view
= GetView(view_id
);
481 return view
&& access_policy_
->CanEmbed(view
, policy_bitmask
);
484 void ViewTreeImpl::PrepareForEmbed(const ViewId
& view_id
) {
485 const ServerView
* view
= GetView(view_id
);
488 // Only allow a node to be the root for one connection.
489 ViewTreeImpl
* existing_owner
=
490 connection_manager_
->GetConnectionWithRoot(view_id
);
492 ConnectionManager::ScopedChange
change(this, connection_manager_
, true);
493 RemoveChildrenAsPartOfEmbed(view_id
);
494 if (existing_owner
) {
495 // Never message the originating connection.
496 connection_manager_
->OnConnectionMessagedClient(id_
);
497 existing_owner
->RemoveRoot();
501 void ViewTreeImpl::RemoveChildrenAsPartOfEmbed(const ViewId
& view_id
) {
502 ServerView
* view
= GetView(view_id
);
504 CHECK(view
->id().connection_id
== view_id
.connection_id
);
505 std::vector
<ServerView
*> children
= view
->GetChildren();
506 for (size_t i
= 0; i
< children
.size(); ++i
)
507 view
->Remove(children
[i
]);
510 void ViewTreeImpl::CreateView(Id transport_view_id
,
511 const Callback
<void(mojo::ErrorCode
)>& callback
) {
512 callback
.Run(CreateView(ViewIdFromTransportId(transport_view_id
)));
515 void ViewTreeImpl::DeleteView(Id transport_view_id
,
516 const Callback
<void(bool)>& callback
) {
517 ServerView
* view
= GetView(ViewIdFromTransportId(transport_view_id
));
518 bool success
= false;
519 if (view
&& access_policy_
->CanDeleteView(view
)) {
520 ViewTreeImpl
* connection
=
521 connection_manager_
->GetConnection(view
->id().connection_id
);
522 success
= connection
&& connection
->DeleteViewImpl(this, view
);
524 callback
.Run(success
);
527 void ViewTreeImpl::AddView(Id parent_id
,
529 const Callback
<void(bool)>& callback
) {
530 callback
.Run(AddView(ViewIdFromTransportId(parent_id
),
531 ViewIdFromTransportId(child_id
)));
534 void ViewTreeImpl::RemoveViewFromParent(Id view_id
,
535 const Callback
<void(bool)>& callback
) {
536 bool success
= false;
537 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
538 if (view
&& view
->parent() && access_policy_
->CanRemoveViewFromParent(view
)) {
540 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
541 view
->parent()->Remove(view
);
543 callback
.Run(success
);
546 void ViewTreeImpl::ReorderView(Id view_id
,
548 OrderDirection direction
,
549 const Callback
<void(bool)>& callback
) {
550 bool success
= false;
551 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
552 ServerView
* relative_view
= GetView(ViewIdFromTransportId(relative_view_id
));
553 if (CanReorderView(view
, relative_view
, direction
)) {
555 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
556 view
->parent()->Reorder(view
, relative_view
, direction
);
557 connection_manager_
->ProcessViewReorder(view
, relative_view
, direction
);
559 callback
.Run(success
);
562 void ViewTreeImpl::GetViewTree(
564 const Callback
<void(Array
<ViewDataPtr
>)>& callback
) {
565 std::vector
<const ServerView
*> views(
566 GetViewTree(ViewIdFromTransportId(view_id
)));
567 callback
.Run(ViewsToViewDatas(views
));
570 void ViewTreeImpl::SetViewBounds(Id view_id
,
571 mojo::RectPtr bounds
,
572 const Callback
<void(bool)>& callback
) {
573 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
574 const bool success
= view
&& access_policy_
->CanSetViewBounds(view
);
576 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
577 view
->SetBounds(bounds
.To
<gfx::Rect
>());
579 callback
.Run(success
);
582 void ViewTreeImpl::SetViewVisibility(Id transport_view_id
,
584 const Callback
<void(bool)>& callback
) {
586 SetViewVisibility(ViewIdFromTransportId(transport_view_id
), visible
));
589 void ViewTreeImpl::SetViewProperty(uint32_t view_id
,
590 const mojo::String
& name
,
591 mojo::Array
<uint8_t> value
,
592 const mojo::Callback
<void(bool)>& callback
) {
593 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
594 const bool success
= view
&& access_policy_
->CanSetViewProperties(view
);
596 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
598 if (value
.is_null()) {
599 view
->SetProperty(name
, nullptr);
601 std::vector
<uint8_t> data
= value
.To
<std::vector
<uint8_t>>();
602 view
->SetProperty(name
, &data
);
605 callback
.Run(success
);
608 void ViewTreeImpl::RequestSurface(Id view_id
,
609 mojo::InterfaceRequest
<mojo::Surface
> surface
,
610 mojo::SurfaceClientPtr client
) {
611 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
612 const bool success
= view
&& access_policy_
->CanSetViewSurfaceId(view
);
615 view
->Bind(surface
.Pass(), client
.Pass());
618 void ViewTreeImpl::SetViewTextInputState(uint32_t view_id
,
619 mojo::TextInputStatePtr state
) {
620 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
621 bool success
= view
&& access_policy_
->CanSetViewTextInputState(view
);
623 view
->SetTextInputState(state
.To
<ui::TextInputState
>());
626 void ViewTreeImpl::SetImeVisibility(Id transport_view_id
,
628 mojo::TextInputStatePtr state
) {
629 ServerView
* view
= GetView(ViewIdFromTransportId(transport_view_id
));
630 bool success
= view
&& access_policy_
->CanSetViewTextInputState(view
);
632 if (!state
.is_null())
633 view
->SetTextInputState(state
.To
<ui::TextInputState
>());
635 ViewTreeHostImpl
* host
= GetHost();
637 host
->SetImeVisibility(view
, visible
);
641 void ViewTreeImpl::Embed(Id transport_view_id
,
642 mojo::ViewTreeClientPtr client
,
643 uint32_t policy_bitmask
,
644 const EmbedCallback
& callback
) {
645 ConnectionSpecificId connection_id
= kInvalidConnectionId
;
646 const bool result
= Embed(ViewIdFromTransportId(transport_view_id
),
647 client
.Pass(), policy_bitmask
, &connection_id
);
648 callback
.Run(result
, connection_id
);
651 void ViewTreeImpl::SetFocus(uint32_t view_id
) {
652 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
653 // TODO(beng): consider shifting non-policy drawn check logic to VTH's
655 if (view
&& view
->IsDrawn() && access_policy_
->CanSetFocus(view
)) {
656 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
657 ViewTreeHostImpl
* host
= GetHost();
659 host
->SetFocusedView(view
);
663 bool ViewTreeImpl::IsRootForAccessPolicy(const ViewId
& id
) const {
667 bool ViewTreeImpl::IsViewKnownForAccessPolicy(const ServerView
* view
) const {
668 return IsViewKnown(view
);
671 bool ViewTreeImpl::IsViewRootOfAnotherConnectionForAccessPolicy(
672 const ServerView
* view
) const {
673 ViewTreeImpl
* connection
=
674 connection_manager_
->GetConnectionWithRoot(view
->id());
675 return connection
&& connection
!= this;
678 bool ViewTreeImpl::IsDescendantOfEmbedRoot(const ServerView
* view
) {
679 return is_embed_root_
&& root_
&& GetView(*root_
)->Contains(view
);