• 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_VIEW_MANAGER_SERVICE_IMPL_H_
6 #define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_SERVICE_IMPL_H_
7 
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/containers/hash_tables.h"
15 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
16 #include "mojo/services/view_manager/ids.h"
17 #include "mojo/services/view_manager/node_delegate.h"
18 #include "mojo/services/view_manager/view_manager_export.h"
19 
20 namespace gfx {
21 class Rect;
22 }
23 
24 namespace mojo {
25 namespace view_manager {
26 namespace service {
27 
28 class Node;
29 class RootNodeManager;
30 class View;
31 
32 #if defined(OS_WIN)
33 // Equivalent of NON_EXPORTED_BASE which does not work with the template snafu
34 // below.
35 #pragma warning(push)
36 #pragma warning(disable : 4275)
37 #endif
38 
39 // Manages a connection from the client.
40 class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl
41     : public InterfaceImpl<ViewManagerService>,
42       public NodeDelegate {
43  public:
44   ViewManagerServiceImpl(RootNodeManager* root_node_manager,
45                          ConnectionSpecificId creator_id,
46                          const std::string& creator_url,
47                          const std::string& url);
48   virtual ~ViewManagerServiceImpl();
49 
50   // Used to mark this connection as originating from a call to
51   // ViewManagerService::Connect(). When set OnConnectionError() deletes |this|.
set_delete_on_connection_error()52   void set_delete_on_connection_error() { delete_on_connection_error_ = true; }
53 
id()54   ConnectionSpecificId id() const { return id_; }
creator_id()55   ConnectionSpecificId creator_id() const { return creator_id_; }
url()56   const std::string& url() const { return url_; }
57 
58   // Returns the Node with the specified id.
GetNode(const NodeId & id)59   Node* GetNode(const NodeId& id) {
60     return const_cast<Node*>(
61         const_cast<const ViewManagerServiceImpl*>(this)->GetNode(id));
62   }
63   const Node* GetNode(const NodeId& id) const;
64 
65   // Returns the View with the specified id.
GetView(const ViewId & id)66   View* GetView(const ViewId& id) {
67     return const_cast<View*>(
68         const_cast<const ViewManagerServiceImpl*>(this)->GetView(id));
69   }
70   const View* GetView(const ViewId& id) const;
71 
72   void SetRoots(const Array<Id>& node_ids);
73 
74   // Invoked when a connection is destroyed.
75   void OnViewManagerServiceImplDestroyed(ConnectionSpecificId id);
76 
77   // The following methods are invoked after the corresponding change has been
78   // processed. They do the appropriate bookkeeping and update the client as
79   // necessary.
80   void ProcessNodeBoundsChanged(const Node* node,
81                                 const gfx::Rect& old_bounds,
82                                 const gfx::Rect& new_bounds,
83                                 bool originated_change);
84   void ProcessNodeHierarchyChanged(const Node* node,
85                                    const Node* new_parent,
86                                    const Node* old_parent,
87                                    Id server_change_id,
88                                    bool originated_change);
89   void ProcessNodeReorder(const Node* node,
90                           const Node* relative_node,
91                           OrderDirection direction,
92                           Id server_change_id,
93                           bool originated_change);
94   void ProcessNodeViewReplaced(const Node* node,
95                                const View* new_view,
96                                const View* old_view,
97                                bool originated_change);
98   void ProcessNodeDeleted(const NodeId& node,
99                           Id server_change_id,
100                           bool originated_change);
101   void ProcessViewDeleted(const ViewId& view, bool originated_change);
102 
103   // TODO(sky): move this to private section (currently can't because of
104   // bindings).
105   // InterfaceImp overrides:
106   virtual void OnConnectionError() MOJO_OVERRIDE;
107 
108  private:
109   typedef std::map<ConnectionSpecificId, Node*> NodeMap;
110   typedef std::map<ConnectionSpecificId, View*> ViewMap;
111   typedef base::hash_set<Id> NodeIdSet;
112 
113   // These functions return true if the corresponding mojom function is allowed
114   // for this connection.
115   bool CanRemoveNodeFromParent(const Node* node) const;
116   bool CanAddNode(const Node* parent, const Node* child) const;
117   bool CanReorderNode(const Node* node,
118                       const Node* relative_node,
119                       OrderDirection direction) const;
120   bool CanDeleteNode(const NodeId& node_id) const;
121   bool CanDeleteView(const ViewId& view_id) const;
122   bool CanSetView(const Node* node, const ViewId& view_id) const;
123   bool CanSetFocus(const Node* node) const;
124   bool CanGetNodeTree(const Node* node) const;
125   bool CanEmbed(const mojo::Array<uint32_t>& node_ids) const;
126 
127   // Deletes a node owned by this connection. Returns true on success. |source|
128   // is the connection that originated the change.
129   bool DeleteNodeImpl(ViewManagerServiceImpl* source, const NodeId& node_id);
130 
131   // Deletes a view owned by this connection. Returns true on success. |source|
132   // is the connection that originated the change.
133   bool DeleteViewImpl(ViewManagerServiceImpl* source, const ViewId& view_id);
134 
135   // Sets the view associated with a node.
136   bool SetViewImpl(Node* node, const ViewId& view_id);
137 
138   // If |node| is known (in |known_nodes_|) does nothing. Otherwise adds |node|
139   // to |nodes|, marks |node| as known and recurses.
140   void GetUnknownNodesFrom(const Node* node, std::vector<const Node*>* nodes);
141 
142   // Removes |node| and all its descendants from |known_nodes_|. This does not
143   // recurse through nodes that were created by this connection.
144   void RemoveFromKnown(const Node* node);
145 
146   // Adds |node_ids| to roots, returning true if at least one of the nodes was
147   // not already a root. If at least one of the nodes was not already a root
148   // the client is told of the new roots.
149   bool AddRoots(const std::vector<Id>& node_ids);
150 
151   // Returns true if |node| is a non-null and a descendant of |roots_| (or
152   // |roots_| is empty).
153   bool IsNodeDescendantOfRoots(const Node* node) const;
154 
155   // Returns true if notification should be sent of a hierarchy change. If true
156   // is returned, any nodes that need to be sent to the client are added to
157   // |to_send|.
158   bool ShouldNotifyOnHierarchyChange(const Node* node,
159                                      const Node** new_parent,
160                                      const Node** old_parent,
161                                      std::vector<const Node*>* to_send);
162 
163   // Converts an array of Nodes to NodeDatas. This assumes all the nodes are
164   // valid for the client. The parent of nodes the client is not allowed to see
165   // are set to NULL (in the returned NodeDatas).
166   Array<NodeDataPtr> NodesToNodeDatas(const std::vector<const Node*>& nodes);
167 
168   // Overridden from ViewManagerService:
169   virtual void CreateNode(Id transport_node_id,
170                           const Callback<void(bool)>& callback) OVERRIDE;
171   virtual void DeleteNode(Id transport_node_id,
172                           Id server_change_id,
173                           const Callback<void(bool)>& callback) OVERRIDE;
174   virtual void AddNode(Id parent_id,
175                        Id child_id,
176                        Id server_change_id,
177                        const Callback<void(bool)>& callback) OVERRIDE;
178   virtual void RemoveNodeFromParent(
179       Id node_id,
180       Id server_change_id,
181       const Callback<void(bool)>& callback) OVERRIDE;
182   virtual void ReorderNode(Id node_id,
183                            Id relative_node_id,
184                            OrderDirection direction,
185                            Id server_change_id,
186                            const Callback<void(bool)>& callback) OVERRIDE;
187   virtual void GetNodeTree(
188       Id node_id,
189       const Callback<void(Array<NodeDataPtr>)>& callback) OVERRIDE;
190   virtual void CreateView(Id transport_view_id,
191                           const Callback<void(bool)>& callback) OVERRIDE;
192   virtual void DeleteView(Id transport_view_id,
193                           const Callback<void(bool)>& callback) OVERRIDE;
194   virtual void SetView(Id transport_node_id,
195                        Id transport_view_id,
196                        const Callback<void(bool)>& callback) OVERRIDE;
197   virtual void SetViewContents(Id view_id,
198                                ScopedSharedBufferHandle buffer,
199                                uint32_t buffer_size,
200                                const Callback<void(bool)>& callback) OVERRIDE;
201   virtual void SetFocus(Id node_id,
202                         const Callback<void(bool)> & callback) OVERRIDE;
203   virtual void SetNodeBounds(Id node_id,
204                              RectPtr bounds,
205                              const Callback<void(bool)>& callback) OVERRIDE;
206   virtual void Embed(const mojo::String& url,
207                      mojo::Array<uint32_t> node_ids,
208                      const mojo::Callback<void(bool)>& callback) OVERRIDE;
209   virtual void DispatchOnViewInputEvent(Id transport_view_id,
210                                         EventPtr event) OVERRIDE;
211 
212   // Overridden from NodeDelegate:
213   virtual void OnNodeHierarchyChanged(const Node* node,
214                                       const Node* new_parent,
215                                       const Node* old_parent) OVERRIDE;
216   virtual void OnNodeViewReplaced(const Node* node,
217                                   const View* new_view,
218                                   const View* old_view) OVERRIDE;
219   virtual void OnViewInputEvent(const View* view,
220                                 const ui::Event* event) OVERRIDE;
221 
222   // InterfaceImp overrides:
223   virtual void OnConnectionEstablished() MOJO_OVERRIDE;
224 
225   RootNodeManager* root_node_manager_;
226 
227   // Id of this connection as assigned by RootNodeManager.
228   const ConnectionSpecificId id_;
229 
230   // URL this connection was created for.
231   const std::string url_;
232 
233   // ID of the connection that created us. If 0 it indicates either we were
234   // created by the root, or the connection that created us has been destroyed.
235   ConnectionSpecificId creator_id_;
236 
237   // The URL of the app that embedded the app this connection was created for.
238   const std::string creator_url_;
239 
240   NodeMap node_map_;
241 
242   ViewMap view_map_;
243 
244   // The set of nodes that has been communicated to the client.
245   NodeIdSet known_nodes_;
246 
247   // This is the set of nodes the connection can parent nodes to (in addition to
248   // any nodes created by this connection). If empty the connection can
249   // manipulate any nodes (except for deleting other connections nodes/views).
250   // The connection can not delete or move these. If this is set to a non-empty
251   // value and all the nodes are deleted (by another connection), then an
252   // invalid node is added here to ensure this connection is still constrained.
253   NodeIdSet roots_;
254 
255   // See description above setter.
256   bool delete_on_connection_error_;
257 
258   DISALLOW_COPY_AND_ASSIGN(ViewManagerServiceImpl);
259 };
260 
261 #if defined(OS_WIN)
262 #pragma warning(pop)
263 #endif
264 
265 }  // namespace service
266 }  // namespace view_manager
267 }  // namespace mojo
268 
269 #endif  // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_SERVICE_IMPL_H_
270