| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |