Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h" | 5 #include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "mojo/public/cpp/application/application_connection.h" | 10 #include "mojo/public/cpp/application/application_connection.h" |
| 11 #include "mojo/public/cpp/application/connect.h" | 11 #include "mojo/public/cpp/application/connect.h" |
| 12 #include "mojo/public/cpp/application/exported_service_registry.h" | |
| 13 #include "mojo/public/interfaces/application/service_provider.mojom.h" | |
| 12 #include "mojo/services/public/cpp/view_manager/lib/node_private.h" | 14 #include "mojo/services/public/cpp/view_manager/lib/node_private.h" |
| 13 #include "mojo/services/public/cpp/view_manager/lib/view_private.h" | 15 #include "mojo/services/public/cpp/view_manager/lib/view_private.h" |
| 14 #include "mojo/services/public/cpp/view_manager/node_observer.h" | 16 #include "mojo/services/public/cpp/view_manager/node_observer.h" |
| 15 #include "mojo/services/public/cpp/view_manager/util.h" | 17 #include "mojo/services/public/cpp/view_manager/util.h" |
| 16 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | 18 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" |
| 17 #include "mojo/services/public/cpp/view_manager/view_observer.h" | 19 #include "mojo/services/public/cpp/view_manager/view_observer.h" |
| 18 #include "mojo/services/public/cpp/view_manager/window_manager_delegate.h" | 20 #include "mojo/services/public/cpp/view_manager/window_manager_delegate.h" |
| 19 #include "third_party/skia/include/core/SkBitmap.h" | 21 #include "third_party/skia/include/core/SkBitmap.h" |
| 20 #include "ui/gfx/codec/png_codec.h" | 22 #include "ui/gfx/codec/png_codec.h" |
| 21 | 23 |
| 22 namespace mojo { | 24 namespace mojo { |
| 23 | 25 |
| 24 Id MakeTransportId(ConnectionSpecificId connection_id, | 26 Id MakeTransportId(ConnectionSpecificId connection_id, |
| 25 ConnectionSpecificId local_id) { | 27 ConnectionSpecificId local_id) { |
| 26 return (connection_id << 16) | local_id; | 28 return (connection_id << 16) | local_id; |
| 27 } | 29 } |
| 28 | 30 |
| 29 // Helper called to construct a local node/view object from transport data. | 31 // Helper called to construct a local node/view object from transport data. |
| 30 Node* AddNodeToViewManager(ViewManagerClientImpl* client, | 32 Node* AddNodeToViewManager(ViewManagerClientImpl* client, |
| 31 Node* parent, | 33 Node* parent, |
| 32 Id node_id, | 34 Id node_id, |
| 33 Id view_id, | 35 Id view_id, |
| 34 const gfx::Rect& bounds) { | 36 const gfx::Rect& bounds) { |
| 35 // We don't use the ctor that takes a ViewManager here, since it will call | 37 // We don't use the ctor that takes a ViewManager here, since it will call |
| 36 // back to the service and attempt to create a new node. | 38 // back to the service and attempt to create a new node. |
| 37 Node* node = NodePrivate::LocalCreate(); | 39 Node* node = NodePrivate::LocalCreate(); |
| 38 NodePrivate private_node(node); | 40 NodePrivate private_node(node); |
| 39 private_node.set_view_manager(client); | 41 private_node.set_view_manager(client); |
| 40 private_node.set_id(node_id); | 42 private_node.set_id(node_id); |
| 43 client->AddNode(node); | |
| 41 private_node.LocalSetBounds(gfx::Rect(), bounds); | 44 private_node.LocalSetBounds(gfx::Rect(), bounds); |
| 42 if (parent) | 45 if (parent) |
| 43 NodePrivate(parent).LocalAddChild(node); | 46 NodePrivate(parent).LocalAddChild(node); |
| 44 client->AddNode(node); | |
| 45 | 47 |
| 46 // View. | 48 // View. |
| 47 if (view_id != 0) { | 49 if (view_id != 0) { |
| 48 View* view = ViewPrivate::LocalCreate(); | 50 View* view = ViewPrivate::LocalCreate(); |
| 49 ViewPrivate private_view(view); | 51 ViewPrivate private_view(view); |
| 50 private_view.set_view_manager(client); | 52 private_view.set_view_manager(client); |
| 51 private_view.set_id(view_id); | 53 private_view.set_id(view_id); |
| 52 private_view.set_node(node); | 54 private_view.set_node(node); |
| 55 client->AddView(view); | |
| 53 // TODO(beng): this broadcasts notifications locally... do we want this? I | 56 // TODO(beng): this broadcasts notifications locally... do we want this? I |
| 54 // don't think so. same story for LocalAddChild above! | 57 // don't think so. same story for LocalAddChild above! |
| 55 private_node.LocalSetActiveView(view); | 58 private_node.LocalSetActiveView(view); |
| 56 client->AddView(view); | |
| 57 } | 59 } |
| 58 return node; | 60 return node; |
| 59 } | 61 } |
| 60 | 62 |
| 61 Node* BuildNodeTree(ViewManagerClientImpl* client, | 63 Node* BuildNodeTree(ViewManagerClientImpl* client, |
| 62 const Array<NodeDataPtr>& nodes, | 64 const Array<NodeDataPtr>& nodes, |
| 63 Node* initial_parent) { | 65 Node* initial_parent) { |
| 64 std::vector<Node*> parents; | 66 std::vector<Node*> parents; |
| 65 Node* root = NULL; | 67 Node* root = NULL; |
| 66 Node* last_node = NULL; | 68 Node* last_node = NULL; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 DCHECK(connected_); | 256 DCHECK(connected_); |
| 255 service_->SetFocus(node_id, ActionCompletedCallback()); | 257 service_->SetFocus(node_id, ActionCompletedCallback()); |
| 256 } | 258 } |
| 257 | 259 |
| 258 void ViewManagerClientImpl::SetVisible(Id node_id, bool visible) { | 260 void ViewManagerClientImpl::SetVisible(Id node_id, bool visible) { |
| 259 DCHECK(connected_); | 261 DCHECK(connected_); |
| 260 service_->SetNodeVisibility(node_id, visible, ActionCompletedCallback()); | 262 service_->SetNodeVisibility(node_id, visible, ActionCompletedCallback()); |
| 261 } | 263 } |
| 262 | 264 |
| 263 void ViewManagerClientImpl::Embed(const String& url, Id node_id) { | 265 void ViewManagerClientImpl::Embed(const String& url, Id node_id) { |
| 266 ServiceProviderPtr sp; | |
| 267 BindToProxy(new ExportedServiceRegistry, &sp); | |
| 268 Embed(url, node_id, sp.Pass()); | |
| 269 } | |
| 270 | |
| 271 void ViewManagerClientImpl::Embed( | |
| 272 const String& url, | |
| 273 Id node_id, | |
| 274 ServiceProviderPtr service_provider) { | |
| 264 DCHECK(connected_); | 275 DCHECK(connected_); |
| 265 service_->Embed(url, node_id, ActionCompletedCallback()); | 276 service_->Embed(url, node_id, service_provider.Pass(), |
| 277 ActionCompletedCallback()); | |
| 266 } | 278 } |
| 267 | 279 |
| 268 void ViewManagerClientImpl::AddNode(Node* node) { | 280 void ViewManagerClientImpl::AddNode(Node* node) { |
| 269 DCHECK(nodes_.find(node->id()) == nodes_.end()); | 281 DCHECK(nodes_.find(node->id()) == nodes_.end()); |
| 270 nodes_[node->id()] = node; | 282 nodes_[node->id()] = node; |
| 271 } | 283 } |
| 272 | 284 |
| 273 void ViewManagerClientImpl::RemoveNode(Id node_id) { | 285 void ViewManagerClientImpl::RemoveNode(Id node_id) { |
| 274 IdToNodeMap::iterator it = nodes_.find(node_id); | 286 IdToNodeMap::iterator it = nodes_.find(node_id); |
| 275 if (it != nodes_.end()) | 287 if (it != nodes_.end()) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 //////////////////////////////////////////////////////////////////////////////// | 334 //////////////////////////////////////////////////////////////////////////////// |
| 323 // ViewManagerClientImpl, InterfaceImpl overrides: | 335 // ViewManagerClientImpl, InterfaceImpl overrides: |
| 324 | 336 |
| 325 void ViewManagerClientImpl::OnConnectionEstablished() { | 337 void ViewManagerClientImpl::OnConnectionEstablished() { |
| 326 service_ = client(); | 338 service_ = client(); |
| 327 } | 339 } |
| 328 | 340 |
| 329 //////////////////////////////////////////////////////////////////////////////// | 341 //////////////////////////////////////////////////////////////////////////////// |
| 330 // ViewManagerClientImpl, ViewManagerClient implementation: | 342 // ViewManagerClientImpl, ViewManagerClient implementation: |
| 331 | 343 |
| 332 void ViewManagerClientImpl::OnEmbed(ConnectionSpecificId connection_id, | 344 void ViewManagerClientImpl::OnEmbed( |
| 333 const String& creator_url, | 345 ConnectionSpecificId connection_id, |
| 334 NodeDataPtr root) { | 346 const String& creator_url, |
| 347 NodeDataPtr root_data, | |
| 348 InterfaceRequest<ServiceProvider> service_provider) { | |
| 335 if (!connected_) { | 349 if (!connected_) { |
| 336 connected_ = true; | 350 connected_ = true; |
| 337 connection_id_ = connection_id; | 351 connection_id_ = connection_id; |
| 338 creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url); | 352 creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url); |
| 339 } else { | 353 } else { |
| 340 DCHECK_EQ(connection_id_, connection_id); | 354 DCHECK_EQ(connection_id_, connection_id); |
| 341 DCHECK_EQ(creator_url_, creator_url); | 355 DCHECK_EQ(creator_url_, creator_url); |
| 342 } | 356 } |
| 343 AddRoot(AddNodeToViewManager(this, NULL, root->node_id, root->view_id, | 357 |
| 344 root->bounds.To<gfx::Rect>())); | 358 // A new root must not already exist as a root or be contained by an existing |
| 359 // hierarchy visible to this view manager. | |
| 360 Node* root = AddNodeToViewManager(this, NULL, root_data->node_id, | |
| 361 root_data->view_id, | |
| 362 root_data->bounds.To<gfx::Rect>()); | |
| 363 std::vector<Node*>::const_iterator it = roots_.begin(); | |
| 364 for (; it != roots_.end(); ++it) { | |
| 365 if (*it == root || (*it)->Contains(root)) | |
| 366 return; | |
|
sky
2014/07/31 21:14:11
Do we ever really hit this?
| |
| 367 } | |
| 368 roots_.push_back(root); | |
| 369 root->AddObserver(new RootObserver(root)); | |
| 370 | |
| 371 // BindToRequest() binds the lifetime of |exported_services| to the pipe. | |
| 372 ExportedServiceRegistry* exported_services = new ExportedServiceRegistry; | |
| 373 BindToRequest(exported_services, &service_provider); | |
| 374 RemoteServiceProvider* remote = | |
| 375 new RemoteServiceProvider(exported_services->client()); | |
| 376 exported_services->set_remote(remote); | |
| 377 delegate_->OnEmbed(this, root, exported_services, | |
| 378 scoped_ptr<ServiceProvider>(remote).Pass()); | |
| 345 } | 379 } |
| 346 | 380 |
| 347 void ViewManagerClientImpl::OnNodeBoundsChanged(Id node_id, | 381 void ViewManagerClientImpl::OnNodeBoundsChanged(Id node_id, |
| 348 RectPtr old_bounds, | 382 RectPtr old_bounds, |
| 349 RectPtr new_bounds) { | 383 RectPtr new_bounds) { |
| 350 Node* node = GetNodeById(node_id); | 384 Node* node = GetNodeById(node_id); |
| 351 NodePrivate(node).LocalSetBounds(old_bounds.To<gfx::Rect>(), | 385 NodePrivate(node).LocalSetBounds(old_bounds.To<gfx::Rect>(), |
| 352 new_bounds.To<gfx::Rect>()); | 386 new_bounds.To<gfx::Rect>()); |
| 353 } | 387 } |
| 354 | 388 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 *NodePrivate(blurred).observers(), | 467 *NodePrivate(blurred).observers(), |
| 434 OnNodeFocusChanged(focused, blurred)); | 468 OnNodeFocusChanged(focused, blurred)); |
| 435 } | 469 } |
| 436 if (focused) { | 470 if (focused) { |
| 437 FOR_EACH_OBSERVER(NodeObserver, | 471 FOR_EACH_OBSERVER(NodeObserver, |
| 438 *NodePrivate(focused).observers(), | 472 *NodePrivate(focused).observers(), |
| 439 OnNodeFocusChanged(focused, blurred)); | 473 OnNodeFocusChanged(focused, blurred)); |
| 440 } | 474 } |
| 441 } | 475 } |
| 442 | 476 |
| 443 void ViewManagerClientImpl::Embed(const String& url) { | 477 void ViewManagerClientImpl::Embed( |
| 444 window_manager_delegate_->Embed(url); | 478 const String& url, |
| 479 InterfaceRequest<ServiceProvider> service_provider) { | |
| 480 window_manager_delegate_->Embed(url, service_provider.Pass()); | |
| 445 } | 481 } |
| 446 | 482 |
| 447 void ViewManagerClientImpl::DispatchOnViewInputEvent(Id view_id, | 483 void ViewManagerClientImpl::DispatchOnViewInputEvent(Id view_id, |
| 448 EventPtr event) { | 484 EventPtr event) { |
| 449 window_manager_delegate_->DispatchEvent(GetViewById(view_id), event.Pass()); | 485 window_manager_delegate_->DispatchEvent(GetViewById(view_id), event.Pass()); |
| 450 } | 486 } |
| 451 | 487 |
| 452 //////////////////////////////////////////////////////////////////////////////// | 488 //////////////////////////////////////////////////////////////////////////////// |
| 453 // ViewManagerClientImpl, private: | 489 // ViewManagerClientImpl, private: |
| 454 | 490 |
| 455 void ViewManagerClientImpl::AddRoot(Node* root) { | |
| 456 // A new root must not already exist as a root or be contained by an existing | |
| 457 // hierarchy visible to this view manager. | |
| 458 std::vector<Node*>::const_iterator it = roots_.begin(); | |
| 459 for (; it != roots_.end(); ++it) { | |
| 460 if (*it == root || (*it)->Contains(root)) | |
| 461 return; | |
| 462 } | |
| 463 roots_.push_back(root); | |
| 464 root->AddObserver(new RootObserver(root)); | |
| 465 delegate_->OnEmbed(this, root); | |
| 466 } | |
| 467 | |
| 468 void ViewManagerClientImpl::RemoveRoot(Node* root) { | 491 void ViewManagerClientImpl::RemoveRoot(Node* root) { |
| 469 std::vector<Node*>::iterator it = | 492 std::vector<Node*>::iterator it = |
| 470 std::find(roots_.begin(), roots_.end(), root); | 493 std::find(roots_.begin(), roots_.end(), root); |
| 471 if (it != roots_.end()) | 494 if (it != roots_.end()) |
| 472 roots_.erase(it); | 495 roots_.erase(it); |
| 473 } | 496 } |
| 474 | 497 |
| 475 void ViewManagerClientImpl::OnActionCompleted(bool success) { | 498 void ViewManagerClientImpl::OnActionCompleted(bool success) { |
| 476 if (!change_acked_callback_.is_null()) | 499 if (!change_acked_callback_.is_null()) |
| 477 change_acked_callback_.Run(); | 500 change_acked_callback_.Run(); |
| 478 } | 501 } |
| 479 | 502 |
| 480 void ViewManagerClientImpl::OnActionCompletedWithErrorCode(ErrorCode code) { | 503 void ViewManagerClientImpl::OnActionCompletedWithErrorCode(ErrorCode code) { |
| 481 OnActionCompleted(code == ERROR_CODE_NONE); | 504 OnActionCompleted(code == ERROR_CODE_NONE); |
| 482 } | 505 } |
| 483 | 506 |
| 484 base::Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() { | 507 base::Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() { |
| 485 return base::Bind(&ViewManagerClientImpl::OnActionCompleted, | 508 return base::Bind(&ViewManagerClientImpl::OnActionCompleted, |
| 486 base::Unretained(this)); | 509 base::Unretained(this)); |
| 487 } | 510 } |
| 488 | 511 |
| 489 base::Callback<void(ErrorCode)> | 512 base::Callback<void(ErrorCode)> |
| 490 ViewManagerClientImpl::ActionCompletedCallbackWithErrorCode() { | 513 ViewManagerClientImpl::ActionCompletedCallbackWithErrorCode() { |
| 491 return base::Bind(&ViewManagerClientImpl::OnActionCompletedWithErrorCode, | 514 return base::Bind(&ViewManagerClientImpl::OnActionCompletedWithErrorCode, |
| 492 base::Unretained(this)); | 515 base::Unretained(this)); |
| 493 } | 516 } |
| 494 | 517 |
| 495 } // namespace mojo | 518 } // namespace mojo |
| OLD | NEW |