Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: components/web_view/frame.cc

Issue 1391963004: Correctly record and pass around navigation start time. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/web_view/frame.h ('k') | components/web_view/frame_apptest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/web_view/frame.h" 5 #include "components/web_view/frame.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 if (view_) { 89 if (view_) {
90 view_->ClearLocalProperty(kFrame); 90 view_->ClearLocalProperty(kFrame);
91 if (view_ownership_ == ViewOwnership::OWNS_VIEW) 91 if (view_ownership_ == ViewOwnership::OWNS_VIEW)
92 view_->Destroy(); 92 view_->Destroy();
93 } 93 }
94 tree_->delegate_->DidDestroyFrame(this); 94 tree_->delegate_->DidDestroyFrame(this);
95 } 95 }
96 96
97 void Frame::Init(Frame* parent, 97 void Frame::Init(Frame* parent,
98 mojo::ViewTreeClientPtr view_tree_client, 98 mojo::ViewTreeClientPtr view_tree_client,
99 mojo::InterfaceRequest<mojom::Frame> frame_request) { 99 mojo::InterfaceRequest<mojom::Frame> frame_request,
100 base::TimeTicks navigation_start_time) {
100 { 101 {
101 // Set the FrameClient to null so that we don't notify the client of the 102 // Set the FrameClient to null so that we don't notify the client of the
102 // add before OnConnect(). 103 // add before OnConnect().
103 base::AutoReset<mojom::FrameClient*> frame_client_resetter(&frame_client_, 104 base::AutoReset<mojom::FrameClient*> frame_client_resetter(&frame_client_,
104 nullptr); 105 nullptr);
105 if (parent) 106 if (parent)
106 parent->Add(this); 107 parent->Add(this);
107 } 108 }
108 109
109 const ClientType client_type = frame_request.is_pending() 110 const ClientType client_type = frame_request.is_pending()
110 ? ClientType::NEW_CHILD_FRAME 111 ? ClientType::NEW_CHILD_FRAME
111 : ClientType::EXISTING_FRAME_NEW_APP; 112 : ClientType::EXISTING_FRAME_NEW_APP;
112 InitClient(client_type, nullptr, view_tree_client.Pass(), 113 InitClient(client_type, nullptr, view_tree_client.Pass(),
113 frame_request.Pass()); 114 frame_request.Pass(), navigation_start_time);
114 115
115 tree_->delegate_->DidCreateFrame(this); 116 tree_->delegate_->DidCreateFrame(this);
116 117
117 DVLOG(2) << "Frame id=" << id_ << " parent=" << (parent_ ? parent_->id_ : 0) 118 DVLOG(2) << "Frame id=" << id_ << " parent=" << (parent_ ? parent_->id_ : 0)
118 << " app_id=" << app_id_ << " this=" << this; 119 << " app_id=" << app_id_ << " this=" << this;
119 } 120 }
120 121
121 // static 122 // static
122 Frame* Frame::FindFirstFrameAncestor(View* view) { 123 Frame* Frame::FindFirstFrameAncestor(View* view) {
123 while (view && !view->GetLocalProperty(kFrame)) 124 while (view && !view->GetLocalProperty(kFrame))
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 reset); 184 reset);
184 } 185 }
185 186
186 void Frame::StopHighlightingFindResults() { 187 void Frame::StopHighlightingFindResults() {
187 frame_client_->StopHighlightingFindResults(); 188 frame_client_->StopHighlightingFindResults();
188 } 189 }
189 190
190 void Frame::InitClient(ClientType client_type, 191 void Frame::InitClient(ClientType client_type,
191 scoped_ptr<FrameUserDataAndBinding> data_and_binding, 192 scoped_ptr<FrameUserDataAndBinding> data_and_binding,
192 mojo::ViewTreeClientPtr view_tree_client, 193 mojo::ViewTreeClientPtr view_tree_client,
193 mojo::InterfaceRequest<mojom::Frame> frame_request) { 194 mojo::InterfaceRequest<mojom::Frame> frame_request,
195 base::TimeTicks navigation_start_time) {
194 if (client_type == ClientType::EXISTING_FRAME_NEW_APP && 196 if (client_type == ClientType::EXISTING_FRAME_NEW_APP &&
195 view_tree_client.get()) { 197 view_tree_client.get()) {
196 embedded_connection_id_ = kInvalidConnectionId; 198 embedded_connection_id_ = kInvalidConnectionId;
197 embed_weak_ptr_factory_.InvalidateWeakPtrs(); 199 embed_weak_ptr_factory_.InvalidateWeakPtrs();
198 view_->Embed( 200 view_->Embed(
199 view_tree_client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT, 201 view_tree_client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT,
200 base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr())); 202 base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr()));
201 } 203 }
202 204
203 if (client_type == ClientType::NEW_CHILD_FRAME) { 205 if (client_type == ClientType::NEW_CHILD_FRAME) {
204 // Don't install an error handler. We allow for the target to only 206 // Don't install an error handler. We allow for the target to only
205 // implement ViewTreeClient. 207 // implement ViewTreeClient.
206 // This frame (and client) was created by an existing FrameClient. There 208 // This frame (and client) was created by an existing FrameClient. There
207 // is no need to send it OnConnect(). 209 // is no need to send it OnConnect().
208 frame_binding_.reset( 210 frame_binding_.reset(
209 new mojo::Binding<mojom::Frame>(this, frame_request.Pass())); 211 new mojo::Binding<mojom::Frame>(this, frame_request.Pass()));
210 frame_client_->OnConnect( 212 frame_client_->OnConnect(
211 nullptr, tree_->change_id(), id_, mojom::VIEW_CONNECT_TYPE_USE_NEW, 213 nullptr, tree_->change_id(), id_, mojom::VIEW_CONNECT_TYPE_USE_NEW,
212 mojo::Array<mojom::FrameDataPtr>(), 214 mojo::Array<mojom::FrameDataPtr>(),
215 navigation_start_time.ToInternalValue(),
213 base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); 216 base::Bind(&OnConnectAck, base::Passed(&data_and_binding)));
214 } else { 217 } else {
215 std::vector<const Frame*> frames; 218 std::vector<const Frame*> frames;
216 tree_->root()->BuildFrameTree(&frames); 219 tree_->root()->BuildFrameTree(&frames);
217 220
218 mojo::Array<mojom::FrameDataPtr> array(frames.size()); 221 mojo::Array<mojom::FrameDataPtr> array(frames.size());
219 for (size_t i = 0; i < frames.size(); ++i) 222 for (size_t i = 0; i < frames.size(); ++i)
220 array[i] = FrameToFrameData(frames[i]).Pass(); 223 array[i] = FrameToFrameData(frames[i]).Pass();
221 224
222 mojom::FramePtr frame_ptr; 225 mojom::FramePtr frame_ptr;
223 // Don't install an error handler. We allow for the target to only 226 // Don't install an error handler. We allow for the target to only
224 // implement ViewTreeClient. 227 // implement ViewTreeClient.
225 frame_binding_.reset( 228 frame_binding_.reset(
226 new mojo::Binding<mojom::Frame>(this, GetProxy(&frame_ptr).Pass())); 229 new mojo::Binding<mojom::Frame>(this, GetProxy(&frame_ptr).Pass()));
227 frame_client_->OnConnect( 230 frame_client_->OnConnect(
228 frame_ptr.Pass(), tree_->change_id(), id_, 231 frame_ptr.Pass(), tree_->change_id(), id_,
229 client_type == ClientType::EXISTING_FRAME_SAME_APP 232 client_type == ClientType::EXISTING_FRAME_SAME_APP
230 ? mojom::VIEW_CONNECT_TYPE_USE_EXISTING 233 ? mojom::VIEW_CONNECT_TYPE_USE_EXISTING
231 : mojom::VIEW_CONNECT_TYPE_USE_NEW, 234 : mojom::VIEW_CONNECT_TYPE_USE_NEW,
232 array.Pass(), 235 array.Pass(), navigation_start_time.ToInternalValue(),
233 base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); 236 base::Bind(&OnConnectAck, base::Passed(&data_and_binding)));
234 tree_->delegate_->DidStartNavigation(this); 237 tree_->delegate_->DidStartNavigation(this);
235 238
236 // We need |embedded_connection_id_| is order to validate requests to 239 // We need |embedded_connection_id_| is order to validate requests to
237 // create a child frame (OnCreatedFrame()). Pause incoming methods until 240 // create a child frame (OnCreatedFrame()). Pause incoming methods until
238 // we get the id to prevent race conditions. 241 // we get the id to prevent race conditions.
239 if (embedded_connection_id_ == kInvalidConnectionId) 242 if (embedded_connection_id_ == kInvalidConnectionId)
240 frame_binding_->PauseIncomingMethodCallProcessing(); 243 frame_binding_->PauseIncomingMethodCallProcessing();
241 } 244 }
242 } 245 }
243 246
244 // static 247 // static
245 void Frame::OnConnectAck(scoped_ptr<FrameUserDataAndBinding> data_and_binding) { 248 void Frame::OnConnectAck(scoped_ptr<FrameUserDataAndBinding> data_and_binding) {
246 } 249 }
247 250
248 void Frame::ChangeClient(mojom::FrameClient* frame_client, 251 void Frame::ChangeClient(mojom::FrameClient* frame_client,
249 scoped_ptr<FrameUserData> user_data, 252 scoped_ptr<FrameUserData> user_data,
250 mojo::ViewTreeClientPtr view_tree_client, 253 mojo::ViewTreeClientPtr view_tree_client,
251 uint32_t app_id) { 254 uint32_t app_id,
255 base::TimeTicks navigation_start_time) {
252 while (!children_.empty()) 256 while (!children_.empty())
253 delete children_[0]; 257 delete children_[0];
254 258
255 ClientType client_type = view_tree_client.get() == nullptr 259 ClientType client_type = view_tree_client.get() == nullptr
256 ? ClientType::EXISTING_FRAME_SAME_APP 260 ? ClientType::EXISTING_FRAME_SAME_APP
257 : ClientType::EXISTING_FRAME_NEW_APP; 261 : ClientType::EXISTING_FRAME_NEW_APP;
258 scoped_ptr<FrameUserDataAndBinding> data_and_binding; 262 scoped_ptr<FrameUserDataAndBinding> data_and_binding;
259 263
260 if (client_type == ClientType::EXISTING_FRAME_SAME_APP) { 264 if (client_type == ClientType::EXISTING_FRAME_SAME_APP) {
261 // See comment in InitClient() for details. 265 // See comment in InitClient() for details.
262 data_and_binding.reset(new FrameUserDataAndBinding); 266 data_and_binding.reset(new FrameUserDataAndBinding);
263 data_and_binding->user_data = user_data_.Pass(); 267 data_and_binding->user_data = user_data_.Pass();
264 data_and_binding->frame_binding = frame_binding_.Pass(); 268 data_and_binding->frame_binding = frame_binding_.Pass();
265 } else { 269 } else {
266 loading_ = false; 270 loading_ = false;
267 progress_ = 0.f; 271 progress_ = 0.f;
268 } 272 }
269 273
270 user_data_ = user_data.Pass(); 274 user_data_ = user_data.Pass();
271 frame_client_ = frame_client; 275 frame_client_ = frame_client;
272 frame_binding_.reset(); 276 frame_binding_.reset();
273 app_id_ = app_id; 277 app_id_ = app_id;
274 278
275 InitClient(client_type, data_and_binding.Pass(), view_tree_client.Pass(), 279 InitClient(client_type, data_and_binding.Pass(), view_tree_client.Pass(),
276 nullptr); 280 nullptr, navigation_start_time);
277 } 281 }
278 282
279 void Frame::OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id) { 283 void Frame::OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id) {
280 if (success) 284 if (success)
281 embedded_connection_id_ = connection_id; 285 embedded_connection_id_ = connection_id;
282 if (frame_binding_->is_bound()) 286 if (frame_binding_->is_bound())
283 frame_binding_->ResumeIncomingMethodCallProcessing(); 287 frame_binding_->ResumeIncomingMethodCallProcessing();
284 } 288 }
285 289
286 void Frame::OnWillNavigateAck(mojom::FrameClient* frame_client, 290 void Frame::OnWillNavigateAck(mojom::FrameClient* frame_client,
287 scoped_ptr<FrameUserData> user_data, 291 scoped_ptr<FrameUserData> user_data,
288 mojo::ViewTreeClientPtr view_tree_client, 292 mojo::ViewTreeClientPtr view_tree_client,
289 uint32 app_id) { 293 uint32 app_id,
294 base::TimeTicks navigation_start_time) {
290 DCHECK(waiting_for_on_will_navigate_ack_); 295 DCHECK(waiting_for_on_will_navigate_ack_);
291 DVLOG(2) << "Frame::OnWillNavigateAck id=" << id_; 296 DVLOG(2) << "Frame::OnWillNavigateAck id=" << id_;
292 waiting_for_on_will_navigate_ack_ = false; 297 waiting_for_on_will_navigate_ack_ = false;
293 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id); 298 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id,
299 navigation_start_time);
294 if (pending_navigate_.get()) 300 if (pending_navigate_.get())
295 StartNavigate(pending_navigate_.Pass()); 301 StartNavigate(pending_navigate_.Pass());
296 } 302 }
297 303
298 void Frame::SetView(mus::View* view) { 304 void Frame::SetView(mus::View* view) {
299 DCHECK(!view_); 305 DCHECK(!view_);
300 DCHECK_EQ(id_, view->id()); 306 DCHECK_EQ(id_, view->id());
301 view_ = view; 307 view_ = view;
302 view_->SetLocalProperty(kFrame, this); 308 view_->SetLocalProperty(kFrame, this);
303 view_->AddObserver(this); 309 view_->AddObserver(this);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 pending_navigate_ = request.Pass(); 352 pending_navigate_ = request.Pass();
347 return; 353 return;
348 } 354 }
349 355
350 // Drop any pending navigation requests. 356 // Drop any pending navigation requests.
351 navigate_weak_ptr_factory_.InvalidateWeakPtrs(); 357 navigate_weak_ptr_factory_.InvalidateWeakPtrs();
352 358
353 DVLOG(2) << "Frame::StartNavigate id=" << id_ << " url=" << request->url; 359 DVLOG(2) << "Frame::StartNavigate id=" << id_ << " url=" << request->url;
354 360
355 const GURL requested_url(request->url); 361 const GURL requested_url(request->url);
362 base::TimeTicks navigation_start_time =
363 base::TimeTicks::FromInternalValue(request->originating_time_ticks);
356 tree_->delegate_->CanNavigateFrame( 364 tree_->delegate_->CanNavigateFrame(
357 this, request.Pass(), 365 this, request.Pass(), base::Bind(&Frame::OnCanNavigateFrame,
358 base::Bind(&Frame::OnCanNavigateFrame, 366 navigate_weak_ptr_factory_.GetWeakPtr(),
359 navigate_weak_ptr_factory_.GetWeakPtr(), requested_url)); 367 requested_url, navigation_start_time));
360 } 368 }
361 369
362 void Frame::OnCanNavigateFrame(const GURL& url, 370 void Frame::OnCanNavigateFrame(const GURL& url,
371 base::TimeTicks navigation_start_time,
363 uint32_t app_id, 372 uint32_t app_id,
364 mojom::FrameClient* frame_client, 373 mojom::FrameClient* frame_client,
365 scoped_ptr<FrameUserData> user_data, 374 scoped_ptr<FrameUserData> user_data,
366 mojo::ViewTreeClientPtr view_tree_client) { 375 mojo::ViewTreeClientPtr view_tree_client) {
367 DVLOG(2) << "Frame::OnCanNavigateFrame id=" << id_ 376 DVLOG(2) << "Frame::OnCanNavigateFrame id=" << id_
368 << " equal=" << (AreAppIdsEqual(app_id, app_id_) ? "true" : "false"); 377 << " equal=" << (AreAppIdsEqual(app_id, app_id_) ? "true" : "false");
369 if (AreAppIdsEqual(app_id, app_id_)) { 378 if (AreAppIdsEqual(app_id, app_id_)) {
370 // The app currently rendering the frame will continue rendering it. In this 379 // The app currently rendering the frame will continue rendering it. In this
371 // case we do not use the ViewTreeClient (because the app has a View already 380 // case we do not use the ViewTreeClient (because the app has a View already
372 // and ends up reusing it). 381 // and ends up reusing it).
373 DCHECK(!view_tree_client.get()); 382 DCHECK(!view_tree_client.get());
374 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), 383 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(),
375 app_id); 384 app_id, navigation_start_time);
376 } else { 385 } else {
377 waiting_for_on_will_navigate_ack_ = true; 386 waiting_for_on_will_navigate_ack_ = true;
378 DCHECK(view_tree_client.get()); 387 DCHECK(view_tree_client.get());
379 // TODO(sky): url isn't correct here, it should be a security origin. 388 // TODO(sky): url isn't correct here, it should be a security origin.
380 frame_client_->OnWillNavigate(url.spec(), base::Bind( 389 frame_client_->OnWillNavigate(
381 &Frame::OnWillNavigateAck, base::Unretained(this), frame_client, 390 url.spec(),
382 base::Passed(&user_data), base::Passed(&view_tree_client), app_id)); 391 base::Bind(&Frame::OnWillNavigateAck, base::Unretained(this),
392 frame_client, base::Passed(&user_data),
393 base::Passed(&view_tree_client), app_id,
394 navigation_start_time));
383 } 395 }
384 } 396 }
385 397
386 void Frame::NotifyAdded(const Frame* source, 398 void Frame::NotifyAdded(const Frame* source,
387 const Frame* added_node, 399 const Frame* added_node,
388 uint32_t change_id) { 400 uint32_t change_id) {
389 // |frame_client_| may be null during initial frame creation and parenting. 401 // |frame_client_| may be null during initial frame creation and parenting.
390 if (frame_client_) 402 if (frame_client_)
391 frame_client_->OnFrameAdded(change_id, FrameToFrameData(added_node)); 403 frame_client_->OnFrameAdded(change_id, FrameToFrameData(added_node));
392 404
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 final_update); 588 final_update);
577 } 589 }
578 590
579 void Frame::OnFindInPageSelectionUpdated(int32_t request_id, 591 void Frame::OnFindInPageSelectionUpdated(int32_t request_id,
580 int32_t active_match_ordinal) { 592 int32_t active_match_ordinal) {
581 tree_->delegate_->OnFindInPageSelectionUpdated(request_id, this, 593 tree_->delegate_->OnFindInPageSelectionUpdated(request_id, this,
582 active_match_ordinal); 594 active_match_ordinal);
583 } 595 }
584 596
585 } // namespace web_view 597 } // namespace web_view
OLDNEW
« no previous file with comments | « components/web_view/frame.h ('k') | components/web_view/frame_apptest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698