summaryrefslogtreecommitdiffstats
path: root/components/mus/connection_manager.h
blob: 3aadfc17b030e9d61dd1424b2ce63106b3777509 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_MUS_CONNECTION_MANAGER_H_
#define COMPONENTS_MUS_CONNECTION_MANAGER_H_

#include <map>
#include <set>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "components/mus/focus_controller_delegate.h"
#include "components/mus/ids.h"
#include "components/mus/public/interfaces/view_tree.mojom.h"
#include "components/mus/public/interfaces/view_tree_host.mojom.h"
#include "components/mus/server_view_delegate.h"
#include "components/mus/server_view_observer.h"
#include "components/mus/surfaces/surfaces_state.h"
#include "components/mus/view_tree_host_impl.h"
#include "mojo/converters/surfaces/custom_surface_converter.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/array.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"

namespace view_manager {

class ClientConnection;
class ConnectionManagerDelegate;
class ServerView;
class ViewTreeHostConnection;
class ViewTreeImpl;

// ConnectionManager manages the set of connections to the ViewManager (all the
// ViewTreeImpl) as well as providing the root of the hierarchy.
class ConnectionManager : public ServerViewDelegate,
                          public ServerViewObserver,
                          public mojo::CustomSurfaceConverter {
 public:
  // Create when a ViewTreeImpl is about to make a change. Ensures clients are
  // notified correctly.
  class ScopedChange {
   public:
    ScopedChange(ViewTreeImpl* connection,
                 ConnectionManager* connection_manager,
                 bool is_delete_view);
    ~ScopedChange();

    mojo::ConnectionSpecificId connection_id() const { return connection_id_; }
    bool is_delete_view() const { return is_delete_view_; }

    // Marks the connection with the specified id as having seen a message.
    void MarkConnectionAsMessaged(mojo::ConnectionSpecificId connection_id) {
      message_ids_.insert(connection_id);
    }

    // Returns true if MarkConnectionAsMessaged(connection_id) was invoked.
    bool DidMessageConnection(mojo::ConnectionSpecificId connection_id) const {
      return message_ids_.count(connection_id) > 0;
    }

   private:
    ConnectionManager* connection_manager_;
    const mojo::ConnectionSpecificId connection_id_;
    const bool is_delete_view_;

    // See description of MarkConnectionAsMessaged/DidMessageConnection.
    std::set<mojo::ConnectionSpecificId> message_ids_;

    DISALLOW_COPY_AND_ASSIGN(ScopedChange);
  };

  ConnectionManager(
      ConnectionManagerDelegate* delegate,
      const scoped_refptr<surfaces::SurfacesState>& surfaces_state);
  ~ConnectionManager() override;

  // Adds a ViewTreeHost.
  void AddHost(ViewTreeHostConnection* connection);

  // Creates a new ServerView. The return value is owned by the caller, but must
  // be destroyed before ConnectionManager.
  ServerView* CreateServerView(const ViewId& id);

  // Returns the id for the next ViewTreeImpl.
  mojo::ConnectionSpecificId GetAndAdvanceNextConnectionId();

  // Returns the id for the next ViewTreeHostImpl.
  uint16_t GetAndAdvanceNextHostId();

  // Invoked when a ViewTreeImpl's connection encounters an error.
  void OnConnectionError(ClientConnection* connection);

  // Invoked when a ViewTreeHostBindingOwnerBase's connection encounters an
  // error or the associated Display window is closed.
  void OnHostConnectionClosed(ViewTreeHostConnection* connection);

  // See description of ViewTree::Embed() for details. This assumes
  // |transport_view_id| is valid.
  void EmbedAtView(mojo::ConnectionSpecificId creator_id,
                   const ViewId& view_id,
                   uint32_t policy_bitmask,
                   mojo::URLRequestPtr request);
  ViewTreeImpl* EmbedAtView(mojo::ConnectionSpecificId creator_id,
                            const ViewId& view_id,
                            uint32_t policy_bitmask,
                            mojo::ViewTreeClientPtr client);

  // Returns the connection by id.
  ViewTreeImpl* GetConnection(mojo::ConnectionSpecificId connection_id);

  // Returns the View identified by |id|.
  ServerView* GetView(const ViewId& id);

  // Returns whether |view| is a descendant of some root view but not itself a
  // root view.
  bool IsViewAttachedToRoot(const ServerView* view) const;

  // Schedules a paint for the specified region in the coordinates of |view|.
  void SchedulePaint(const ServerView* view, const gfx::Rect& bounds);

  bool IsProcessingChange() const { return current_change_ != NULL; }

  bool is_processing_delete_view() const {
    return current_change_ && current_change_->is_delete_view();
  }

  // Invoked when the ViewTreeHostImpl's display is closed.
  void OnDisplayClosed();

  // Invoked when a connection messages a client about the change. This is used
  // to avoid sending ServerChangeIdAdvanced() unnecessarily.
  void OnConnectionMessagedClient(mojo::ConnectionSpecificId id);

  // Returns true if OnConnectionMessagedClient() was invoked for id.
  bool DidConnectionMessageClient(mojo::ConnectionSpecificId id) const;

  // Returns the metrics of the viewport where the provided |view| is displayed.
  mojo::ViewportMetricsPtr GetViewportMetricsForView(const ServerView* view);

  // Returns the ViewTreeImpl that has |id| as a root.
  ViewTreeImpl* GetConnectionWithRoot(const ViewId& id) {
    return const_cast<ViewTreeImpl*>(
        const_cast<const ConnectionManager*>(this)->GetConnectionWithRoot(id));
  }
  const ViewTreeImpl* GetConnectionWithRoot(const ViewId& id) const;

  ViewTreeHostImpl* GetViewTreeHostByView(const ServerView* view);
  const ViewTreeHostImpl* GetViewTreeHostByView(const ServerView* view) const;

  // Returns the first ancestor of |service| that is marked as an embed root.
  ViewTreeImpl* GetEmbedRoot(ViewTreeImpl* service);

  // ViewTreeHost implementation helper; see mojom for details.
  bool CloneAndAnimate(const ViewId& view_id);

  // Dispatches |event| directly to the appropriate connection for |view|.
  void DispatchInputEventToView(const ServerView* view, mojo::EventPtr event);

  // These functions trivially delegate to all ViewTreeImpls, which in
  // term notify their clients.
  void ProcessViewDestroyed(ServerView* view);
  void ProcessViewBoundsChanged(const ServerView* view,
                                const gfx::Rect& old_bounds,
                                const gfx::Rect& new_bounds);
  void ProcessViewportMetricsChanged(const mojo::ViewportMetrics& old_metrics,
                                     const mojo::ViewportMetrics& new_metrics);
  void ProcessWillChangeViewHierarchy(const ServerView* view,
                                      const ServerView* new_parent,
                                      const ServerView* old_parent);
  void ProcessViewHierarchyChanged(const ServerView* view,
                                   const ServerView* new_parent,
                                   const ServerView* old_parent);
  void ProcessViewReorder(const ServerView* view,
                          const ServerView* relative_view,
                          const mojo::OrderDirection direction);
  void ProcessViewDeleted(const ViewId& view);

 private:
  using ConnectionMap = std::map<mojo::ConnectionSpecificId, ClientConnection*>;
  using HostConnectionMap =
      std::map<ViewTreeHostImpl*, ViewTreeHostConnection*>;

  // Invoked when a connection is about to make a change.  Subsequently followed
  // by FinishChange() once the change is done.
  //
  // Changes should never nest, meaning each PrepareForChange() must be
  // balanced with a call to FinishChange() with no PrepareForChange()
  // in between.
  void PrepareForChange(ScopedChange* change);

  // Balances a call to PrepareForChange().
  void FinishChange();

  // Returns true if the specified connection originated the current change.
  bool IsChangeSource(mojo::ConnectionSpecificId connection_id) const {
    return current_change_ && current_change_->connection_id() == connection_id;
  }

  // Adds |connection| to internal maps.
  void AddConnection(ClientConnection* connection);

  // Overridden from ServerViewDelegate:
  scoped_ptr<cc::CompositorFrame> UpdateViewTreeFromCompositorFrame(
      const mojo::CompositorFramePtr& input) override;
  surfaces::SurfacesState* GetSurfacesState() override;
  void OnScheduleViewPaint(const ServerView* view) override;
  const ServerView* GetRootView(const ServerView* view) const override;

  // Overridden from ServerViewObserver:
  void OnViewDestroyed(ServerView* view) override;
  void OnWillChangeViewHierarchy(ServerView* view,
                                 ServerView* new_parent,
                                 ServerView* old_parent) override;
  void OnViewHierarchyChanged(ServerView* view,
                              ServerView* new_parent,
                              ServerView* old_parent) override;
  void OnViewBoundsChanged(ServerView* view,
                           const gfx::Rect& old_bounds,
                           const gfx::Rect& new_bounds) override;
  void OnViewReordered(ServerView* view,
                       ServerView* relative,
                       mojo::OrderDirection direction) override;
  void OnWillChangeViewVisibility(ServerView* view) override;
  void OnViewSharedPropertyChanged(
      ServerView* view,
      const std::string& name,
      const std::vector<uint8_t>* new_data) override;
  void OnViewTextInputStateChanged(ServerView* view,
                                   const ui::TextInputState& state) override;

  // Overriden from CustomSurfaceConverter:
  bool ConvertSurfaceDrawQuad(const mojo::QuadPtr& input,
                              const mojo::CompositorFrameMetadataPtr& metadata,
                              cc::SharedQuadState* sqs,
                              cc::RenderPass* render_pass) override;

  ConnectionManagerDelegate* delegate_;

  // State for rendering into a Surface.
  scoped_refptr<surfaces::SurfacesState> surfaces_state_;

  // ID to use for next ViewTreeImpl.
  mojo::ConnectionSpecificId next_connection_id_;

  // ID to use for next ViewTreeHostImpl.
  uint16_t next_host_id_;

  // Set of ViewTreeImpls.
  ConnectionMap connection_map_;

  // Set of ViewTreeHostImpls.
  HostConnectionMap host_connection_map_;

  // If non-null we're processing a change. The ScopedChange is not owned by us
  // (it's created on the stack by ViewTreeImpl).
  ScopedChange* current_change_;

  bool in_destructor_;

  DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
};

}  // namespace view_manager

#endif  // COMPONENTS_MUS_CONNECTION_MANAGER_H_