• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ROOT_NODE_MANAGER_H_
6 #define MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_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/ids.h"
14 #include "mojo/services/view_manager/node.h"
15 #include "mojo/services/view_manager/node_delegate.h"
16 #include "mojo/services/view_manager/root_view_manager.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 ServiceProvider;
26 
27 namespace view_manager {
28 namespace service {
29 
30 class RootViewManagerDelegate;
31 class View;
32 class ViewManagerServiceImpl;
33 
34 // RootNodeManager is responsible for managing the set of
35 // ViewManagerServiceImpls as well as providing the root of the node hierarchy.
36 class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
37  public:
38   // Used to indicate if the server id should be incremented after notifiying
39   // clients of the change.
40   enum ChangeType {
41     CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID,
42     CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID,
43   };
44 
45   // Create when a ViewManagerServiceImpl is about to make a change. Ensures
46   // clients are notified of the correct change id.
47   class ScopedChange {
48    public:
49     ScopedChange(ViewManagerServiceImpl* connection,
50                  RootNodeManager* root,
51                  RootNodeManager::ChangeType change_type,
52                  bool is_delete_node);
53     ~ScopedChange();
54 
connection_id()55     ConnectionSpecificId connection_id() const { return connection_id_; }
change_type()56     ChangeType change_type() const { return change_type_; }
is_delete_node()57     bool is_delete_node() const { return is_delete_node_; }
58 
59     // Marks the connection with the specified id as having seen a message.
MarkConnectionAsMessaged(ConnectionSpecificId connection_id)60     void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) {
61       message_ids_.insert(connection_id);
62     }
63 
64     // Returns true if MarkConnectionAsMessaged(connection_id) was invoked.
DidMessageConnection(ConnectionSpecificId connection_id)65     bool DidMessageConnection(ConnectionSpecificId connection_id) const {
66       return message_ids_.count(connection_id) > 0;
67     }
68 
69    private:
70     RootNodeManager* root_;
71     const ConnectionSpecificId connection_id_;
72     const ChangeType change_type_;
73     const bool is_delete_node_;
74 
75     // See description of MarkConnectionAsMessaged/DidMessageConnection.
76     std::set<ConnectionSpecificId> message_ids_;
77 
78     DISALLOW_COPY_AND_ASSIGN(ScopedChange);
79   };
80 
81   RootNodeManager(ServiceProvider* service_provider,
82                   RootViewManagerDelegate* view_manager_delegate);
83   virtual ~RootNodeManager();
84 
85   // Returns the id for the next ViewManagerServiceImpl.
86   ConnectionSpecificId GetAndAdvanceNextConnectionId();
87 
next_server_change_id()88   Id next_server_change_id() const {
89     return next_server_change_id_;
90   }
91 
92   void AddConnection(ViewManagerServiceImpl* connection);
93   void RemoveConnection(ViewManagerServiceImpl* connection);
94 
95   // Establishes the initial client. Similar to Connect(), but the resulting
96   // client is allowed to do anything.
97   void EmbedRoot(const std::string& url);
98 
99   // See description of ViewManagerService::Embed() for details. This assumes
100   // |node_ids| has been validated.
101   void Embed(ConnectionSpecificId creator_id,
102              const String& url,
103              const Array<Id>& node_ids);
104 
105   // Returns the connection by id.
106   ViewManagerServiceImpl* GetConnection(ConnectionSpecificId connection_id);
107 
108   // Returns the Node identified by |id|.
109   Node* GetNode(const NodeId& id);
110 
111   // Returns the View identified by |id|.
112   View* GetView(const ViewId& id);
113 
root()114   Node* root() { return &root_; }
115 
IsProcessingChange()116   bool IsProcessingChange() const { return current_change_ != NULL; }
117 
is_processing_delete_node()118   bool is_processing_delete_node() const {
119     return current_change_ && current_change_->is_delete_node(); }
120 
121   // Invoked when a connection messages a client about the change. This is used
122   // to avoid sending ServerChangeIdAdvanced() unnecessarily.
123   void OnConnectionMessagedClient(ConnectionSpecificId id);
124 
125   // Returns true if OnConnectionMessagedClient() was invoked for id.
126   bool DidConnectionMessageClient(ConnectionSpecificId id) const;
127 
128   ViewManagerServiceImpl* GetConnectionByCreator(
129       ConnectionSpecificId creator_id,
130       const std::string& url) const;
131 
132   void DispatchViewInputEventToWindowManager(const View* view,
133                                              const ui::Event* event);
134 
135   // These functions trivially delegate to all ViewManagerServiceImpls, which in
136   // term notify their clients.
137   void ProcessNodeBoundsChanged(const Node* node,
138                                 const gfx::Rect& old_bounds,
139                                 const gfx::Rect& new_bounds);
140   void ProcessNodeHierarchyChanged(const Node* node,
141                                    const Node* new_parent,
142                                    const Node* old_parent);
143   void ProcessNodeReorder(const Node* node,
144                           const Node* relative_node,
145                           const OrderDirection direction);
146   void ProcessNodeViewReplaced(const Node* node,
147                                const View* new_view_id,
148                                const View* old_view_id);
149   void ProcessNodeDeleted(const NodeId& node);
150   void ProcessViewDeleted(const ViewId& view);
151 
152  private:
153   // Used to setup any static state needed by RootNodeManager.
154   struct Context {
155     Context();
156     ~Context();
157   };
158 
159   typedef std::map<ConnectionSpecificId, ViewManagerServiceImpl*> ConnectionMap;
160 
161   // Invoked when a connection is about to make a change.  Subsequently followed
162   // by FinishChange() once the change is done.
163   //
164   // Changes should never nest, meaning each PrepareForChange() must be
165   // balanced with a call to FinishChange() with no PrepareForChange()
166   // in between.
167   void PrepareForChange(ScopedChange* change);
168 
169   // Balances a call to PrepareForChange().
170   void FinishChange();
171 
172   // Returns true if the specified connection originated the current change.
IsChangeSource(ConnectionSpecificId connection_id)173   bool IsChangeSource(ConnectionSpecificId connection_id) const {
174     return current_change_ && current_change_->connection_id() == connection_id;
175   }
176 
177   // Implementation of the two embed variants.
178   ViewManagerServiceImpl* EmbedImpl(ConnectionSpecificId creator_id,
179                                    const String& url,
180                                    const Array<Id>& node_ids);
181 
182   // Overridden from NodeDelegate:
183   virtual void OnNodeHierarchyChanged(const Node* node,
184                                       const Node* new_parent,
185                                       const Node* old_parent) OVERRIDE;
186   virtual void OnNodeViewReplaced(const Node* node,
187                                   const View* new_view,
188                                   const View* old_view) OVERRIDE;
189   virtual void OnViewInputEvent(const View* view,
190                                 const ui::Event* event) OVERRIDE;
191 
192   Context context_;
193 
194   ServiceProvider* service_provider_;
195 
196   // ID to use for next ViewManagerServiceImpl.
197   ConnectionSpecificId next_connection_id_;
198 
199   Id next_server_change_id_;
200 
201   // Set of ViewManagerServiceImpls.
202   ConnectionMap connection_map_;
203 
204   RootViewManager root_view_manager_;
205 
206   // Root node.
207   Node root_;
208 
209   // Set of ViewManagerServiceImpls created by way of Connect(). These have to
210   // be explicitly destroyed.
211   std::set<ViewManagerServiceImpl*> connections_created_by_connect_;
212 
213   // If non-null we're processing a change. The ScopedChange is not owned by us
214   // (it's created on the stack by ViewManagerServiceImpl).
215   ScopedChange* current_change_;
216 
217   DISALLOW_COPY_AND_ASSIGN(RootNodeManager);
218 };
219 
220 }  // namespace service
221 }  // namespace view_manager
222 }  // namespace mojo
223 
224 #endif  // MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_
225