| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "mojo/services/view_manager/root_node_manager.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "mojo/public/cpp/application/application_connection.h" | |
| 9 #include "mojo/public/interfaces/application/service_provider.mojom.h" | |
| 10 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h" | |
| 11 #include "mojo/services/view_manager/view_manager_service_impl.h" | |
| 12 #include "ui/aura/env.h" | |
| 13 | |
| 14 namespace mojo { | |
| 15 namespace service { | |
| 16 | |
| 17 RootNodeManager::ScopedChange::ScopedChange( | |
| 18 ViewManagerServiceImpl* connection, | |
| 19 RootNodeManager* root, | |
| 20 bool is_delete_node) | |
| 21 : root_(root), | |
| 22 connection_id_(connection->id()), | |
| 23 is_delete_node_(is_delete_node) { | |
| 24 root_->PrepareForChange(this); | |
| 25 } | |
| 26 | |
| 27 RootNodeManager::ScopedChange::~ScopedChange() { | |
| 28 root_->FinishChange(); | |
| 29 } | |
| 30 | |
| 31 RootNodeManager::Context::Context() { | |
| 32 // Pass in false as native viewport creates the PlatformEventSource. | |
| 33 aura::Env::CreateInstance(false); | |
| 34 } | |
| 35 | |
| 36 RootNodeManager::Context::~Context() { | |
| 37 aura::Env::DeleteInstance(); | |
| 38 } | |
| 39 | |
| 40 RootNodeManager::RootNodeManager( | |
| 41 ApplicationConnection* app_connection, | |
| 42 DisplayManagerDelegate* display_manager_delegate, | |
| 43 const Callback<void()>& native_viewport_closed_callback) | |
| 44 : app_connection_(app_connection), | |
| 45 next_connection_id_(1), | |
| 46 display_manager_(app_connection, | |
| 47 this, | |
| 48 display_manager_delegate, | |
| 49 native_viewport_closed_callback), | |
| 50 root_(new Node(this, RootNodeId())), | |
| 51 current_change_(NULL) { | |
| 52 } | |
| 53 | |
| 54 RootNodeManager::~RootNodeManager() { | |
| 55 while (!connections_created_by_connect_.empty()) | |
| 56 delete *(connections_created_by_connect_.begin()); | |
| 57 // All the connections should have been destroyed. | |
| 58 DCHECK(connection_map_.empty()); | |
| 59 root_.reset(); | |
| 60 } | |
| 61 | |
| 62 ConnectionSpecificId RootNodeManager::GetAndAdvanceNextConnectionId() { | |
| 63 const ConnectionSpecificId id = next_connection_id_++; | |
| 64 DCHECK_LT(id, next_connection_id_); | |
| 65 return id; | |
| 66 } | |
| 67 | |
| 68 void RootNodeManager::AddConnection(ViewManagerServiceImpl* connection) { | |
| 69 DCHECK_EQ(0u, connection_map_.count(connection->id())); | |
| 70 connection_map_[connection->id()] = connection; | |
| 71 } | |
| 72 | |
| 73 void RootNodeManager::RemoveConnection(ViewManagerServiceImpl* connection) { | |
| 74 connection_map_.erase(connection->id()); | |
| 75 connections_created_by_connect_.erase(connection); | |
| 76 | |
| 77 // Notify remaining connections so that they can cleanup. | |
| 78 for (ConnectionMap::const_iterator i = connection_map_.begin(); | |
| 79 i != connection_map_.end(); ++i) { | |
| 80 i->second->OnViewManagerServiceImplDestroyed(connection->id()); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 void RootNodeManager::EmbedRoot( | |
| 85 const std::string& url, | |
| 86 InterfaceRequest<ServiceProvider> service_provider) { | |
| 87 if (connection_map_.empty()) { | |
| 88 EmbedImpl(kInvalidConnectionId, String::From(url), RootNodeId(), | |
| 89 service_provider.Pass()); | |
| 90 return; | |
| 91 } | |
| 92 ViewManagerServiceImpl* connection = GetConnection(kWindowManagerConnection); | |
| 93 connection->client()->Embed(url, service_provider.Pass()); | |
| 94 } | |
| 95 | |
| 96 void RootNodeManager::Embed( | |
| 97 ConnectionSpecificId creator_id, | |
| 98 const String& url, | |
| 99 Id transport_node_id, | |
| 100 InterfaceRequest<ServiceProvider> service_provider) { | |
| 101 EmbedImpl(creator_id, | |
| 102 url, | |
| 103 NodeIdFromTransportId(transport_node_id), | |
| 104 service_provider.Pass())->set_delete_on_connection_error(); | |
| 105 } | |
| 106 | |
| 107 ViewManagerServiceImpl* RootNodeManager::GetConnection( | |
| 108 ConnectionSpecificId connection_id) { | |
| 109 ConnectionMap::iterator i = connection_map_.find(connection_id); | |
| 110 return i == connection_map_.end() ? NULL : i->second; | |
| 111 } | |
| 112 | |
| 113 Node* RootNodeManager::GetNode(const NodeId& id) { | |
| 114 if (id == root_->id()) | |
| 115 return root_.get(); | |
| 116 ConnectionMap::iterator i = connection_map_.find(id.connection_id); | |
| 117 return i == connection_map_.end() ? NULL : i->second->GetNode(id); | |
| 118 } | |
| 119 | |
| 120 void RootNodeManager::OnConnectionMessagedClient(ConnectionSpecificId id) { | |
| 121 if (current_change_) | |
| 122 current_change_->MarkConnectionAsMessaged(id); | |
| 123 } | |
| 124 | |
| 125 bool RootNodeManager::DidConnectionMessageClient( | |
| 126 ConnectionSpecificId id) const { | |
| 127 return current_change_ && current_change_->DidMessageConnection(id); | |
| 128 } | |
| 129 | |
| 130 ViewManagerServiceImpl* RootNodeManager::GetConnectionByCreator( | |
| 131 ConnectionSpecificId creator_id, | |
| 132 const std::string& url) const { | |
| 133 for (ConnectionMap::const_iterator i = connection_map_.begin(); | |
| 134 i != connection_map_.end(); ++i) { | |
| 135 if (i->second->creator_id() == creator_id && i->second->url() == url) | |
| 136 return i->second; | |
| 137 } | |
| 138 return NULL; | |
| 139 } | |
| 140 | |
| 141 const ViewManagerServiceImpl* RootNodeManager::GetConnectionWithRoot( | |
| 142 const NodeId& id) const { | |
| 143 for (ConnectionMap::const_iterator i = connection_map_.begin(); | |
| 144 i != connection_map_.end(); ++i) { | |
| 145 if (i->second->HasRoot(id)) | |
| 146 return i->second; | |
| 147 } | |
| 148 return NULL; | |
| 149 } | |
| 150 | |
| 151 void RootNodeManager::DispatchNodeInputEventToWindowManager(EventPtr event) { | |
| 152 // Input events are forwarded to the WindowManager. The WindowManager | |
| 153 // eventually calls back to us with DispatchOnViewInputEvent(). | |
| 154 ViewManagerServiceImpl* connection = GetConnection(kWindowManagerConnection); | |
| 155 if (!connection) | |
| 156 return; | |
| 157 connection->client()->DispatchOnViewInputEvent(event.Pass()); | |
| 158 } | |
| 159 | |
| 160 void RootNodeManager::ProcessNodeBoundsChanged(const Node* node, | |
| 161 const gfx::Rect& old_bounds, | |
| 162 const gfx::Rect& new_bounds) { | |
| 163 for (ConnectionMap::iterator i = connection_map_.begin(); | |
| 164 i != connection_map_.end(); ++i) { | |
| 165 i->second->ProcessNodeBoundsChanged(node, old_bounds, new_bounds, | |
| 166 IsChangeSource(i->first)); | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 void RootNodeManager::ProcessNodeHierarchyChanged(const Node* node, | |
| 171 const Node* new_parent, | |
| 172 const Node* old_parent) { | |
| 173 for (ConnectionMap::iterator i = connection_map_.begin(); | |
| 174 i != connection_map_.end(); ++i) { | |
| 175 i->second->ProcessNodeHierarchyChanged( | |
| 176 node, new_parent, old_parent, IsChangeSource(i->first)); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 void RootNodeManager::ProcessNodeReorder(const Node* node, | |
| 181 const Node* relative_node, | |
| 182 const OrderDirection direction) { | |
| 183 for (ConnectionMap::iterator i = connection_map_.begin(); | |
| 184 i != connection_map_.end(); ++i) { | |
| 185 i->second->ProcessNodeReorder( | |
| 186 node, relative_node, direction, IsChangeSource(i->first)); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 void RootNodeManager::ProcessNodeDeleted(const NodeId& node) { | |
| 191 for (ConnectionMap::iterator i = connection_map_.begin(); | |
| 192 i != connection_map_.end(); ++i) { | |
| 193 i->second->ProcessNodeDeleted(node, IsChangeSource(i->first)); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 void RootNodeManager::PrepareForChange(ScopedChange* change) { | |
| 198 // Should only ever have one change in flight. | |
| 199 CHECK(!current_change_); | |
| 200 current_change_ = change; | |
| 201 } | |
| 202 | |
| 203 void RootNodeManager::FinishChange() { | |
| 204 // PrepareForChange/FinishChange should be balanced. | |
| 205 CHECK(current_change_); | |
| 206 current_change_ = NULL; | |
| 207 } | |
| 208 | |
| 209 ViewManagerServiceImpl* RootNodeManager::EmbedImpl( | |
| 210 const ConnectionSpecificId creator_id, | |
| 211 const String& url, | |
| 212 const NodeId& root_id, | |
| 213 InterfaceRequest<ServiceProvider> service_provider) { | |
| 214 MessagePipe pipe; | |
| 215 | |
| 216 ServiceProvider* view_manager_service_provider = | |
| 217 app_connection_->ConnectToApplication(url)->GetServiceProvider(); | |
| 218 view_manager_service_provider->ConnectToService( | |
| 219 ViewManagerServiceImpl::Client::Name_, | |
| 220 pipe.handle1.Pass()); | |
| 221 | |
| 222 std::string creator_url; | |
| 223 ConnectionMap::const_iterator it = connection_map_.find(creator_id); | |
| 224 if (it != connection_map_.end()) | |
| 225 creator_url = it->second->url(); | |
| 226 | |
| 227 ViewManagerServiceImpl* connection = | |
| 228 new ViewManagerServiceImpl(this, | |
| 229 creator_id, | |
| 230 creator_url, | |
| 231 url.To<std::string>(), | |
| 232 root_id, | |
| 233 service_provider.Pass()); | |
| 234 WeakBindToPipe(connection, pipe.handle0.Pass()); | |
| 235 connections_created_by_connect_.insert(connection); | |
| 236 OnConnectionMessagedClient(connection->id()); | |
| 237 return connection; | |
| 238 } | |
| 239 | |
| 240 void RootNodeManager::OnNodeDestroyed(const Node* node) { | |
| 241 ProcessNodeDeleted(node->id()); | |
| 242 } | |
| 243 | |
| 244 void RootNodeManager::OnNodeHierarchyChanged(const Node* node, | |
| 245 const Node* new_parent, | |
| 246 const Node* old_parent) { | |
| 247 if (!display_manager_.in_setup()) | |
| 248 ProcessNodeHierarchyChanged(node, new_parent, old_parent); | |
| 249 } | |
| 250 | |
| 251 void RootNodeManager::OnNodeBoundsChanged(const Node* node, | |
| 252 const gfx::Rect& old_bounds, | |
| 253 const gfx::Rect& new_bounds) { | |
| 254 ProcessNodeBoundsChanged(node, old_bounds, new_bounds); | |
| 255 if (!node->parent()) | |
| 256 return; | |
| 257 | |
| 258 // TODO(sky): optimize this. | |
| 259 display_manager_.SchedulePaint(node->parent(), old_bounds); | |
| 260 display_manager_.SchedulePaint(node->parent(), new_bounds); | |
| 261 } | |
| 262 | |
| 263 void RootNodeManager::OnNodeBitmapChanged(const Node* node) { | |
| 264 display_manager_.SchedulePaint(node, gfx::Rect(node->bounds().size())); | |
| 265 } | |
| 266 | |
| 267 } // namespace service | |
| 268 } // namespace mojo | |
| OLD | NEW |