[Drive] Handle error cases earlier in FakeDriveService
[chromium-blink-merge.git] / mojo / services / view_manager / root_node_manager.cc
blob03a81d294317c2293c139f8918b91d05311c736a
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 "mojo/services/view_manager/root_node_manager.h"
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"
14 namespace mojo {
15 namespace service {
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);
27 RootNodeManager::ScopedChange::~ScopedChange() {
28 root_->FinishChange();
31 RootNodeManager::Context::Context() {
32 // Pass in false as native viewport creates the PlatformEventSource.
33 aura::Env::CreateInstance(false);
36 RootNodeManager::Context::~Context() {
37 aura::Env::DeleteInstance();
40 RootNodeManager::RootNodeManager(
41 ApplicationConnection* app_connection,
42 RootViewManagerDelegate* view_manager_delegate,
43 const Callback<void()>& native_viewport_closed_callback)
44 : app_connection_(app_connection),
45 next_connection_id_(1),
46 root_view_manager_(app_connection,
47 this,
48 view_manager_delegate,
49 native_viewport_closed_callback),
50 root_(new Node(this, RootNodeId())),
51 current_change_(NULL) {
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();
62 ConnectionSpecificId RootNodeManager::GetAndAdvanceNextConnectionId() {
63 const ConnectionSpecificId id = next_connection_id_++;
64 DCHECK_LT(id, next_connection_id_);
65 return id;
68 void RootNodeManager::AddConnection(ViewManagerServiceImpl* connection) {
69 DCHECK_EQ(0u, connection_map_.count(connection->id()));
70 connection_map_[connection->id()] = connection;
73 void RootNodeManager::RemoveConnection(ViewManagerServiceImpl* connection) {
74 connection_map_.erase(connection->id());
75 connections_created_by_connect_.erase(connection);
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());
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;
92 ViewManagerServiceImpl* connection = GetConnection(kWindowManagerConnection);
93 connection->client()->Embed(url, service_provider.Pass());
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();
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;
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);
120 void RootNodeManager::OnConnectionMessagedClient(ConnectionSpecificId id) {
121 if (current_change_)
122 current_change_->MarkConnectionAsMessaged(id);
125 bool RootNodeManager::DidConnectionMessageClient(
126 ConnectionSpecificId id) const {
127 return current_change_ && current_change_->DidMessageConnection(id);
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;
138 return NULL;
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;
148 return NULL;
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());
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));
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));
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));
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));
197 void RootNodeManager::PrepareForChange(ScopedChange* change) {
198 // Should only ever have one change in flight.
199 CHECK(!current_change_);
200 current_change_ = change;
203 void RootNodeManager::FinishChange() {
204 // PrepareForChange/FinishChange should be balanced.
205 CHECK(current_change_);
206 current_change_ = NULL;
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;
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());
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();
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;
240 void RootNodeManager::OnNodeDestroyed(const Node* node) {
241 ProcessNodeDeleted(node->id());
244 void RootNodeManager::OnNodeHierarchyChanged(const Node* node,
245 const Node* new_parent,
246 const Node* old_parent) {
247 if (!root_view_manager_.in_setup())
248 ProcessNodeHierarchyChanged(node, new_parent, old_parent);
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);
257 } // namespace service
258 } // namespace mojo