| 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |