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 #include "components/web_view/web_view_impl.h" | |
6 | |
7 #include <queue> | |
8 #include <utility> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/command_line.h" | |
12 #include "components/mus/public/cpp/scoped_window_ptr.h" | |
13 #include "components/mus/public/cpp/window.h" | |
14 #include "components/mus/public/cpp/window_tree_connection.h" | |
15 #include "components/web_view/client_initiated_frame_connection.h" | |
16 #include "components/web_view/frame.h" | |
17 #include "components/web_view/frame_connection.h" | |
18 #include "components/web_view/frame_devtools_agent.h" | |
19 #include "components/web_view/frame_tree.h" | |
20 #include "components/web_view/navigation_entry.h" | |
21 #include "components/web_view/pending_web_view_load.h" | |
22 #include "components/web_view/url_request_cloneable.h" | |
23 #include "mojo/converters/geometry/geometry_type_converters.h" | |
24 #include "mojo/shell/public/cpp/shell.h" | |
25 #include "url/gurl.h" | |
26 | |
27 namespace web_view { | |
28 | |
29 using web_view::mojom::ButtonState; | |
30 | |
31 //////////////////////////////////////////////////////////////////////////////// | |
32 // WebViewImpl, public: | |
33 | |
34 WebViewImpl::WebViewImpl(mojo::Shell* shell, | |
35 mojom::WebViewClientPtr client, | |
36 mojo::InterfaceRequest<mojom::WebView> request) | |
37 : shell_(shell), | |
38 client_(std::move(client)), | |
39 binding_(this, std::move(request)), | |
40 root_(nullptr), | |
41 content_(nullptr), | |
42 find_controller_(this), | |
43 navigation_controller_(this) { | |
44 devtools_agent_.reset(new FrameDevToolsAgent(shell_, this)); | |
45 OnDidNavigate(); | |
46 } | |
47 | |
48 WebViewImpl::~WebViewImpl() { | |
49 if (content_) | |
50 content_->RemoveObserver(this); | |
51 if (root_) { | |
52 root_->RemoveObserver(this); | |
53 mus::ScopedWindowPtr::DeleteWindowOrWindowManager(root_); | |
54 } | |
55 } | |
56 | |
57 void WebViewImpl::OnLoad(const GURL& pending_url) { | |
58 // Frames are uniqued based on the id of the associated Window. By creating a | |
59 // new Window each time through we ensure the renderers get a clean id, rather | |
60 // than one they may know about and try to incorrectly use. | |
61 if (content_) { | |
62 content_->Destroy(); | |
63 DCHECK(!content_); | |
64 } | |
65 | |
66 client_->TopLevelNavigationStarted(pending_url.spec()); | |
67 | |
68 content_ = root_->connection()->NewWindow(); | |
69 content_->SetBounds(gfx::Rect(root_->bounds().size())); | |
70 root_->AddChild(content_); | |
71 content_->SetVisible(true); | |
72 content_->AddObserver(this); | |
73 | |
74 scoped_ptr<PendingWebViewLoad> pending_load(std::move(pending_load_)); | |
75 scoped_ptr<FrameConnection> frame_connection( | |
76 pending_load->frame_connection()); | |
77 mus::mojom::WindowTreeClientPtr window_tree_client = | |
78 frame_connection->GetWindowTreeClient(); | |
79 | |
80 Frame::ClientPropertyMap client_properties; | |
81 if (devtools_agent_) { | |
82 devtools_service::DevToolsAgentPtr forward_agent; | |
83 frame_connection->connection()->ConnectToService(&forward_agent); | |
84 devtools_agent_->AttachFrame(std::move(forward_agent), &client_properties); | |
85 } | |
86 | |
87 mojom::FrameClient* frame_client = frame_connection->frame_client(); | |
88 const uint32_t content_handler_id = frame_connection->GetContentHandlerID(); | |
89 frame_tree_.reset( | |
90 new FrameTree(content_handler_id, content_, std::move(window_tree_client), | |
91 this, frame_client, std::move(frame_connection), | |
92 client_properties, pending_load->navigation_start_time())); | |
93 } | |
94 | |
95 void WebViewImpl::PreOrderDepthFirstTraverseTree(Frame* node, | |
96 std::vector<Frame*>* output) { | |
97 output->push_back(node); | |
98 for (Frame* child : node->children()) | |
99 PreOrderDepthFirstTraverseTree(child, output); | |
100 } | |
101 | |
102 //////////////////////////////////////////////////////////////////////////////// | |
103 // WebViewImpl, WebView implementation: | |
104 | |
105 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request) { | |
106 navigation_controller_.LoadURL(std::move(request)); | |
107 } | |
108 | |
109 void WebViewImpl::GetWindowTreeClient( | |
110 mojo::InterfaceRequest<mus::mojom::WindowTreeClient> window_tree_client) { | |
111 mus::WindowTreeConnection::Create( | |
112 this, std::move(window_tree_client), | |
113 mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); | |
114 } | |
115 | |
116 void WebViewImpl::Find(const mojo::String& search_text, | |
117 bool forward_direction) { | |
118 find_controller_.Find(search_text.To<std::string>(), forward_direction); | |
119 } | |
120 | |
121 void WebViewImpl::StopFinding() { | |
122 find_controller_.StopFinding(); | |
123 } | |
124 | |
125 void WebViewImpl::GoBack() { | |
126 if (!navigation_controller_.CanGoBack()) | |
127 return; | |
128 navigation_controller_.GoBack(); | |
129 } | |
130 | |
131 void WebViewImpl::GoForward() { | |
132 if (!navigation_controller_.CanGoForward()) | |
133 return; | |
134 navigation_controller_.GoForward(); | |
135 } | |
136 | |
137 //////////////////////////////////////////////////////////////////////////////// | |
138 // WebViewImpl, mus::WindowTreeDelegate implementation: | |
139 | |
140 void WebViewImpl::OnEmbed(mus::Window* root) { | |
141 // We must have been granted embed root priviledges, otherwise we can't | |
142 // Embed() in any descendants. | |
143 DCHECK(root->connection()->IsEmbedRoot()); | |
144 root->AddObserver(this); | |
145 root_ = root; | |
146 | |
147 if (pending_load_ && pending_load_->is_content_handler_id_valid()) | |
148 OnLoad(pending_load_->pending_url()); | |
149 } | |
150 | |
151 void WebViewImpl::OnConnectionLost(mus::WindowTreeConnection* connection) { | |
152 root_ = nullptr; | |
153 } | |
154 | |
155 //////////////////////////////////////////////////////////////////////////////// | |
156 // WebViewImpl, mus::WindowObserver implementation: | |
157 | |
158 void WebViewImpl::OnWindowBoundsChanged(mus::Window* window, | |
159 const gfx::Rect& old_bounds, | |
160 const gfx::Rect& new_bounds) { | |
161 if (window != content_ && content_) | |
162 content_->SetBounds(gfx::Rect(new_bounds.size())); | |
163 } | |
164 | |
165 void WebViewImpl::OnWindowDestroyed(mus::Window* window) { | |
166 // |FrameTree| cannot outlive the content window. | |
167 if (window == content_) { | |
168 frame_tree_.reset(); | |
169 content_ = nullptr; | |
170 } | |
171 } | |
172 | |
173 //////////////////////////////////////////////////////////////////////////////// | |
174 // WebViewImpl, FrameTreeDelegate implementation: | |
175 | |
176 scoped_ptr<FrameUserData> WebViewImpl::CreateUserDataForNewFrame( | |
177 mojom::FrameClientPtr frame_client) { | |
178 return make_scoped_ptr( | |
179 new ClientInitiatedFrameConnection(std::move(frame_client))); | |
180 } | |
181 | |
182 bool WebViewImpl::CanPostMessageEventToFrame(const Frame* source, | |
183 const Frame* target, | |
184 mojom::HTMLMessageEvent* event) { | |
185 return true; | |
186 } | |
187 | |
188 void WebViewImpl::LoadingStateChanged(bool loading, double progress) { | |
189 client_->LoadingStateChanged(loading, progress); | |
190 } | |
191 | |
192 void WebViewImpl::TitleChanged(const mojo::String& title) { | |
193 client_->TitleChanged(title); | |
194 } | |
195 | |
196 void WebViewImpl::NavigateTopLevel(Frame* source, mojo::URLRequestPtr request) { | |
197 client_->TopLevelNavigateRequest(std::move(request)); | |
198 } | |
199 | |
200 void WebViewImpl::CanNavigateFrame(Frame* target, | |
201 mojo::URLRequestPtr request, | |
202 const CanNavigateFrameCallback& callback) { | |
203 FrameConnection::CreateConnectionForCanNavigateFrame( | |
204 shell_, target, std::move(request), callback); | |
205 } | |
206 | |
207 void WebViewImpl::DidStartNavigation(Frame* frame) {} | |
208 | |
209 void WebViewImpl::DidCommitProvisionalLoad(Frame* frame) { | |
210 navigation_controller_.FrameDidCommitProvisionalLoad(frame); | |
211 } | |
212 | |
213 void WebViewImpl::DidNavigateLocally(Frame* source, | |
214 const GURL& url) { | |
215 navigation_controller_.FrameDidNavigateLocally(source, url); | |
216 if (source == frame_tree_->root()) | |
217 client_->TopLevelNavigationStarted(url.spec()); | |
218 } | |
219 | |
220 void WebViewImpl::DidDestroyFrame(Frame* frame) { | |
221 find_controller_.DidDestroyFrame(frame); | |
222 } | |
223 | |
224 void WebViewImpl::OnFindInFrameCountUpdated(int32_t request_id, | |
225 Frame* frame, | |
226 int32_t count, | |
227 bool final_update) { | |
228 find_controller_.OnFindInFrameCountUpdated(request_id, frame, count, | |
229 final_update); | |
230 } | |
231 | |
232 void WebViewImpl::OnFindInPageSelectionUpdated(int32_t request_id, | |
233 Frame* frame, | |
234 int32_t active_match_ordinal) { | |
235 find_controller_.OnFindInPageSelectionUpdated(request_id, frame, | |
236 active_match_ordinal); | |
237 } | |
238 | |
239 //////////////////////////////////////////////////////////////////////////////// | |
240 // WebViewImpl, FrameDevToolsAgentDelegate implementation: | |
241 | |
242 void WebViewImpl::HandlePageNavigateRequest(const GURL& url) { | |
243 mojo::URLRequestPtr request(mojo::URLRequest::New()); | |
244 request->url = url.spec(); | |
245 client_->TopLevelNavigateRequest(std::move(request)); | |
246 } | |
247 | |
248 //////////////////////////////////////////////////////////////////////////////// | |
249 // WebViewImpl, NavigationControllerDelegate implementation: | |
250 | |
251 void WebViewImpl::OnNavigate(mojo::URLRequestPtr request) { | |
252 pending_load_.reset(new PendingWebViewLoad(this)); | |
253 pending_load_->Init(std::move(request)); | |
254 } | |
255 | |
256 void WebViewImpl::OnDidNavigate() { | |
257 client_->BackForwardChanged( | |
258 navigation_controller_.CanGoBack() ? ButtonState::ENABLED | |
259 : ButtonState::DISABLED, | |
260 navigation_controller_.CanGoForward() ? ButtonState::ENABLED | |
261 : ButtonState::DISABLED); | |
262 } | |
263 | |
264 //////////////////////////////////////////////////////////////////////////////// | |
265 // WebViewImpl, FindControllerDelegate implementation: | |
266 | |
267 std::vector<Frame*> WebViewImpl::GetAllFrames() { | |
268 std::vector<Frame*> all_frames; | |
269 PreOrderDepthFirstTraverseTree(frame_tree_->root(), &all_frames); | |
270 return all_frames; | |
271 } | |
272 | |
273 mojom::WebViewClient* WebViewImpl::GetWebViewClient() { | |
274 return client_.get(); | |
275 } | |
276 | |
277 } // namespace web_view | |
OLD | NEW |