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/view_manager_service_impl.h"
8 #include "base/stl_util.h"
9 #include "components/view_manager/connection_manager.h"
10 #include "components/view_manager/default_access_policy.h"
11 #include "components/view_manager/display_manager.h"
12 #include "components/view_manager/server_view.h"
13 #include "components/view_manager/window_manager_access_policy.h"
14 #include "mojo/converters/geometry/geometry_type_converters.h"
15 #include "mojo/converters/input_events/input_events_type_converters.h"
16 #include "mojo/converters/surfaces/surfaces_type_converters.h"
21 using mojo::InterfaceRequest
;
22 using mojo::OrderDirection
;
24 using mojo::ServiceProvider
;
25 using mojo::ServiceProviderPtr
;
27 using mojo::ViewDataPtr
;
29 namespace view_manager
{
31 // Contains information needed to complete an Embed(). See description of
32 // |pending_embeds_| for more details.
33 struct ViewManagerServiceImpl::PendingEmbed
34 : public base::RefCounted
<PendingEmbed
> {
35 PendingEmbed() : embed_root(nullptr) {}
37 ViewManagerServiceImpl
* embed_root
;
39 mojo::Callback
<void(bool)> callback
;
42 friend class base::RefCounted
<PendingEmbed
>;
47 ViewManagerServiceImpl::ViewManagerServiceImpl(
48 ConnectionManager
* connection_manager
,
49 mojo::ConnectionSpecificId creator_id
,
50 const ViewId
& root_id
)
51 : connection_manager_(connection_manager
),
52 id_(connection_manager_
->GetAndAdvanceNextConnectionId()),
53 creator_id_(creator_id
),
55 is_embed_root_(false) {
56 ServerView
* view
= GetView(root_id
);
58 root_
.reset(new ViewId(root_id
));
59 if (view
->GetRoot() == view
)
60 access_policy_
.reset(new WindowManagerAccessPolicy(id_
, this));
62 access_policy_
.reset(new DefaultAccessPolicy(id_
, this));
65 ViewManagerServiceImpl::~ViewManagerServiceImpl() {
69 void ViewManagerServiceImpl::Init(mojo::ViewManagerClient
* client
,
70 mojo::ViewManagerServicePtr service_ptr
) {
73 std::vector
<const ServerView
*> to_send
;
75 GetUnknownViewsFrom(GetView(*root_
), &to_send
);
77 const ServerView
* focused_view
= connection_manager_
->GetFocusedView();
79 focused_view
= access_policy_
->GetViewForFocusChange(focused_view
);
80 const mojo::Id
focused_view_transport_id(
81 ViewIdToTransportId(focused_view
? focused_view
->id() : ViewId()));
83 client
->OnEmbed(id_
, ViewToViewData(to_send
.front()), service_ptr
.Pass(),
84 focused_view_transport_id
);
87 const ServerView
* ViewManagerServiceImpl::GetView(const ViewId
& id
) const {
88 if (id_
== id
.connection_id
) {
89 ViewMap::const_iterator i
= view_map_
.find(id
.view_id
);
90 return i
== view_map_
.end() ? NULL
: i
->second
;
92 return connection_manager_
->GetView(id
);
95 bool ViewManagerServiceImpl::IsRoot(const ViewId
& id
) const {
96 return root_
.get() && *root_
== id
;
99 void ViewManagerServiceImpl::OnWillDestroyViewManagerServiceImpl(
100 ViewManagerServiceImpl
* connection
) {
101 InvalidatePendingEmbedForConnection(connection
);
102 if (creator_id_
== connection
->id())
103 creator_id_
= kInvalidConnectionId
;
104 if (connection
->root_
&& connection
->root_
->connection_id
== id_
&&
105 view_map_
.count(connection
->root_
->view_id
) > 0) {
106 client()->OnEmbeddedAppDisconnected(
107 ViewIdToTransportId(*connection
->root_
));
109 if (root_
.get() && root_
->connection_id
== connection
->id())
113 mojo::ErrorCode
ViewManagerServiceImpl::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 ViewManagerServiceImpl::AddView(const ViewId
& parent_id
,
124 const ViewId
& child_id
) {
125 ServerView
* parent
= GetView(parent_id
);
126 ServerView
* child
= GetView(child_id
);
127 if (parent
&& child
&& child
->parent() != parent
&&
128 !child
->Contains(parent
) && access_policy_
->CanAddView(parent
, child
)) {
129 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
136 std::vector
<const ServerView
*> ViewManagerServiceImpl::GetViewTree(
137 const ViewId
& view_id
) const {
138 const ServerView
* view
= GetView(view_id
);
139 std::vector
<const ServerView
*> views
;
141 GetViewTreeImpl(view
, &views
);
145 bool ViewManagerServiceImpl::SetViewVisibility(const ViewId
& view_id
,
147 ServerView
* view
= GetView(view_id
);
148 if (!view
|| view
->visible() == visible
||
149 !access_policy_
->CanChangeViewVisibility(view
)) {
152 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
153 view
->SetVisible(visible
);
157 void ViewManagerServiceImpl::EmbedAllowingReembed(
158 const ViewId
& view_id
,
159 mojo::URLRequestPtr request
,
160 const mojo::Callback
<void(bool)>& callback
) {
161 if (!CanEmbed(view_id
)) {
166 ViewManagerServiceImpl
* embed_root
= nullptr;
168 ServerView
* view
= GetView(view_id
);
169 DCHECK(view
); // CanEmbed() returns true only if |view_id| is valid.
170 if (view
->id().connection_id
== id_
) {
171 view
->set_allows_reembed(true);
173 // Only consult the embed root if the creator is doing the embed. If someone
174 // other than the creator is doing the embed they were granted embed access.
175 embed_root
= connection_manager_
->GetEmbedRoot(this);
179 PrepareForEmbed(view_id
);
180 connection_manager_
->EmbedAtView(id_
, view_id
, request
.Pass());
185 // There is an embed root. We have to query it before completing the embed.
186 scoped_refptr
<PendingEmbed
> pending_embed(new PendingEmbed
);
187 pending_embeds_
.insert(pending_embed
);
188 pending_embed
->embed_root
= embed_root
;
189 pending_embed
->view_id
= view_id
;
190 pending_embed
->callback
= callback
;
191 pending_embeds_
.insert(pending_embed
);
192 embed_root
->client()->OnEmbedForDescendant(
193 ViewIdToTransportId(view_id
), request
.Pass(),
194 base::Bind(&ViewManagerServiceImpl::OnEmbedForDescendantDone
,
195 base::Unretained(this), pending_embed
));
198 bool ViewManagerServiceImpl::Embed(const ViewId
& view_id
,
199 mojo::ViewManagerClientPtr client
) {
200 if (!client
.get() || !CanEmbed(view_id
))
202 PrepareForEmbed(view_id
);
203 connection_manager_
->EmbedAtView(id_
, view_id
, client
.Pass());
207 void ViewManagerServiceImpl::ProcessViewBoundsChanged(
208 const ServerView
* view
,
209 const gfx::Rect
& old_bounds
,
210 const gfx::Rect
& new_bounds
,
211 bool originated_change
) {
212 if (originated_change
|| !IsViewKnown(view
))
214 client()->OnViewBoundsChanged(ViewIdToTransportId(view
->id()),
215 Rect::From(old_bounds
),
216 Rect::From(new_bounds
));
219 void ViewManagerServiceImpl::ProcessViewportMetricsChanged(
220 const mojo::ViewportMetrics
& old_metrics
,
221 const mojo::ViewportMetrics
& new_metrics
,
222 bool originated_change
) {
223 client()->OnViewViewportMetricsChanged(old_metrics
.Clone(),
224 new_metrics
.Clone());
227 void ViewManagerServiceImpl::ProcessWillChangeViewHierarchy(
228 const ServerView
* view
,
229 const ServerView
* new_parent
,
230 const ServerView
* old_parent
,
231 bool originated_change
) {
232 if (originated_change
)
235 const bool old_drawn
= view
->IsDrawn();
236 const bool new_drawn
= view
->visible() && new_parent
&& new_parent
->IsDrawn();
237 if (old_drawn
== new_drawn
)
240 NotifyDrawnStateChanged(view
, new_drawn
);
243 void ViewManagerServiceImpl::ProcessViewPropertyChanged(
244 const ServerView
* view
,
245 const std::string
& name
,
246 const std::vector
<uint8_t>* new_data
,
247 bool originated_change
) {
248 if (originated_change
)
253 data
= Array
<uint8_t>::From(*new_data
);
255 client()->OnViewSharedPropertyChanged(ViewIdToTransportId(view
->id()),
256 String(name
), data
.Pass());
259 void ViewManagerServiceImpl::ProcessViewHierarchyChanged(
260 const ServerView
* view
,
261 const ServerView
* new_parent
,
262 const ServerView
* old_parent
,
263 bool originated_change
) {
264 if (originated_change
&& !IsViewKnown(view
) && new_parent
&&
265 IsViewKnown(new_parent
)) {
266 std::vector
<const ServerView
*> unused
;
267 GetUnknownViewsFrom(view
, &unused
);
269 if (originated_change
|| connection_manager_
->is_processing_delete_view() ||
270 connection_manager_
->DidConnectionMessageClient(id_
)) {
274 if (!access_policy_
->ShouldNotifyOnHierarchyChange(
275 view
, &new_parent
, &old_parent
)) {
278 // Inform the client of any new views and update the set of views we know
280 std::vector
<const ServerView
*> to_send
;
281 if (!IsViewKnown(view
))
282 GetUnknownViewsFrom(view
, &to_send
);
283 const ViewId
new_parent_id(new_parent
? new_parent
->id() : ViewId());
284 const ViewId
old_parent_id(old_parent
? old_parent
->id() : ViewId());
285 client()->OnViewHierarchyChanged(ViewIdToTransportId(view
->id()),
286 ViewIdToTransportId(new_parent_id
),
287 ViewIdToTransportId(old_parent_id
),
288 ViewsToViewDatas(to_send
));
289 connection_manager_
->OnConnectionMessagedClient(id_
);
292 void ViewManagerServiceImpl::ProcessViewReorder(const ServerView
* view
,
293 const ServerView
* relative_view
,
294 OrderDirection direction
,
295 bool originated_change
) {
296 if (originated_change
|| !IsViewKnown(view
) || !IsViewKnown(relative_view
))
299 client()->OnViewReordered(ViewIdToTransportId(view
->id()),
300 ViewIdToTransportId(relative_view
->id()),
304 void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId
& view
,
305 bool originated_change
) {
306 if (view
.connection_id
== id_
)
307 view_map_
.erase(view
.view_id
);
309 const bool in_known
= known_views_
.erase(ViewIdToTransportId(view
)) > 0;
314 InvalidatePendingEmbedForView(view
);
316 if (originated_change
)
320 client()->OnViewDeleted(ViewIdToTransportId(view
));
321 connection_manager_
->OnConnectionMessagedClient(id_
);
325 void ViewManagerServiceImpl::ProcessWillChangeViewVisibility(
326 const ServerView
* view
,
327 bool originated_change
) {
328 if (originated_change
)
331 if (IsViewKnown(view
)) {
332 client()->OnViewVisibilityChanged(ViewIdToTransportId(view
->id()),
337 bool view_target_drawn_state
;
338 if (view
->visible()) {
339 // View is being hidden, won't be drawn.
340 view_target_drawn_state
= false;
342 // View is being shown. View will be drawn if its parent is drawn.
343 view_target_drawn_state
= view
->parent() && view
->parent()->IsDrawn();
346 NotifyDrawnStateChanged(view
, view_target_drawn_state
);
349 void ViewManagerServiceImpl::ProcessFocusChanged(
350 const ServerView
* old_focused_view
,
351 const ServerView
* new_focused_view
) {
352 const ServerView
* view
=
353 new_focused_view
? access_policy_
->GetViewForFocusChange(new_focused_view
)
355 client()->OnViewFocused(view
? ViewIdToTransportId(view
->id())
356 : ViewIdToTransportId(ViewId()));
359 bool ViewManagerServiceImpl::IsViewKnown(const ServerView
* view
) const {
360 return known_views_
.count(ViewIdToTransportId(view
->id())) > 0;
363 bool ViewManagerServiceImpl::CanReorderView(const ServerView
* view
,
364 const ServerView
* relative_view
,
365 OrderDirection direction
) const {
366 if (!view
|| !relative_view
)
369 if (!view
->parent() || view
->parent() != relative_view
->parent())
372 if (!access_policy_
->CanReorderView(view
, relative_view
, direction
))
375 std::vector
<const ServerView
*> children
= view
->parent()->GetChildren();
376 const size_t child_i
=
377 std::find(children
.begin(), children
.end(), view
) - children
.begin();
378 const size_t target_i
=
379 std::find(children
.begin(), children
.end(), relative_view
) -
381 if ((direction
== mojo::ORDER_DIRECTION_ABOVE
&& child_i
== target_i
+ 1) ||
382 (direction
== mojo::ORDER_DIRECTION_BELOW
&& child_i
+ 1 == target_i
)) {
389 bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl
* source
,
392 DCHECK_EQ(view
->id().connection_id
, id_
);
393 ConnectionManager::ScopedChange
change(source
, connection_manager_
, true);
398 void ViewManagerServiceImpl::GetUnknownViewsFrom(
399 const ServerView
* view
,
400 std::vector
<const ServerView
*>* views
) {
401 if (IsViewKnown(view
) || !access_policy_
->CanGetViewTree(view
))
403 views
->push_back(view
);
404 known_views_
.insert(ViewIdToTransportId(view
->id()));
405 if (!access_policy_
->CanDescendIntoViewForViewTree(view
))
407 std::vector
<const ServerView
*> children(view
->GetChildren());
408 for (size_t i
= 0 ; i
< children
.size(); ++i
)
409 GetUnknownViewsFrom(children
[i
], views
);
412 void ViewManagerServiceImpl::RemoveFromKnown(
413 const ServerView
* view
,
414 std::vector
<ServerView
*>* local_views
) {
415 if (view
->id().connection_id
== id_
) {
417 local_views
->push_back(GetView(view
->id()));
420 known_views_
.erase(ViewIdToTransportId(view
->id()));
421 std::vector
<const ServerView
*> children
= view
->GetChildren();
422 for (size_t i
= 0; i
< children
.size(); ++i
)
423 RemoveFromKnown(children
[i
], local_views
);
426 void ViewManagerServiceImpl::RemoveRoot() {
428 const ViewId
root_id(*root_
);
430 // No need to do anything if we created the view.
431 if (root_id
.connection_id
== id_
)
434 client()->OnViewDeleted(ViewIdToTransportId(root_id
));
435 connection_manager_
->OnConnectionMessagedClient(id_
);
437 // This connection no longer knows about the view. Unparent any views that
438 // were parented to views in the root.
439 std::vector
<ServerView
*> local_views
;
440 RemoveFromKnown(GetView(root_id
), &local_views
);
441 for (size_t i
= 0; i
< local_views
.size(); ++i
)
442 local_views
[i
]->parent()->Remove(local_views
[i
]);
445 Array
<ViewDataPtr
> ViewManagerServiceImpl::ViewsToViewDatas(
446 const std::vector
<const ServerView
*>& views
) {
447 Array
<ViewDataPtr
> array(views
.size());
448 for (size_t i
= 0; i
< views
.size(); ++i
)
449 array
[i
] = ViewToViewData(views
[i
]).Pass();
453 ViewDataPtr
ViewManagerServiceImpl::ViewToViewData(const ServerView
* view
) {
454 DCHECK(IsViewKnown(view
));
455 const ServerView
* parent
= view
->parent();
456 // If the parent isn't known, it means the parent is not visible to us (not
457 // in roots), and should not be sent over.
458 if (parent
&& !IsViewKnown(parent
))
460 ViewDataPtr
view_data(mojo::ViewData::New());
461 view_data
->parent_id
= ViewIdToTransportId(parent
? parent
->id() : ViewId());
462 view_data
->view_id
= ViewIdToTransportId(view
->id());
463 view_data
->bounds
= Rect::From(view
->bounds());
464 view_data
->properties
=
465 mojo::Map
<String
, Array
<uint8_t>>::From(view
->properties());
466 view_data
->visible
= view
->visible();
467 view_data
->drawn
= view
->IsDrawn();
468 view_data
->viewport_metrics
=
469 connection_manager_
->GetViewportMetricsForView(view
);
470 return view_data
.Pass();
473 void ViewManagerServiceImpl::GetViewTreeImpl(
474 const ServerView
* view
,
475 std::vector
<const ServerView
*>* views
) const {
478 if (!access_policy_
->CanGetViewTree(view
))
481 views
->push_back(view
);
483 if (!access_policy_
->CanDescendIntoViewForViewTree(view
))
486 std::vector
<const ServerView
*> children(view
->GetChildren());
487 for (size_t i
= 0 ; i
< children
.size(); ++i
)
488 GetViewTreeImpl(children
[i
], views
);
491 void ViewManagerServiceImpl::NotifyDrawnStateChanged(const ServerView
* view
,
492 bool new_drawn_value
) {
493 // Even though we don't know about view, it may be an ancestor of our root, in
494 // which case the change may effect our roots drawn state.
498 const ServerView
* root
= GetView(*root_
);
500 if (view
->Contains(root
) && (new_drawn_value
!= root
->IsDrawn())) {
501 client()->OnViewDrawnStateChanged(ViewIdToTransportId(root
->id()),
506 void ViewManagerServiceImpl::DestroyViews() {
507 if (!view_map_
.empty()) {
508 ConnectionManager::ScopedChange
change(this, connection_manager_
, true);
509 // If we get here from the destructor we're not going to get
510 // ProcessViewDeleted(). Copy the map and delete from the copy so that we
511 // don't have to worry about whether |view_map_| changes or not.
512 ViewMap view_map_copy
;
513 view_map_
.swap(view_map_copy
);
514 STLDeleteValues(&view_map_copy
);
518 bool ViewManagerServiceImpl::CanEmbed(const ViewId
& view_id
) const {
519 const ServerView
* view
= GetView(view_id
);
520 return view
&& access_policy_
->CanEmbed(view
);
523 void ViewManagerServiceImpl::PrepareForEmbed(const ViewId
& view_id
) {
524 const ServerView
* view
= GetView(view_id
);
525 DCHECK(view
&& access_policy_
->CanEmbed(view
));
527 // Only allow a node to be the root for one connection.
528 ViewManagerServiceImpl
* existing_owner
=
529 connection_manager_
->GetConnectionWithRoot(view_id
);
531 ConnectionManager::ScopedChange
change(this, connection_manager_
, true);
532 RemoveChildrenAsPartOfEmbed(view_id
);
533 if (existing_owner
) {
534 // Never message the originating connection.
535 connection_manager_
->OnConnectionMessagedClient(id_
);
536 existing_owner
->RemoveRoot();
540 void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
541 const ViewId
& view_id
) {
542 ServerView
* view
= GetView(view_id
);
544 CHECK(view
->id().connection_id
== view_id
.connection_id
);
545 std::vector
<ServerView
*> children
= view
->GetChildren();
546 for (size_t i
= 0; i
< children
.size(); ++i
)
547 view
->Remove(children
[i
]);
550 void ViewManagerServiceImpl::OnEmbedForDescendantDone(
551 scoped_refptr
<PendingEmbed
> pending_embed
,
552 mojo::ViewManagerClientPtr client
) {
553 if (!pending_embeds_
.count(pending_embed
.get()))
556 const bool allow_embed
= client
.get() && CanEmbed(pending_embed
->view_id
);
558 PrepareForEmbed(pending_embed
->view_id
);
559 connection_manager_
->EmbedAtView(id_
, pending_embed
->view_id
,
562 RemovePendingEmbedAndNotifyCallback(pending_embed
.get(), allow_embed
);
565 void ViewManagerServiceImpl::InvalidatePendingEmbedForConnection(
566 ViewManagerServiceImpl
* connection
) {
567 if (pending_embeds_
.empty())
569 std::set
<scoped_refptr
<PendingEmbed
>> copy(pending_embeds_
);
570 for (auto& embed
: copy
) {
571 if (embed
->embed_root
== connection
)
572 RemovePendingEmbedAndNotifyCallback(embed
, false);
576 void ViewManagerServiceImpl::InvalidatePendingEmbedForView(
577 const ViewId
& view_id
) {
578 if (pending_embeds_
.empty())
580 std::set
<scoped_refptr
<PendingEmbed
>> copy(pending_embeds_
);
581 for (auto& embed
: copy
) {
582 if (embed
->view_id
== view_id
)
583 RemovePendingEmbedAndNotifyCallback(embed
, false);
587 void ViewManagerServiceImpl::RemovePendingEmbedAndNotifyCallback(
588 scoped_refptr
<PendingEmbed
> embed
,
590 pending_embeds_
.erase(embed
);
591 embed
->callback
.Run(success
);
594 void ViewManagerServiceImpl::CreateView(
595 Id transport_view_id
,
596 const Callback
<void(mojo::ErrorCode
)>& callback
) {
597 callback
.Run(CreateView(ViewIdFromTransportId(transport_view_id
)));
600 void ViewManagerServiceImpl::DeleteView(
601 Id transport_view_id
,
602 const Callback
<void(bool)>& callback
) {
603 ServerView
* view
= GetView(ViewIdFromTransportId(transport_view_id
));
604 bool success
= false;
605 if (view
&& access_policy_
->CanDeleteView(view
)) {
606 ViewManagerServiceImpl
* connection
=
607 connection_manager_
->GetConnection(view
->id().connection_id
);
608 success
= connection
&& connection
->DeleteViewImpl(this, view
);
610 callback
.Run(success
);
613 void ViewManagerServiceImpl::AddView(
616 const Callback
<void(bool)>& callback
) {
617 callback
.Run(AddView(ViewIdFromTransportId(parent_id
),
618 ViewIdFromTransportId(child_id
)));
621 void ViewManagerServiceImpl::RemoveViewFromParent(
623 const Callback
<void(bool)>& callback
) {
624 bool success
= false;
625 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
626 if (view
&& view
->parent() && access_policy_
->CanRemoveViewFromParent(view
)) {
628 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
629 view
->parent()->Remove(view
);
631 callback
.Run(success
);
634 void ViewManagerServiceImpl::ReorderView(Id view_id
,
636 OrderDirection direction
,
637 const Callback
<void(bool)>& callback
) {
638 bool success
= false;
639 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
640 ServerView
* relative_view
= GetView(ViewIdFromTransportId(relative_view_id
));
641 if (CanReorderView(view
, relative_view
, direction
)) {
643 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
644 view
->parent()->Reorder(view
, relative_view
, direction
);
645 connection_manager_
->ProcessViewReorder(view
, relative_view
, direction
);
647 callback
.Run(success
);
650 void ViewManagerServiceImpl::GetViewTree(
652 const Callback
<void(Array
<ViewDataPtr
>)>& callback
) {
653 std::vector
<const ServerView
*> views(
654 GetViewTree(ViewIdFromTransportId(view_id
)));
655 callback
.Run(ViewsToViewDatas(views
));
658 void ViewManagerServiceImpl::SetViewSurfaceId(
660 mojo::SurfaceIdPtr surface_id
,
661 const Callback
<void(bool)>& callback
) {
662 // TODO(sky): add coverage of not being able to set for random node.
663 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
664 if (!view
|| !access_policy_
->CanSetViewSurfaceId(view
)) {
668 view
->SetSurfaceId(surface_id
.To
<cc::SurfaceId
>());
672 void ViewManagerServiceImpl::SetViewBounds(
674 mojo::RectPtr bounds
,
675 const Callback
<void(bool)>& callback
) {
676 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
677 const bool success
= view
&& access_policy_
->CanSetViewBounds(view
);
679 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
680 view
->SetBounds(bounds
.To
<gfx::Rect
>());
682 callback
.Run(success
);
685 void ViewManagerServiceImpl::SetViewVisibility(
686 Id transport_view_id
,
688 const Callback
<void(bool)>& callback
) {
690 SetViewVisibility(ViewIdFromTransportId(transport_view_id
), visible
));
693 void ViewManagerServiceImpl::SetViewProperty(
695 const mojo::String
& name
,
696 mojo::Array
<uint8_t> value
,
697 const mojo::Callback
<void(bool)>& callback
) {
698 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
699 const bool success
= view
&& access_policy_
->CanSetViewProperties(view
);
701 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
703 if (value
.is_null()) {
704 view
->SetProperty(name
, nullptr);
706 std::vector
<uint8_t> data
= value
.To
<std::vector
<uint8_t>>();
707 view
->SetProperty(name
, &data
);
710 callback
.Run(success
);
713 void ViewManagerServiceImpl::SetEmbedRoot() {
714 is_embed_root_
= true;
717 void ViewManagerServiceImpl::Embed(mojo::Id transport_view_id
,
718 mojo::ViewManagerClientPtr client
,
719 const mojo::Callback
<void(bool)>& callback
) {
720 callback
.Run(Embed(ViewIdFromTransportId(transport_view_id
), client
.Pass()));
723 void ViewManagerServiceImpl::EmbedAllowingReembed(
724 mojo::Id transport_view_id
,
725 mojo::URLRequestPtr request
,
726 const mojo::Callback
<void(bool)>& callback
) {
727 EmbedAllowingReembed(ViewIdFromTransportId(transport_view_id
), request
.Pass(),
731 void ViewManagerServiceImpl::SetFocus(uint32_t view_id
,
732 const SetFocusCallback
& callback
) {
733 ServerView
* view
= GetView(ViewIdFromTransportId(view_id
));
734 bool success
= view
&& view
->IsDrawn() && access_policy_
->CanSetFocus(view
);
736 ConnectionManager::ScopedChange
change(this, connection_manager_
, false);
737 connection_manager_
->SetFocusedView(view
);
739 callback
.Run(success
);
742 bool ViewManagerServiceImpl::IsRootForAccessPolicy(const ViewId
& id
) const {
746 bool ViewManagerServiceImpl::IsViewKnownForAccessPolicy(
747 const ServerView
* view
) const {
748 return IsViewKnown(view
);
751 bool ViewManagerServiceImpl::IsViewRootOfAnotherConnectionForAccessPolicy(
752 const ServerView
* view
) const {
753 ViewManagerServiceImpl
* connection
=
754 connection_manager_
->GetConnectionWithRoot(view
->id());
755 return connection
&& connection
!= this;
758 bool ViewManagerServiceImpl::IsEmbedRootForAccessPolicy() {
759 return is_embed_root_
;
762 } // namespace view_manager