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

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
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 frame_client_->HighlightFindResults(request_id, search_text, reset); 179 frame_client_->HighlightFindResults(request_id, search_text, reset);
179 } 180 }
180 181
181 void Frame::StopHighlightingFindResults() { 182 void Frame::StopHighlightingFindResults() {
182 frame_client_->StopHighlightingFindResults(); 183 frame_client_->StopHighlightingFindResults();
183 } 184 }
184 185
185 void Frame::InitClient(ClientType client_type, 186 void Frame::InitClient(ClientType client_type,
186 scoped_ptr<FrameUserDataAndBinding> data_and_binding, 187 scoped_ptr<FrameUserDataAndBinding> data_and_binding,
187 mojo::ViewTreeClientPtr view_tree_client, 188 mojo::ViewTreeClientPtr view_tree_client,
188 mojo::InterfaceRequest<mojom::Frame> frame_request) { 189 mojo::InterfaceRequest<mojom::Frame> frame_request,
190 base::TimeTicks navigation_start_time) {
189 if (client_type == ClientType::EXISTING_FRAME_NEW_APP && 191 if (client_type == ClientType::EXISTING_FRAME_NEW_APP &&
190 view_tree_client.get()) { 192 view_tree_client.get()) {
191 embedded_connection_id_ = kInvalidConnectionId; 193 embedded_connection_id_ = kInvalidConnectionId;
192 embed_weak_ptr_factory_.InvalidateWeakPtrs(); 194 embed_weak_ptr_factory_.InvalidateWeakPtrs();
193 view_->Embed( 195 view_->Embed(
194 view_tree_client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT, 196 view_tree_client.Pass(), mojo::ViewTree::ACCESS_POLICY_DEFAULT,
195 base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr())); 197 base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr()));
196 } 198 }
197 199
198 if (client_type == ClientType::NEW_CHILD_FRAME) { 200 if (client_type == ClientType::NEW_CHILD_FRAME) {
199 // Don't install an error handler. We allow for the target to only 201 // Don't install an error handler. We allow for the target to only
200 // implement ViewTreeClient. 202 // implement ViewTreeClient.
201 // This frame (and client) was created by an existing FrameClient. There 203 // This frame (and client) was created by an existing FrameClient. There
202 // is no need to send it OnConnect(). 204 // is no need to send it OnConnect().
203 frame_binding_.reset( 205 frame_binding_.reset(
204 new mojo::Binding<mojom::Frame>(this, frame_request.Pass())); 206 new mojo::Binding<mojom::Frame>(this, frame_request.Pass()));
205 frame_client_->OnConnect( 207 frame_client_->OnConnect(
206 nullptr, tree_->change_id(), id_, mojom::VIEW_CONNECT_TYPE_USE_NEW, 208 nullptr, tree_->change_id(), id_, mojom::VIEW_CONNECT_TYPE_USE_NEW,
207 mojo::Array<mojom::FrameDataPtr>(), 209 mojo::Array<mojom::FrameDataPtr>(),
210 navigation_start_time.ToInternalValue(),
208 base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); 211 base::Bind(&OnConnectAck, base::Passed(&data_and_binding)));
209 } else { 212 } else {
210 std::vector<const Frame*> frames; 213 std::vector<const Frame*> frames;
211 tree_->root()->BuildFrameTree(&frames); 214 tree_->root()->BuildFrameTree(&frames);
212 215
213 mojo::Array<mojom::FrameDataPtr> array(frames.size()); 216 mojo::Array<mojom::FrameDataPtr> array(frames.size());
214 for (size_t i = 0; i < frames.size(); ++i) 217 for (size_t i = 0; i < frames.size(); ++i)
215 array[i] = FrameToFrameData(frames[i]).Pass(); 218 array[i] = FrameToFrameData(frames[i]).Pass();
216 219
217 mojom::FramePtr frame_ptr; 220 mojom::FramePtr frame_ptr;
218 // Don't install an error handler. We allow for the target to only 221 // Don't install an error handler. We allow for the target to only
219 // implement ViewTreeClient. 222 // implement ViewTreeClient.
220 frame_binding_.reset( 223 frame_binding_.reset(
221 new mojo::Binding<mojom::Frame>(this, GetProxy(&frame_ptr).Pass())); 224 new mojo::Binding<mojom::Frame>(this, GetProxy(&frame_ptr).Pass()));
222 frame_client_->OnConnect( 225 frame_client_->OnConnect(
223 frame_ptr.Pass(), tree_->change_id(), id_, 226 frame_ptr.Pass(), tree_->change_id(), id_,
224 client_type == ClientType::EXISTING_FRAME_SAME_APP 227 client_type == ClientType::EXISTING_FRAME_SAME_APP
225 ? mojom::VIEW_CONNECT_TYPE_USE_EXISTING 228 ? mojom::VIEW_CONNECT_TYPE_USE_EXISTING
226 : mojom::VIEW_CONNECT_TYPE_USE_NEW, 229 : mojom::VIEW_CONNECT_TYPE_USE_NEW,
227 array.Pass(), 230 array.Pass(), navigation_start_time.ToInternalValue(),
228 base::Bind(&OnConnectAck, base::Passed(&data_and_binding))); 231 base::Bind(&OnConnectAck, base::Passed(&data_and_binding)));
229 tree_->delegate_->DidStartNavigation(this); 232 tree_->delegate_->DidStartNavigation(this);
230 233
231 // We need |embedded_connection_id_| is order to validate requests to 234 // We need |embedded_connection_id_| is order to validate requests to
232 // create a child frame (OnCreatedFrame()). Pause incoming methods until 235 // create a child frame (OnCreatedFrame()). Pause incoming methods until
233 // we get the id to prevent race conditions. 236 // we get the id to prevent race conditions.
234 if (embedded_connection_id_ == kInvalidConnectionId) 237 if (embedded_connection_id_ == kInvalidConnectionId)
235 frame_binding_->PauseIncomingMethodCallProcessing(); 238 frame_binding_->PauseIncomingMethodCallProcessing();
236 } 239 }
237 } 240 }
238 241
239 // static 242 // static
240 void Frame::OnConnectAck(scoped_ptr<FrameUserDataAndBinding> data_and_binding) { 243 void Frame::OnConnectAck(scoped_ptr<FrameUserDataAndBinding> data_and_binding) {
241 } 244 }
242 245
243 void Frame::ChangeClient(mojom::FrameClient* frame_client, 246 void Frame::ChangeClient(mojom::FrameClient* frame_client,
244 scoped_ptr<FrameUserData> user_data, 247 scoped_ptr<FrameUserData> user_data,
245 mojo::ViewTreeClientPtr view_tree_client, 248 mojo::ViewTreeClientPtr view_tree_client,
246 uint32_t app_id) { 249 uint32_t app_id,
250 base::TimeTicks navigation_start_time) {
247 while (!children_.empty()) 251 while (!children_.empty())
248 delete children_[0]; 252 delete children_[0];
249 253
250 ClientType client_type = view_tree_client.get() == nullptr 254 ClientType client_type = view_tree_client.get() == nullptr
251 ? ClientType::EXISTING_FRAME_SAME_APP 255 ? ClientType::EXISTING_FRAME_SAME_APP
252 : ClientType::EXISTING_FRAME_NEW_APP; 256 : ClientType::EXISTING_FRAME_NEW_APP;
253 scoped_ptr<FrameUserDataAndBinding> data_and_binding; 257 scoped_ptr<FrameUserDataAndBinding> data_and_binding;
254 258
255 if (client_type == ClientType::EXISTING_FRAME_SAME_APP) { 259 if (client_type == ClientType::EXISTING_FRAME_SAME_APP) {
256 // See comment in InitClient() for details. 260 // See comment in InitClient() for details.
257 data_and_binding.reset(new FrameUserDataAndBinding); 261 data_and_binding.reset(new FrameUserDataAndBinding);
258 data_and_binding->user_data = user_data_.Pass(); 262 data_and_binding->user_data = user_data_.Pass();
259 data_and_binding->frame_binding = frame_binding_.Pass(); 263 data_and_binding->frame_binding = frame_binding_.Pass();
260 } else { 264 } else {
261 loading_ = false; 265 loading_ = false;
262 progress_ = 0.f; 266 progress_ = 0.f;
263 } 267 }
264 268
265 user_data_ = user_data.Pass(); 269 user_data_ = user_data.Pass();
266 frame_client_ = frame_client; 270 frame_client_ = frame_client;
267 frame_binding_.reset(); 271 frame_binding_.reset();
268 app_id_ = app_id; 272 app_id_ = app_id;
269 273
270 InitClient(client_type, data_and_binding.Pass(), view_tree_client.Pass(), 274 InitClient(client_type, data_and_binding.Pass(), view_tree_client.Pass(),
271 nullptr); 275 nullptr, navigation_start_time);
272 } 276 }
273 277
274 void Frame::OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id) { 278 void Frame::OnEmbedAck(bool success, mus::ConnectionSpecificId connection_id) {
275 if (success) 279 if (success)
276 embedded_connection_id_ = connection_id; 280 embedded_connection_id_ = connection_id;
277 if (frame_binding_->is_bound()) 281 if (frame_binding_->is_bound())
278 frame_binding_->ResumeIncomingMethodCallProcessing(); 282 frame_binding_->ResumeIncomingMethodCallProcessing();
279 } 283 }
280 284
281 void Frame::OnWillNavigateAck(mojom::FrameClient* frame_client, 285 void Frame::OnWillNavigateAck(mojom::FrameClient* frame_client,
282 scoped_ptr<FrameUserData> user_data, 286 scoped_ptr<FrameUserData> user_data,
283 mojo::ViewTreeClientPtr view_tree_client, 287 mojo::ViewTreeClientPtr view_tree_client,
284 uint32 app_id) { 288 uint32 app_id,
289 base::TimeTicks navigation_start_time) {
285 DCHECK(waiting_for_on_will_navigate_ack_); 290 DCHECK(waiting_for_on_will_navigate_ack_);
286 DVLOG(2) << "Frame::OnWillNavigateAck id=" << id_; 291 DVLOG(2) << "Frame::OnWillNavigateAck id=" << id_;
287 waiting_for_on_will_navigate_ack_ = false; 292 waiting_for_on_will_navigate_ack_ = false;
288 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id); 293 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), app_id,
294 navigation_start_time);
289 if (pending_navigate_.get()) 295 if (pending_navigate_.get())
290 StartNavigate(pending_navigate_.Pass()); 296 StartNavigate(pending_navigate_.Pass());
291 } 297 }
292 298
293 void Frame::SetView(mus::View* view) { 299 void Frame::SetView(mus::View* view) {
294 DCHECK(!view_); 300 DCHECK(!view_);
295 DCHECK_EQ(id_, view->id()); 301 DCHECK_EQ(id_, view->id());
296 view_ = view; 302 view_ = view;
297 view_->SetLocalProperty(kFrame, this); 303 view_->SetLocalProperty(kFrame, this);
298 view_->AddObserver(this); 304 view_->AddObserver(this);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 pending_navigate_ = request.Pass(); 347 pending_navigate_ = request.Pass();
342 return; 348 return;
343 } 349 }
344 350
345 // Drop any pending navigation requests. 351 // Drop any pending navigation requests.
346 navigate_weak_ptr_factory_.InvalidateWeakPtrs(); 352 navigate_weak_ptr_factory_.InvalidateWeakPtrs();
347 353
348 DVLOG(2) << "Frame::StartNavigate id=" << id_ << " url=" << request->url; 354 DVLOG(2) << "Frame::StartNavigate id=" << id_ << " url=" << request->url;
349 355
350 const GURL requested_url(request->url); 356 const GURL requested_url(request->url);
357 base::TimeTicks navigation_start_time =
358 base::TimeTicks::FromInternalValue(request->originating_time_ticks);
351 tree_->delegate_->CanNavigateFrame( 359 tree_->delegate_->CanNavigateFrame(
352 this, request.Pass(), 360 this, request.Pass(), base::Bind(&Frame::OnCanNavigateFrame,
353 base::Bind(&Frame::OnCanNavigateFrame, 361 navigate_weak_ptr_factory_.GetWeakPtr(),
354 navigate_weak_ptr_factory_.GetWeakPtr(), requested_url)); 362 requested_url, navigation_start_time));
355 } 363 }
356 364
357 void Frame::OnCanNavigateFrame(const GURL& url, 365 void Frame::OnCanNavigateFrame(const GURL& url,
366 base::TimeTicks navigation_start_time,
358 uint32_t app_id, 367 uint32_t app_id,
359 mojom::FrameClient* frame_client, 368 mojom::FrameClient* frame_client,
360 scoped_ptr<FrameUserData> user_data, 369 scoped_ptr<FrameUserData> user_data,
361 mojo::ViewTreeClientPtr view_tree_client) { 370 mojo::ViewTreeClientPtr view_tree_client) {
362 DVLOG(2) << "Frame::OnCanNavigateFrame id=" << id_ 371 DVLOG(2) << "Frame::OnCanNavigateFrame id=" << id_
363 << " equal=" << (AreAppIdsEqual(app_id, app_id_) ? "true" : "false"); 372 << " equal=" << (AreAppIdsEqual(app_id, app_id_) ? "true" : "false");
364 if (AreAppIdsEqual(app_id, app_id_)) { 373 if (AreAppIdsEqual(app_id, app_id_)) {
365 // The app currently rendering the frame will continue rendering it. In this 374 // The app currently rendering the frame will continue rendering it. In this
366 // case we do not use the ViewTreeClient (because the app has a View already 375 // case we do not use the ViewTreeClient (because the app has a View already
367 // and ends up reusing it). 376 // and ends up reusing it).
368 DCHECK(!view_tree_client.get()); 377 DCHECK(!view_tree_client.get());
369 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(), 378 ChangeClient(frame_client, user_data.Pass(), view_tree_client.Pass(),
370 app_id); 379 app_id, navigation_start_time);
371 } else { 380 } else {
372 waiting_for_on_will_navigate_ack_ = true; 381 waiting_for_on_will_navigate_ack_ = true;
373 DCHECK(view_tree_client.get()); 382 DCHECK(view_tree_client.get());
374 // TODO(sky): url isn't correct here, it should be a security origin. 383 // TODO(sky): url isn't correct here, it should be a security origin.
375 frame_client_->OnWillNavigate(url.spec(), base::Bind( 384 frame_client_->OnWillNavigate(
376 &Frame::OnWillNavigateAck, base::Unretained(this), frame_client, 385 url.spec(),
377 base::Passed(&user_data), base::Passed(&view_tree_client), app_id)); 386 base::Bind(&Frame::OnWillNavigateAck, base::Unretained(this),
387 frame_client, base::Passed(&user_data),
388 base::Passed(&view_tree_client), app_id,
389 navigation_start_time));
378 } 390 }
379 } 391 }
380 392
381 void Frame::NotifyAdded(const Frame* source, 393 void Frame::NotifyAdded(const Frame* source,
382 const Frame* added_node, 394 const Frame* added_node,
383 uint32_t change_id) { 395 uint32_t change_id) {
384 // |frame_client_| may be null during initial frame creation and parenting. 396 // |frame_client_| may be null during initial frame creation and parenting.
385 if (frame_client_) 397 if (frame_client_)
386 frame_client_->OnFrameAdded(change_id, FrameToFrameData(added_node)); 398 frame_client_->OnFrameAdded(change_id, FrameToFrameData(added_node));
387 399
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 final_update); 583 final_update);
572 } 584 }
573 585
574 void Frame::OnFindInPageSelectionUpdated(int32_t request_id, 586 void Frame::OnFindInPageSelectionUpdated(int32_t request_id,
575 int32_t active_match_ordinal) { 587 int32_t active_match_ordinal) {
576 tree_->delegate_->OnFindInPageSelectionUpdated(request_id, this, 588 tree_->delegate_->OnFindInPageSelectionUpdated(request_id, this,
577 active_match_ordinal); 589 active_match_ordinal);
578 } 590 }
579 591
580 } // namespace web_view 592 } // namespace web_view
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698