summaryrefslogtreecommitdiffstats
path: root/components/html_viewer/html_frame_tree_manager.h
blob: 61ea86ffa25662cda46c21f8c3d3e5df0501f215 (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
// Copyright 2015 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_HTML_VIEWER_HTML_FRAME_TREE_MANAGER_H_
#define COMPONENTS_HTML_VIEWER_HTML_FRAME_TREE_MANAGER_H_

#include <map>
#include <set>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "components/web_view/public/interfaces/frame_tree.mojom.h"

namespace blink {
class WebView;
}

namespace mojo {
class View;
}

namespace html_viewer {

class DocumentResourceWaiter;
class GlobalState;
class HTMLFrame;
class HTMLFrameDelegate;
class HTMLFrameTreeManagerObserver;

// HTMLFrameTreeManager is responsible for managing the frames that comprise a
// document. Some of the frames may be remote. HTMLFrameTreeManager updates its
// state in response to changes from the FrameTreeServer, as well as changes
// from the underlying frames. The frame tree has at least one local frame
// that is backed by a mojo::View.
class HTMLFrameTreeManager {
 public:
  // Returns a new HTMLFrame or null if a HTMLFrame does not need to be created.
  // If this returns non-null the caller owns the return value and must call
  // Close() when done.
  static HTMLFrame* CreateFrameAndAttachToTree(
      GlobalState* global_state,
      mojo::View* view,
      scoped_ptr<DocumentResourceWaiter> resource_waiter,
      HTMLFrameDelegate* delegate);

  // Returns the HTMLFrameTreeManager with the specified root id.
  static HTMLFrameTreeManager* FindFrameTreeWithRoot(uint32_t root_frame_id);

  GlobalState* global_state() { return global_state_; }

  blink::WebView* GetWebView();

  // Ever increasing value that is used to identify the state the tree is in.
  // That is, the value increases every time a structural change is made to
  // the tree, eg add or remove.
  uint32_t change_id() const { return change_id_; }

  void AddObserver(HTMLFrameTreeManagerObserver* observer);
  void RemoveObserver(HTMLFrameTreeManagerObserver* observer);

 private:
  friend class HTMLFrame;
  class ChangeIdAdvancedNotifier;
  using TreeMap = std::map<uint32_t, HTMLFrameTreeManager*>;
  using ChangeIDSet = std::set<uint32_t>;

  explicit HTMLFrameTreeManager(GlobalState* global_state);
  ~HTMLFrameTreeManager();

  void Init(HTMLFrameDelegate* delegate,
            mojo::View* local_view,
            const mojo::Array<web_view::FrameDataPtr>& frame_data,
            uint32_t change_id);

  // Creates a Frame per FrameData element in |frame_data|. Returns the root.
  HTMLFrame* BuildFrameTree(
      HTMLFrameDelegate* delegate,
      const mojo::Array<web_view::FrameDataPtr>& frame_data,
      uint32_t local_frame_id,
      mojo::View* local_view);

  // Returns this HTMLFrameTreeManager from |instances_|.
  void RemoveFromInstances();

  // Invoked when a Frame is destroyed.
  void OnFrameDestroyed(HTMLFrame* frame);

  // Call before applying a structure change from the server. |source| is the
  // the source of the change, and |change_id| the id from the server. Returns
  // true if the change should be applied, false otherwise.
  bool PrepareForStructureChange(HTMLFrame* source, uint32_t change_id);

  // Each HTMLFrame delegates FrameTreeClient methods to the
  // HTMLFrameTreeManager the frame is in. HTMLFrameTreeManager only responds
  // to changes from the |local_root_| (this is because each FrameTreeClient
  // sees the same change, and a change only need be processed once).
  void ProcessOnFrameAdded(HTMLFrame* source,
                           uint32_t change_id,
                           web_view::FrameDataPtr frame_data);
  void ProcessOnFrameRemoved(HTMLFrame* source,
                             uint32_t change_id,
                             uint32_t frame_id);
  void ProcessOnFrameClientPropertyChanged(HTMLFrame* source,
                                           uint32_t frame_id,
                                           const mojo::String& name,
                                           mojo::Array<uint8_t> new_data);

  static TreeMap* instances_;

  GlobalState* global_state_;

  HTMLFrame* root_;

  // The |local_root_| is the HTMLFrame that is the highest frame that is
  // local.
  HTMLFrame* local_root_;

  uint32_t change_id_;

  // When a frame is locally removed the id is added here. When the server
  // notifies us we remove from this set. This is done to ensure an add/remove
  // followed by notification from the server doesn't attempt to add the frame
  // back that was locally removed.
  ChangeIDSet pending_remove_ids_;

  // If true, we're in ProcessOnFrameRemoved().
  bool in_process_on_frame_removed_;

  base::ObserverList<HTMLFrameTreeManagerObserver> observers_;

  base::WeakPtrFactory<HTMLFrameTreeManager> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(HTMLFrameTreeManager);
};

}  // namespace html_viewer

#endif  // COMPONENTS_HTML_VIEWER_HTML_FRAME_TREE_MANAGER_H_