Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / components / web_view / frame.h
blob2ce5bb2f26978f22cd1cc638f0333f5f62a55395
1 // Copyright 2015 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.
5 #ifndef COMPONENTS_WEB_VIEW_FRAME_H_
6 #define COMPONENTS_WEB_VIEW_FRAME_H_
8 #include <map>
9 #include <vector>
11 #include "base/basictypes.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "components/mus/public/cpp/types.h"
14 #include "components/mus/public/cpp/view_observer.h"
15 #include "components/web_view/public/interfaces/frame.mojom.h"
16 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
18 namespace web_view {
20 class FrameTest;
21 class FrameTree;
22 class FrameUserData;
24 namespace mojom {
25 class FrameClient;
28 enum class ViewOwnership {
29 OWNS_VIEW,
30 DOESNT_OWN_VIEW,
33 // Frame represents an embedding in a frame. Frames own their children.
34 // Frames automatically delete themself if the View the frame is associated
35 // with is deleted.
37 // In general each Frame has a View. When a new Frame is created by a client
38 // there may be a small amount of time where the View is not yet known
39 // (separate pipes are used for the view and frame, resulting in undefined
40 // message ordering). In this case the view is null and will be set once we
41 // see the view (OnTreeChanged()).
43 // Each frame has an identifier of the app providing the FrameClient
44 // (|app_id|). This id is used when servicing a request to navigate the frame.
45 // When navigating, if the id of the new app matches that of the existing app,
46 // then it is expected that the new FrameClient will take over rendering to the
47 // existing view. Because of this a new ViewTreeClient is not obtained and
48 // Embed() is not invoked on the View. The FrameClient can detect this case by
49 // the argument |reuse_existing_view| supplied to OnConnect(). Typically the id
50 // is that of content handler id, but this is left up to the FrameTreeDelegate
51 // to decide.
52 class Frame : public mus::ViewObserver, public mojom::Frame {
53 public:
54 using ClientPropertyMap = std::map<std::string, std::vector<uint8_t>>;
56 Frame(FrameTree* tree,
57 mus::View* view,
58 uint32_t frame_id,
59 uint32_t app_id,
60 ViewOwnership view_ownership,
61 mojom::FrameClient* frame_client,
62 scoped_ptr<FrameUserData> user_data,
63 const ClientPropertyMap& client_properties);
64 ~Frame() override;
66 void Init(Frame* parent,
67 mojo::ViewTreeClientPtr view_tree_client,
68 mojo::InterfaceRequest<mojom::Frame> frame_request);
70 // Walks the View tree starting at |view| going up returning the first
71 // Frame that is associated with |view|. For example, if |view|
72 // has a Frame associated with it, then that is returned. Otherwise
73 // this checks view->parent() and so on.
74 static Frame* FindFirstFrameAncestor(mus::View* view);
76 FrameTree* tree() { return tree_; }
78 Frame* parent() { return parent_; }
79 const Frame* parent() const { return parent_; }
81 mus::View* view() { return view_; }
82 const mus::View* view() const { return view_; }
84 uint32_t id() const { return id_; }
86 uint32_t app_id() const { return app_id_; }
88 const ClientPropertyMap& client_properties() const {
89 return client_properties_;
92 // Finds the descendant with the specified id.
93 Frame* FindFrame(uint32_t id) {
94 return const_cast<Frame*>(const_cast<const Frame*>(this)->FindFrame(id));
96 const Frame* FindFrame(uint32_t id) const;
98 bool HasAncestor(const Frame* frame) const;
100 FrameUserData* user_data() { return user_data_.get(); }
102 const std::vector<Frame*>& children() const { return children_; }
104 // Returns true if this Frame or any child Frame is loading.
105 bool IsLoading() const;
107 // Returns the sum total of loading progress from this Frame and all of its
108 // children, as well as the number of Frames accumulated.
109 double GatherProgress(int* frame_count) const;
111 private:
112 friend class FrameTest;
113 friend class FrameTree;
115 // Identifies whether the FrameClient is from the same app or a different
116 // app.
117 enum class ClientType {
118 // The client is either the root frame, or navigating an existing frame
119 // to a different app.
120 EXISTING_FRAME_NEW_APP,
122 // The client is the result of navigating an existing frame to a new app.
123 EXISTING_FRAME_SAME_APP,
125 // The client is the result of a new frame (not the root).
126 NEW_CHILD_FRAME
129 struct FrameUserDataAndBinding;
131 // Initializes the client by sending it the state of the tree.
132 // |data_and_binding| contains the current FrameUserDataAndBinding (if any)
133 // and is destroyed after the connection responds to OnConnect().
135 // If |client_type| is SAME_APP we can't destroy the existing client
136 // (and related data) until we get back the ack from OnConnect(). This way
137 // we know the client has completed the switch. If we did not do this it
138 // would be possible for the app to see it's existing Frame connection lost
139 // (and assume the frame is being torn down) before the OnConnect().
140 void InitClient(ClientType client_type,
141 scoped_ptr<FrameUserDataAndBinding> data_and_binding,
142 mojo::ViewTreeClientPtr view_tree_client,
143 mojo::InterfaceRequest<mojom::Frame> frame_request);
145 // Callback from OnConnect(). This does nothing (other than destroying
146 // |data_and_binding|). See InitClient() for details as to why destruction of
147 // |data_and_binding| happens after OnConnect().
148 static void OnConnectAck(
149 scoped_ptr<FrameUserDataAndBinding> data_and_binding);
151 // Callback from OnEmbed().
152 void OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id);
154 // Completes a navigation request; swapping the existing FrameClient to the
155 // supplied arguments.
156 void ChangeClient(mojom::FrameClient* frame_client,
157 scoped_ptr<FrameUserData> user_data,
158 mojo::ViewTreeClientPtr view_tree_client,
159 uint32 app_id);
161 void SetView(mus::View* view);
163 // Adds this to |frames| and recurses through the children calling the
164 // same function.
165 void BuildFrameTree(std::vector<const Frame*>* frames) const;
167 void Add(Frame* node);
168 void Remove(Frame* node);
170 // Starts a new navigation to |request|. The navigation proceeds as long
171 // as there is a View and once OnWillNavigate() has returned. If there is
172 // no View the navigation waits until the View is available.
173 void StartNavigate(mojo::URLRequestPtr request);
174 void OnCanNavigateFrame(uint32_t app_id,
175 mojom::FrameClient* frame_client,
176 scoped_ptr<FrameUserData> user_data,
177 mojo::ViewTreeClientPtr view_tree_client);
179 // Notifies the client and all descendants as appropriate.
180 void NotifyAdded(const Frame* source,
181 const Frame* added_node,
182 uint32_t change_id);
183 void NotifyRemoved(const Frame* source,
184 const Frame* removed_node,
185 uint32_t change_id);
186 void NotifyClientPropertyChanged(const Frame* source,
187 const mojo::String& name,
188 const mojo::Array<uint8_t>& value);
189 void NotifyFrameLoadingStateChanged(const Frame* frame, bool loading);
190 void NotifyDispatchFrameLoadEvent(const Frame* frame);
192 // mus::ViewObserver:
193 void OnTreeChanged(const TreeChangeParams& params) override;
194 void OnViewDestroying(mus::View* view) override;
195 void OnViewEmbeddedAppDisconnected(mus::View* view) override;
197 // mojom::Frame:
198 void PostMessageEventToFrame(uint32_t target_frame_id,
199 mojom::HTMLMessageEventPtr event) override;
200 void LoadingStateChanged(bool loading, double progress) override;
201 void TitleChanged(const mojo::String& title) override;
202 void DidCommitProvisionalLoad() override;
203 void SetClientProperty(const mojo::String& name,
204 mojo::Array<uint8_t> value) override;
205 void OnCreatedFrame(
206 mojo::InterfaceRequest<mojom::Frame> frame_request,
207 mojom::FrameClientPtr client,
208 uint32_t frame_id,
209 mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties) override;
210 void RequestNavigate(mojom::NavigationTargetType target_type,
211 uint32_t target_frame_id,
212 mojo::URLRequestPtr request) override;
213 void DidNavigateLocally(const mojo::String& url) override;
214 void DispatchLoadEventToParent() override;
216 FrameTree* const tree_;
217 // WARNING: this may be null. See class description for details.
218 mus::View* view_;
219 // The connection id returned from ViewManager::Embed(). Frames created by
220 // way of OnCreatedFrame() inherit the id from the parent.
221 mus::ConnectionSpecificId embedded_connection_id_;
222 // ID for the frame, which is the same as that of the view.
223 const uint32_t id_;
224 // ID of the app providing the FrameClient and ViewTreeClient.
225 uint32_t app_id_;
226 Frame* parent_;
227 ViewOwnership view_ownership_;
228 std::vector<Frame*> children_;
229 scoped_ptr<FrameUserData> user_data_;
231 mojom::FrameClient* frame_client_;
233 bool loading_;
234 double progress_;
236 ClientPropertyMap client_properties_;
238 // StartNavigate() stores the request here if the view isn't available at
239 // the time of StartNavigate().
240 mojo::URLRequestPtr pending_navigate_;
242 scoped_ptr<mojo::Binding<mojom::Frame>> frame_binding_;
244 base::WeakPtrFactory<Frame> embed_weak_ptr_factory_;
246 base::WeakPtrFactory<Frame> navigate_weak_ptr_factory_;
248 DISALLOW_COPY_AND_ASSIGN(Frame);
251 } // namespace web_view
253 #endif // COMPONENTS_WEB_VIEW_FRAME_H_