OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef COMPONENTS_WEB_VIEW_FRAME_H_ | |
6 #define COMPONENTS_WEB_VIEW_FRAME_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <map> | |
11 #include <vector> | |
12 | |
13 #include "base/macros.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/time/time.h" | |
16 #include "components/mus/common/types.h" | |
17 #include "components/mus/public/cpp/window_observer.h" | |
18 #include "components/web_view/public/interfaces/frame.mojom.h" | |
19 #include "mojo/public/cpp/bindings/binding.h" | |
20 | |
21 class GURL; | |
22 | |
23 namespace web_view { | |
24 | |
25 class FrameTest; | |
26 class FrameTree; | |
27 class FrameUserData; | |
28 | |
29 namespace mojom { | |
30 class FrameClient; | |
31 } | |
32 | |
33 enum class WindowOwnership { | |
34 OWNS_WINDOW, | |
35 DOESNT_OWN_WINDOW, | |
36 }; | |
37 | |
38 // Frame represents an embedding in a frame. Frames own their children. | |
39 // Frames automatically delete themself if the Window the frame is associated | |
40 // with is deleted. | |
41 // | |
42 // In general each Frame has a Window. When a new Frame is created by a client | |
43 // there may be a small amount of time where the Window is not yet known | |
44 // (separate pipes are used for the window and frame, resulting in undefined | |
45 // message ordering). In this case the window is null and will be set once we | |
46 // see the window (OnTreeChanged()). | |
47 // | |
48 // Each frame has an identifier of the app providing the FrameClient | |
49 // (|app_id|). This id is used when servicing a request to navigate the frame. | |
50 // When navigating, if the id of the new app matches that of the existing app, | |
51 // then it is expected that the new FrameClient will take over rendering to the | |
52 // existing window. Because of this a new WindowTreeClient is not obtained and | |
53 // Embed() is not invoked on the Window. The FrameClient can detect this case by | |
54 // the argument |reuse_existing_view| supplied to OnConnect(). Typically the id | |
55 // is that of content handler id, but this is left up to the FrameTreeDelegate | |
56 // to decide. | |
57 class Frame : public mus::WindowObserver, public mojom::Frame { | |
58 public: | |
59 using ClientPropertyMap = std::map<std::string, std::vector<uint8_t>>; | |
60 using FindCallback = mojo::Callback<void(bool)>; | |
61 | |
62 Frame(FrameTree* tree, | |
63 mus::Window* window, | |
64 uint32_t frame_id, | |
65 uint32_t app_id, | |
66 WindowOwnership window_ownership, | |
67 mojom::FrameClient* frame_client, | |
68 scoped_ptr<FrameUserData> user_data, | |
69 const ClientPropertyMap& client_properties); | |
70 ~Frame() override; | |
71 | |
72 void Init(Frame* parent, | |
73 mus::mojom::WindowTreeClientPtr window_tree_client, | |
74 mojo::InterfaceRequest<mojom::Frame> frame_request, | |
75 base::TimeTicks navigation_start_time); | |
76 | |
77 // Walks the Window tree starting at |window| going up returning the first | |
78 // Frame that is associated with |window|. For example, if |window| | |
79 // has a Frame associated with it, then that is returned. Otherwise | |
80 // this checks window->parent() and so on. | |
81 static Frame* FindFirstFrameAncestor(mus::Window* window); | |
82 | |
83 FrameTree* tree() { return tree_; } | |
84 | |
85 Frame* parent() { return parent_; } | |
86 const Frame* parent() const { return parent_; } | |
87 | |
88 mus::Window* window() { return window_; } | |
89 const mus::Window* window() const { return window_; } | |
90 | |
91 uint32_t id() const { return id_; } | |
92 | |
93 uint32_t app_id() const { return app_id_; } | |
94 | |
95 bool loading() const { return loading_; } | |
96 | |
97 const ClientPropertyMap& client_properties() const { | |
98 return client_properties_; | |
99 } | |
100 | |
101 // Finds the descendant with the specified id. | |
102 Frame* FindFrame(uint32_t id) { | |
103 return const_cast<Frame*>(const_cast<const Frame*>(this)->FindFrame(id)); | |
104 } | |
105 const Frame* FindFrame(uint32_t id) const; | |
106 | |
107 bool HasAncestor(const Frame* frame) const; | |
108 | |
109 FrameUserData* user_data() { return user_data_.get(); } | |
110 | |
111 const std::vector<Frame*>& children() const { return children_; } | |
112 | |
113 // Returns true if this Frame or any child Frame is loading. | |
114 bool IsLoading() const; | |
115 | |
116 // Returns the sum total of loading progress from this Frame and all of its | |
117 // children, as well as the number of Frames accumulated. | |
118 double GatherProgress(int* frame_count) const; | |
119 | |
120 void Find(int32_t request_id, | |
121 const mojo::String& search_text, | |
122 mojom::FindOptionsPtr options, | |
123 bool wrap_within_frame, | |
124 const FindCallback& callback); | |
125 void StopFinding(bool clear_selection); | |
126 void HighlightFindResults(int32_t request_id, | |
127 const mojo::String& search_text, | |
128 mojom::FindOptionsPtr options, | |
129 bool reset); | |
130 void StopHighlightingFindResults(); | |
131 | |
132 private: | |
133 friend class FrameTest; | |
134 friend class FrameTree; | |
135 | |
136 // Identifies whether the FrameClient is from the same app or a different | |
137 // app. | |
138 enum class ClientType { | |
139 // The client is either the root frame, or navigating an existing frame | |
140 // to a different app. | |
141 EXISTING_FRAME_NEW_APP, | |
142 | |
143 // The client is the result of navigating an existing frame in the same | |
144 // app. | |
145 EXISTING_FRAME_SAME_APP, | |
146 | |
147 // The client is the result of a new frame (not the root). | |
148 NEW_CHILD_FRAME | |
149 }; | |
150 | |
151 struct FrameUserDataAndBinding; | |
152 | |
153 // Initializes the client by sending it the state of the tree. | |
154 // |data_and_binding| contains the current FrameUserDataAndBinding (if any) | |
155 // and is destroyed after the connection responds to OnConnect(). | |
156 // | |
157 // If |client_type| is SAME_APP we can't destroy the existing client | |
158 // (and related data) until we get back the ack from OnConnect(). This way | |
159 // we know the client has completed the switch. If we did not do this it | |
160 // would be possible for the app to see it's existing Frame connection lost | |
161 // (and assume the frame is being torn down) before the OnConnect(). | |
162 void InitClient(ClientType client_type, | |
163 scoped_ptr<FrameUserDataAndBinding> data_and_binding, | |
164 mus::mojom::WindowTreeClientPtr window_tree_client, | |
165 mojo::InterfaceRequest<mojom::Frame> frame_request, | |
166 base::TimeTicks navigation_start_time); | |
167 | |
168 // Callback from OnConnect(). This does nothing (other than destroying | |
169 // |data_and_binding|). See InitClient() for details as to why destruction of | |
170 // |data_and_binding| happens after OnConnect(). | |
171 static void OnConnectAck( | |
172 scoped_ptr<FrameUserDataAndBinding> data_and_binding); | |
173 | |
174 // Callback from OnEmbed(). | |
175 void OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id); | |
176 | |
177 // Callback from Frame::OnWillNavigate(). Completes navigation. | |
178 void OnWillNavigateAck(mojom::FrameClient* frame_client, | |
179 scoped_ptr<FrameUserData> user_data, | |
180 mus::mojom::WindowTreeClientPtr window_tree_client, | |
181 uint32_t app_id, | |
182 base::TimeTicks navigation_start_time); | |
183 | |
184 // Completes a navigation request; swapping the existing FrameClient to the | |
185 // supplied arguments. | |
186 void ChangeClient(mojom::FrameClient* frame_client, | |
187 scoped_ptr<FrameUserData> user_data, | |
188 mus::mojom::WindowTreeClientPtr window_tree_client, | |
189 uint32_t app_id, | |
190 base::TimeTicks navigation_start_time); | |
191 | |
192 void SetWindow(mus::Window* window); | |
193 | |
194 // Adds this to |frames| and recurses through the children calling the | |
195 // same function. | |
196 void BuildFrameTree(std::vector<const Frame*>* frames) const; | |
197 | |
198 void Add(Frame* node); | |
199 void Remove(Frame* node); | |
200 | |
201 // Starts a new navigation to |request|. The navigation proceeds as long | |
202 // as there is a Window and once OnWillNavigate() has returned. If there is | |
203 // no Window the navigation waits until the Window is available. | |
204 void StartNavigate(mojo::URLRequestPtr request); | |
205 void OnCanNavigateFrame(const GURL& url, | |
206 base::TimeTicks navigation_start_time, | |
207 uint32_t app_id, | |
208 mojom::FrameClient* frame_client, | |
209 scoped_ptr<FrameUserData> user_data, | |
210 mus::mojom::WindowTreeClientPtr window_tree_client); | |
211 | |
212 // Notifies the client and all descendants as appropriate. | |
213 void NotifyAdded(const Frame* source, | |
214 const Frame* added_node, | |
215 uint32_t change_id); | |
216 void NotifyRemoved(const Frame* source, | |
217 const Frame* removed_node, | |
218 uint32_t change_id); | |
219 void NotifyClientPropertyChanged(const Frame* source, | |
220 const mojo::String& name, | |
221 const mojo::Array<uint8_t>& value); | |
222 void NotifyFrameLoadingStateChanged(const Frame* frame, bool loading); | |
223 void NotifyDispatchFrameLoadEvent(const Frame* frame); | |
224 | |
225 // mus::WindowObserver: | |
226 void OnTreeChanged(const TreeChangeParams& params) override; | |
227 void OnWindowDestroying(mus::Window* window) override; | |
228 void OnWindowEmbeddedAppDisconnected(mus::Window* window) override; | |
229 | |
230 // mojom::Frame: | |
231 void PostMessageEventToFrame(uint32_t target_frame_id, | |
232 mojom::HTMLMessageEventPtr event) override; | |
233 void LoadingStateChanged(bool loading, double progress) override; | |
234 void TitleChanged(const mojo::String& title) override; | |
235 void DidCommitProvisionalLoad() override; | |
236 void SetClientProperty(const mojo::String& name, | |
237 mojo::Array<uint8_t> value) override; | |
238 void OnCreatedFrame( | |
239 mojo::InterfaceRequest<mojom::Frame> frame_request, | |
240 mojom::FrameClientPtr client, | |
241 uint32_t frame_id, | |
242 mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties) override; | |
243 void RequestNavigate(mojom::NavigationTargetType target_type, | |
244 uint32_t target_frame_id, | |
245 mojo::URLRequestPtr request) override; | |
246 void DidNavigateLocally(const mojo::String& url) override; | |
247 void DispatchLoadEventToParent() override; | |
248 void OnFindInFrameCountUpdated(int32_t request_id, | |
249 int32_t count, | |
250 bool final_update) override; | |
251 void OnFindInPageSelectionUpdated(int32_t request_id, | |
252 int32_t active_match_ordinal) override; | |
253 | |
254 FrameTree* const tree_; | |
255 // WARNING: this may be null. See class description for details. | |
256 mus::Window* window_; | |
257 // The connection id returned from WindowManager::Embed(). Frames created by | |
258 // way of OnCreatedFrame() inherit the id from the parent. | |
259 mus::ConnectionSpecificId embedded_connection_id_; | |
260 // ID for the frame, which is the same as that of the window. | |
261 const uint32_t id_; | |
262 // ID of the app providing the FrameClient and WindowTreeClient. | |
263 uint32_t app_id_; | |
264 Frame* parent_; | |
265 WindowOwnership window_ownership_; | |
266 std::vector<Frame*> children_; | |
267 scoped_ptr<FrameUserData> user_data_; | |
268 | |
269 mojom::FrameClient* frame_client_; | |
270 | |
271 bool loading_; | |
272 double progress_; | |
273 | |
274 ClientPropertyMap client_properties_; | |
275 | |
276 // StartNavigate() stores the request here if the window isn't available at | |
277 // the time of StartNavigate(). | |
278 mojo::URLRequestPtr pending_navigate_; | |
279 | |
280 scoped_ptr<mojo::Binding<mojom::Frame>> frame_binding_; | |
281 | |
282 // True if waiting on callback from FrameClient::OnWillNavigate(). | |
283 bool waiting_for_on_will_navigate_ack_; | |
284 | |
285 base::WeakPtrFactory<Frame> embed_weak_ptr_factory_; | |
286 | |
287 base::WeakPtrFactory<Frame> navigate_weak_ptr_factory_; | |
288 | |
289 DISALLOW_COPY_AND_ASSIGN(Frame); | |
290 }; | |
291 | |
292 } // namespace web_view | |
293 | |
294 #endif // COMPONENTS_WEB_VIEW_FRAME_H_ | |
OLD | NEW |