Reland "Non-SFI mode: Switch to newlib. (patchset #4 id:60001 of https://codereview...
[chromium-blink-merge.git] / components / view_manager / view_manager_service_impl.cc
blob43f4c62beaabfa107f51b3849aa72bbd7e19ded9
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"
7 #include "base/bind.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"
18 using mojo::Array;
19 using mojo::Callback;
20 using mojo::Id;
21 using mojo::InterfaceRequest;
22 using mojo::OrderDirection;
23 using mojo::Rect;
24 using mojo::ServiceProvider;
25 using mojo::ServiceProviderPtr;
26 using mojo::String;
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;
38 ViewId view_id;
39 mojo::Callback<void(bool)> callback;
41 private:
42 friend class base::RefCounted<PendingEmbed>;
44 ~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),
54 client_(nullptr),
55 is_embed_root_(false) {
56 ServerView* view = GetView(root_id);
57 CHECK(view);
58 root_.reset(new ViewId(root_id));
59 if (view->GetRoot() == view)
60 access_policy_.reset(new WindowManagerAccessPolicy(id_, this));
61 else
62 access_policy_.reset(new DefaultAccessPolicy(id_, this));
65 ViewManagerServiceImpl::~ViewManagerServiceImpl() {
66 DestroyViews();
69 void ViewManagerServiceImpl::Init(mojo::ViewManagerClient* client,
70 mojo::ViewManagerServicePtr service_ptr) {
71 DCHECK(!client_);
72 client_ = client;
73 std::vector<const ServerView*> to_send;
74 if (root_.get())
75 GetUnknownViewsFrom(GetView(*root_), &to_send);
77 const ServerView* focused_view = connection_manager_->GetFocusedView();
78 if (focused_view)
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())
110 root_.reset();
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);
130 parent->Add(child);
131 return true;
133 return 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;
140 if (view)
141 GetViewTreeImpl(view, &views);
142 return views;
145 bool ViewManagerServiceImpl::SetViewVisibility(const ViewId& view_id,
146 bool visible) {
147 ServerView* view = GetView(view_id);
148 if (!view || view->visible() == visible ||
149 !access_policy_->CanChangeViewVisibility(view)) {
150 return false;
152 ConnectionManager::ScopedChange change(this, connection_manager_, false);
153 view->SetVisible(visible);
154 return true;
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)) {
162 callback.Run(false);
163 return;
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);
178 if (!embed_root) {
179 PrepareForEmbed(view_id);
180 connection_manager_->EmbedAtView(id_, view_id, request.Pass());
181 callback.Run(true);
182 return;
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))
201 return false;
202 PrepareForEmbed(view_id);
203 connection_manager_->EmbedAtView(id_, view_id, client.Pass());
204 return true;
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))
213 return;
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)
233 return;
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)
238 return;
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)
249 return;
251 Array<uint8_t> data;
252 if (new_data)
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_)) {
271 return;
274 if (!access_policy_->ShouldNotifyOnHierarchyChange(
275 view, &new_parent, &old_parent)) {
276 return;
278 // Inform the client of any new views and update the set of views we know
279 // about.
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))
297 return;
299 client()->OnViewReordered(ViewIdToTransportId(view->id()),
300 ViewIdToTransportId(relative_view->id()),
301 direction);
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;
311 if (IsRoot(view))
312 root_.reset();
314 InvalidatePendingEmbedForView(view);
316 if (originated_change)
317 return;
319 if (in_known) {
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)
329 return;
331 if (IsViewKnown(view)) {
332 client()->OnViewVisibilityChanged(ViewIdToTransportId(view->id()),
333 !view->visible());
334 return;
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;
341 } else {
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)
354 : nullptr;
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)
367 return false;
369 if (!view->parent() || view->parent() != relative_view->parent())
370 return false;
372 if (!access_policy_->CanReorderView(view, relative_view, direction))
373 return false;
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) -
380 children.begin();
381 if ((direction == mojo::ORDER_DIRECTION_ABOVE && child_i == target_i + 1) ||
382 (direction == mojo::ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) {
383 return false;
386 return true;
389 bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source,
390 ServerView* view) {
391 DCHECK(view);
392 DCHECK_EQ(view->id().connection_id, id_);
393 ConnectionManager::ScopedChange change(source, connection_manager_, true);
394 delete view;
395 return true;
398 void ViewManagerServiceImpl::GetUnknownViewsFrom(
399 const ServerView* view,
400 std::vector<const ServerView*>* views) {
401 if (IsViewKnown(view) || !access_policy_->CanGetViewTree(view))
402 return;
403 views->push_back(view);
404 known_views_.insert(ViewIdToTransportId(view->id()));
405 if (!access_policy_->CanDescendIntoViewForViewTree(view))
406 return;
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_) {
416 if (local_views)
417 local_views->push_back(GetView(view->id()));
418 return;
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() {
427 CHECK(root_.get());
428 const ViewId root_id(*root_);
429 root_.reset();
430 // No need to do anything if we created the view.
431 if (root_id.connection_id == id_)
432 return;
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();
450 return array.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))
459 parent = NULL;
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 {
476 DCHECK(view);
478 if (!access_policy_->CanGetViewTree(view))
479 return;
481 views->push_back(view);
483 if (!access_policy_->CanDescendIntoViewForViewTree(view))
484 return;
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.
495 if (!root_.get())
496 return;
498 const ServerView* root = GetView(*root_);
499 DCHECK(root);
500 if (view->Contains(root) && (new_drawn_value != root->IsDrawn())) {
501 client()->OnViewDrawnStateChanged(ViewIdToTransportId(root->id()),
502 new_drawn_value);
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);
543 CHECK(view);
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()))
554 return;
556 const bool allow_embed = client.get() && CanEmbed(pending_embed->view_id);
557 if (allow_embed) {
558 PrepareForEmbed(pending_embed->view_id);
559 connection_manager_->EmbedAtView(id_, pending_embed->view_id,
560 client.Pass());
562 RemovePendingEmbedAndNotifyCallback(pending_embed.get(), allow_embed);
565 void ViewManagerServiceImpl::InvalidatePendingEmbedForConnection(
566 ViewManagerServiceImpl* connection) {
567 if (pending_embeds_.empty())
568 return;
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())
579 return;
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,
589 bool success) {
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(
614 Id parent_id,
615 Id child_id,
616 const Callback<void(bool)>& callback) {
617 callback.Run(AddView(ViewIdFromTransportId(parent_id),
618 ViewIdFromTransportId(child_id)));
621 void ViewManagerServiceImpl::RemoveViewFromParent(
622 Id view_id,
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)) {
627 success = true;
628 ConnectionManager::ScopedChange change(this, connection_manager_, false);
629 view->parent()->Remove(view);
631 callback.Run(success);
634 void ViewManagerServiceImpl::ReorderView(Id view_id,
635 Id relative_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)) {
642 success = true;
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(
651 Id view_id,
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(
659 Id view_id,
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)) {
665 callback.Run(false);
666 return;
668 view->SetSurfaceId(surface_id.To<cc::SurfaceId>());
669 callback.Run(true);
672 void ViewManagerServiceImpl::SetViewBounds(
673 Id view_id,
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);
678 if (success) {
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,
687 bool visible,
688 const Callback<void(bool)>& callback) {
689 callback.Run(
690 SetViewVisibility(ViewIdFromTransportId(transport_view_id), visible));
693 void ViewManagerServiceImpl::SetViewProperty(
694 uint32_t view_id,
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);
700 if (success) {
701 ConnectionManager::ScopedChange change(this, connection_manager_, false);
703 if (value.is_null()) {
704 view->SetProperty(name, nullptr);
705 } else {
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(),
728 callback);
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);
735 if (success) {
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 {
743 return IsRoot(id);
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