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 #ifndef MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_ 6 #define MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/basictypes.h" 12 #include "mojo/public/cpp/bindings/array.h" 13 #include "mojo/services/view_manager/display_manager.h" 14 #include "mojo/services/view_manager/ids.h" 15 #include "mojo/services/view_manager/server_view.h" 16 #include "mojo/services/view_manager/server_view_delegate.h" 17 #include "mojo/services/view_manager/view_manager_export.h" 18 19 namespace ui { 20 class Event; 21 } 22 23 namespace mojo { 24 25 class ApplicationConnection; 26 27 namespace service { 28 29 class ViewManagerServiceImpl; 30 31 // ConnectionManager manages the set of connections to the ViewManager (all the 32 // ViewManagerServiceImpls) as well as providing the root of the hierarchy. 33 class MOJO_VIEW_MANAGER_EXPORT ConnectionManager : public ServerViewDelegate { 34 public: 35 // Create when a ViewManagerServiceImpl is about to make a change. Ensures 36 // clients are notified correctly. 37 class ScopedChange { 38 public: 39 ScopedChange(ViewManagerServiceImpl* connection, 40 ConnectionManager* connection_manager, 41 bool is_delete_view); 42 ~ScopedChange(); 43 connection_id()44 ConnectionSpecificId connection_id() const { return connection_id_; } is_delete_view()45 bool is_delete_view() const { return is_delete_view_; } 46 47 // Marks the connection with the specified id as having seen a message. MarkConnectionAsMessaged(ConnectionSpecificId connection_id)48 void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) { 49 message_ids_.insert(connection_id); 50 } 51 52 // Returns true if MarkConnectionAsMessaged(connection_id) was invoked. DidMessageConnection(ConnectionSpecificId connection_id)53 bool DidMessageConnection(ConnectionSpecificId connection_id) const { 54 return message_ids_.count(connection_id) > 0; 55 } 56 57 private: 58 ConnectionManager* connection_manager_; 59 const ConnectionSpecificId connection_id_; 60 const bool is_delete_view_; 61 62 // See description of MarkConnectionAsMessaged/DidMessageConnection. 63 std::set<ConnectionSpecificId> message_ids_; 64 65 DISALLOW_COPY_AND_ASSIGN(ScopedChange); 66 }; 67 68 ConnectionManager(ApplicationConnection* app_connection, 69 const Callback<void()>& native_viewport_closed_callback); 70 virtual ~ConnectionManager(); 71 72 // Returns the id for the next ViewManagerServiceImpl. 73 ConnectionSpecificId GetAndAdvanceNextConnectionId(); 74 75 void AddConnection(ViewManagerServiceImpl* connection); 76 void RemoveConnection(ViewManagerServiceImpl* connection); 77 78 // Establishes the initial client. Similar to Connect(), but the resulting 79 // client is allowed to do anything. 80 void EmbedRoot(const std::string& url, 81 InterfaceRequest<ServiceProvider> service_provider); 82 83 // See description of ViewManagerService::Embed() for details. This assumes 84 // |transport_view_id| is valid. 85 void Embed(ConnectionSpecificId creator_id, 86 const String& url, 87 Id transport_view_id, 88 InterfaceRequest<ServiceProvider> service_provider); 89 90 // Returns the connection by id. 91 ViewManagerServiceImpl* GetConnection(ConnectionSpecificId connection_id); 92 93 // Returns the View identified by |id|. 94 ServerView* GetView(const ViewId& id); 95 root()96 ServerView* root() { return root_.get(); } 97 IsProcessingChange()98 bool IsProcessingChange() const { return current_change_ != NULL; } 99 is_processing_delete_view()100 bool is_processing_delete_view() const { 101 return current_change_ && current_change_->is_delete_view(); 102 } 103 104 // Invoked when a connection messages a client about the change. This is used 105 // to avoid sending ServerChangeIdAdvanced() unnecessarily. 106 void OnConnectionMessagedClient(ConnectionSpecificId id); 107 108 // Returns true if OnConnectionMessagedClient() was invoked for id. 109 bool DidConnectionMessageClient(ConnectionSpecificId id) const; 110 111 // Returns the ViewManagerServiceImpl that has |id| as a root. GetConnectionWithRoot(const ViewId & id)112 ViewManagerServiceImpl* GetConnectionWithRoot(const ViewId& id) { 113 return const_cast<ViewManagerServiceImpl*>( 114 const_cast<const ConnectionManager*>(this)->GetConnectionWithRoot(id)); 115 } 116 const ViewManagerServiceImpl* GetConnectionWithRoot(const ViewId& id) const; 117 118 void DispatchViewInputEventToWindowManager(EventPtr event); 119 120 // These functions trivially delegate to all ViewManagerServiceImpls, which in 121 // term notify their clients. 122 void ProcessViewDestroyed(ServerView* view); 123 void ProcessViewBoundsChanged(const ServerView* view, 124 const gfx::Rect& old_bounds, 125 const gfx::Rect& new_bounds); 126 void ProcessWillChangeViewHierarchy(const ServerView* view, 127 const ServerView* new_parent, 128 const ServerView* old_parent); 129 void ProcessViewHierarchyChanged(const ServerView* view, 130 const ServerView* new_parent, 131 const ServerView* old_parent); 132 void ProcessViewReorder(const ServerView* view, 133 const ServerView* relative_view, 134 const OrderDirection direction); 135 void ProcessViewDeleted(const ViewId& view); 136 137 private: 138 typedef std::map<ConnectionSpecificId, ViewManagerServiceImpl*> ConnectionMap; 139 140 // Invoked when a connection is about to make a change. Subsequently followed 141 // by FinishChange() once the change is done. 142 // 143 // Changes should never nest, meaning each PrepareForChange() must be 144 // balanced with a call to FinishChange() with no PrepareForChange() 145 // in between. 146 void PrepareForChange(ScopedChange* change); 147 148 // Balances a call to PrepareForChange(). 149 void FinishChange(); 150 151 // Returns true if the specified connection originated the current change. IsChangeSource(ConnectionSpecificId connection_id)152 bool IsChangeSource(ConnectionSpecificId connection_id) const { 153 return current_change_ && current_change_->connection_id() == connection_id; 154 } 155 156 // Implementation of the two embed variants. 157 ViewManagerServiceImpl* EmbedImpl( 158 ConnectionSpecificId creator_id, 159 const String& url, 160 const ViewId& root_id, 161 InterfaceRequest<ServiceProvider> service_provider); 162 163 // Overridden from ServerViewDelegate: 164 virtual void OnViewDestroyed(const ServerView* view) OVERRIDE; 165 virtual void OnWillChangeViewHierarchy(const ServerView* view, 166 const ServerView* new_parent, 167 const ServerView* old_parent) OVERRIDE; 168 virtual void OnViewHierarchyChanged(const ServerView* view, 169 const ServerView* new_parent, 170 const ServerView* old_parent) OVERRIDE; 171 virtual void OnViewBoundsChanged(const ServerView* view, 172 const gfx::Rect& old_bounds, 173 const gfx::Rect& new_bounds) OVERRIDE; 174 virtual void OnViewSurfaceIdChanged(const ServerView* view) OVERRIDE; 175 virtual void OnWillChangeViewVisibility(const ServerView* view) OVERRIDE; 176 177 ApplicationConnection* app_connection_; 178 179 // ID to use for next ViewManagerServiceImpl. 180 ConnectionSpecificId next_connection_id_; 181 182 // Set of ViewManagerServiceImpls. 183 ConnectionMap connection_map_; 184 185 DisplayManager display_manager_; 186 187 scoped_ptr<ServerView> root_; 188 189 // Set of ViewManagerServiceImpls created by way of Connect(). These have to 190 // be explicitly destroyed. 191 std::set<ViewManagerServiceImpl*> connections_created_by_connect_; 192 193 // If non-null we're processing a change. The ScopedChange is not owned by us 194 // (it's created on the stack by ViewManagerServiceImpl). 195 ScopedChange* current_change_; 196 197 DISALLOW_COPY_AND_ASSIGN(ConnectionManager); 198 }; 199 200 } // namespace service 201 } // namespace mojo 202 203 #endif // MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_ 204