Home | History | Annotate | Download | only in view_manager
      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 
     55     ConnectionSpecificId connection_id() const { return connection_id_; }
     56     ChangeType change_type() const { return change_type_; }
     57     bool is_delete_node() const { return is_delete_node_; }
     58 
     59     // Marks the connection with the specified id as having seen a message.
     60     void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) {
     61       message_ids_.insert(connection_id);
     62     }
     63 
     64     // Returns true if MarkConnectionAsMessaged(connection_id) was invoked.
     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 
     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 
    114   Node* root() { return &root_; }
    115 
    116   bool IsProcessingChange() const { return current_change_ != NULL; }
    117 
    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.
    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