diff options
Diffstat (limited to 'chromium/content')
23 files changed, 277 insertions, 67 deletions
diff --git a/chromium/content/app/strings/translations/content_strings_bn.xtb b/chromium/content/app/strings/translations/content_strings_bn.xtb index 23a7e807f7f..d99fd33af1e 100644 --- a/chromium/content/app/strings/translations/content_strings_bn.xtb +++ b/chromium/content/app/strings/translations/content_strings_bn.xtb @@ -100,7 +100,7 @@ <translation id="5406322316791861025">আকার</translation> <translation id="5453733299334684579">ট্রি আইটেম</translation> <translation id="5466621249238537318">দয়া করে এক বা একাধিক ফাইল নির্বাচন করুন৷</translation> -<translation id="5468998798572797635">পূর্ণ স্ক্রীন বন্ধ করুন</translation> +<translation id="5468998798572797635">পূর্ণ স্ক্রিন বন্ধ করুন</translation> <translation id="5516424706154626233">তারিখ চয়নকারি</translation> <translation id="5537725057119320332">কাস্ট করুন</translation> <translation id="5546461542133609677">সশব্দ</translation> @@ -162,7 +162,7 @@ <translation id="8053789581856978548">অনুসন্ধান পাঠ্য ফিল্ড</translation> <translation id="8115662671911883373">বন্ধ পরিচয়লিপিগুলির প্রদর্শন শুরু করুন</translation> <translation id="8117451130807776954">এই সপ্তাহ</translation> -<translation id="819205353528511139">পূর্ণ স্ক্রীন মোডে চলচ্চিত্র চালান</translation> +<translation id="819205353528511139">পূর্ণ স্ক্রিন মোডে চলচ্চিত্র চালান</translation> <translation id="8199524924445686405">yyyy</translation> <translation id="8284326494547611709">পরিচয়লিপিগুলি</translation> <translation id="835897206747267392">অকার্যকর মান৷</translation> diff --git a/chromium/content/browser/android/overscroll_controller_android_unittest.cc b/chromium/content/browser/android/overscroll_controller_android_unittest.cc index 8750391986b..2745dd1243e 100644 --- a/chromium/content/browser/android/overscroll_controller_android_unittest.cc +++ b/chromium/content/browser/android/overscroll_controller_android_unittest.cc @@ -34,11 +34,7 @@ namespace { class MockCompositor : public WindowAndroidCompositor { public: ~MockCompositor() override {} - base::WeakPtr<ui::WindowAndroidCompositor> GetWeakPtr() override { - return nullptr; - } - void IncrementReadbackRequestCount() override {} - void DecrementReadbackRequestCount() override {} + void AttachLayerForReadback(scoped_refptr<cc::Layer>) override {} void RequestCopyOfOutputOnRootLayer( std::unique_ptr<viz::CopyOutputRequest>) override {} void SetNeedsAnimate() override {} diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.cc b/chromium/content/browser/frame_host/interstitial_page_impl.cc index af9c604d578..94e29b878e1 100644 --- a/chromium/content/browser/frame_host/interstitial_page_impl.cc +++ b/chromium/content/browser/frame_host/interstitial_page_impl.cc @@ -836,6 +836,12 @@ void InterstitialPageImpl::Shutdown() { } void InterstitialPageImpl::OnNavigatingAwayOrTabClosing() { + // Notify the RenderWidgetHostView so it can clean up interstitial resources + // before the WebContents is fully destroyed. + if (render_view_host_ && render_view_host_->GetWidget() && + render_view_host_->GetWidget()->GetView()) { + render_view_host_->GetWidget()->GetView()->OnInterstitialPageGoingAway(); + } if (action_taken_ == NO_ACTION) { // We are navigating away from the interstitial or closing a tab with an // interstitial. Default to DontProceed(). We don't just call Hide as diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc index ee48fdd3405..1462dab7844 100644 --- a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc @@ -7656,6 +7656,43 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, } } +// Regression test for https://crbug.com/845923. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + GoBackFromCrossSiteSubFrame) { + // Navigate to a page with a cross-site frame. + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + GURL initial_subframe_url = + root->child_at(0)->current_frame_host()->GetLastCommittedURL(); + NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( + shell()->web_contents()->GetController()); + EXPECT_EQ(1, controller.GetEntryCount()); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); + + // Navigate the subframe to another cross-site location + // (this prepares for executing history.back() in a later step). + GURL final_subframe_url = + embedded_test_server()->GetURL("b.com", "/title1.html"); + NavigateFrameToURL(root->child_at(0), final_subframe_url); + EXPECT_EQ(final_subframe_url, + root->child_at(0)->current_frame_host()->GetLastCommittedURL()); + EXPECT_EQ(2, controller.GetEntryCount()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + + // Execute |history.back()| in the subframe. + TestNavigationObserver nav_observer(shell()->web_contents(), 1); + EXPECT_TRUE(ExecuteScript(root->child_at(0), "history.back()")); + nav_observer.Wait(); + EXPECT_EQ(initial_subframe_url, + root->child_at(0)->current_frame_host()->GetLastCommittedURL()); + EXPECT_EQ(2, controller.GetEntryCount()); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); +} + IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, HashNavigationVsBeforeUnloadEvent) { GURL main_url(embedded_test_server()->GetURL("/title1.html")); diff --git a/chromium/content/browser/indexed_db/indexed_db_database.cc b/chromium/content/browser/indexed_db/indexed_db_database.cc index fff36197e29..3baba4f2ed7 100644 --- a/chromium/content/browser/indexed_db/indexed_db_database.cc +++ b/chromium/content/browser/indexed_db/indexed_db_database.cc @@ -257,8 +257,6 @@ class IndexedDBDatabase::OpenRequest void UpgradeTransactionFinished(bool committed) override { // Ownership of connection was already passed along in OnUpgradeNeeded. - DCHECK(!connection_); - if (committed) { DCHECK_EQ(pending_->version, db_->metadata_.version); pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(), diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction.cc b/chromium/content/browser/indexed_db/indexed_db_transaction.cc index a0878c2dce7..78ac2ba3600 100644 --- a/chromium/content/browser/indexed_db/indexed_db_transaction.cc +++ b/chromium/content/browser/indexed_db/indexed_db_transaction.cc @@ -111,7 +111,7 @@ IndexedDBTransaction::IndexedDBTransaction( : id_(id), object_store_ids_(object_store_ids), mode_(mode), - connection_(connection), + connection_(connection->GetWeakPtr()), transaction_(backing_store_transaction), ptr_factory_(this) { IDB_ASYNC_TRACE_BEGIN("IndexedDBTransaction::lifetime", this); @@ -222,7 +222,10 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) { database_->TransactionFinished(this, false); // RemoveTransaction will delete |this|. - connection_->RemoveTransaction(id_); + // Note: During force-close situations, the connection can be destroyed during + // the |IndexedDBDatabase::TransactionFinished| call + if (connection_) + connection_->RemoveTransaction(id_); } bool IndexedDBTransaction::IsTaskQueueEmpty() const { diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction.h b/chromium/content/browser/indexed_db/indexed_db_transaction.h index 7196f25943e..fd690bcc345 100644 --- a/chromium/content/browser/indexed_db/indexed_db_transaction.h +++ b/chromium/content/browser/indexed_db/indexed_db_transaction.h @@ -107,7 +107,7 @@ class CONTENT_EXPORT IndexedDBTransaction { IndexedDBDatabase* database() const { return database_.get(); } IndexedDBDatabaseCallbacks* callbacks() const { return callbacks_.get(); } - IndexedDBConnection* connection() const { return connection_; } + IndexedDBConnection* connection() const { return connection_.get(); } State state() const { return state_; } bool IsTimeoutTimerRunning() const { return timeout_timer_.IsRunning(); } @@ -187,8 +187,9 @@ class CONTENT_EXPORT IndexedDBTransaction { bool used_ = false; State state_ = CREATED; bool commit_pending_ = false; - // We are owned by the connection object. - IndexedDBConnection* connection_; + // We are owned by the connection object, but during force closes sometimes + // there are issues if there is a pending OpenRequest. So use a WeakPtr. + base::WeakPtr<IndexedDBConnection> connection_; scoped_refptr<IndexedDBDatabaseCallbacks> callbacks_; scoped_refptr<IndexedDBDatabase> database_; diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc index 6cbf42626e1..8738af74a88 100644 --- a/chromium/content/browser/renderer_host/compositor_impl_android.cc +++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc @@ -544,6 +544,11 @@ void CompositorImpl::SetRootWindow(gfx::NativeWindow root_window) { root_window_ = root_window; root_window_->SetLayer(root_layer ? root_layer : cc::Layer::Create()); root_window_->GetLayer()->SetBounds(size_); + if (!readback_layer_tree_) { + readback_layer_tree_ = cc::Layer::Create(); + readback_layer_tree_->SetHideLayerAndSubtree(true); + } + root_window->GetLayer()->AddChild(readback_layer_tree_); root_window->AttachCompositor(this); if (!host_) { CreateLayerTreeHost(); @@ -923,17 +928,8 @@ void CompositorImpl::DidCommit() { root_window_->OnCompositingDidCommit(); } -base::WeakPtr<ui::WindowAndroidCompositor> CompositorImpl::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -void CompositorImpl::IncrementReadbackRequestCount() { - pending_readback_request_count_++; -} - -void CompositorImpl::DecrementReadbackRequestCount() { - DCHECK_GT(pending_readback_request_count_, 0u); - pending_readback_request_count_--; +void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { + readback_layer_tree_->AddChild(layer); } void CompositorImpl::RequestCopyOfOutputOnRootLayer( @@ -995,7 +991,7 @@ void CompositorImpl::OnDisplayMetricsChanged(const display::Display& display, } bool CompositorImpl::HavePendingReadbacks() { - return pending_readback_request_count_ > 0u; + return !readback_layer_tree_->children().empty(); } std::unique_ptr<ui::CompositorLock> CompositorImpl::GetCompositorLock( diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h index a037726c11d..6b59f095804 100644 --- a/chromium/content/browser/renderer_host/compositor_impl_android.h +++ b/chromium/content/browser/renderer_host/compositor_impl_android.h @@ -122,9 +122,7 @@ class CONTENT_EXPORT CompositorImpl void DidLoseLayerTreeFrameSink() override; // WindowAndroidCompositor implementation. - base::WeakPtr<ui::WindowAndroidCompositor> GetWeakPtr() override; - void IncrementReadbackRequestCount() override; - void DecrementReadbackRequestCount() override; + void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override; void RequestCopyOfOutputOnRootLayer( std::unique_ptr<viz::CopyOutputRequest> request) override; void SetNeedsAnimate() override; @@ -177,6 +175,9 @@ class CONTENT_EXPORT CompositorImpl // is the one attached by the compositor client. scoped_refptr<cc::Layer> subroot_layer_; + // Subtree for hidden layers with CopyOutputRequests on them. + scoped_refptr<cc::Layer> readback_layer_tree_; + // Destruction order matters here: std::unique_ptr<cc::AnimationHost> animation_host_; std::unique_ptr<cc::LayerTreeHost> host_; @@ -215,8 +216,6 @@ class CONTENT_EXPORT CompositorImpl ui::CompositorLockManager lock_manager_; bool has_submitted_frame_since_became_visible_ = false; - unsigned int pending_readback_request_count_ = 0u; - // A task which runs cleanup tasks on low-end Android after a delay. Enqueued // when we hide, canceled when we're shown. base::CancelableOnceClosure low_end_background_cleanup_task_; diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc index acf8f012a83..85864f594da 100644 --- a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc +++ b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc @@ -14,7 +14,7 @@ MouseWheelPhaseHandler::MouseWheelPhaseHandler( RenderWidgetHostViewBase* const host_view) : host_view_(host_view), mouse_wheel_end_dispatch_timeout_(kDefaultMouseWheelLatchingTransaction), - scroll_phase_state_(SCROLL_STATE_UNKNOWN) {} + touchpad_scroll_phase_state_(TOUCHPAD_SCROLL_STATE_UNKNOWN) {} void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent( blink::WebMouseWheelEvent& mouse_wheel_event, @@ -43,8 +43,8 @@ void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent( IgnorePendingWheelEndEvent(); } } else { // !has_phase - switch (scroll_phase_state_) { - case SCROLL_STATE_UNKNOWN: { + switch (touchpad_scroll_phase_state_) { + case TOUCHPAD_SCROLL_STATE_UNKNOWN: { mouse_wheel_event.has_synthetic_phase = true; // Break the latching when the location difference between the current // and the initial wheel event positions exceeds the maximum allowed @@ -75,11 +75,11 @@ void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent( } break; } - case SCROLL_MAY_BEGIN: + case TOUCHPAD_SCROLL_MAY_BEGIN: mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; - scroll_phase_state_ = SCROLL_IN_PROGRESS; + touchpad_scroll_phase_state_ = TOUCHPAD_SCROLL_IN_PROGRESS; break; - case SCROLL_IN_PROGRESS: + case TOUCHPAD_SCROLL_IN_PROGRESS: mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseChanged; break; default: @@ -103,15 +103,15 @@ void MouseWheelPhaseHandler::IgnorePendingWheelEndEvent() { mouse_wheel_end_dispatch_timer_.Stop(); } -void MouseWheelPhaseHandler::ResetScrollSequence() { - scroll_phase_state_ = SCROLL_STATE_UNKNOWN; +void MouseWheelPhaseHandler::ResetTouchpadScrollSequence() { + touchpad_scroll_phase_state_ = TOUCHPAD_SCROLL_STATE_UNKNOWN; } -void MouseWheelPhaseHandler::SendWheelEndIfNeeded() { - if (scroll_phase_state_ == SCROLL_IN_PROGRESS) { +void MouseWheelPhaseHandler::SendWheelEndForTouchpadScrollingIfNeeded() { + if (touchpad_scroll_phase_state_ == TOUCHPAD_SCROLL_IN_PROGRESS) { RenderWidgetHostImpl* widget_host = host_view_->host(); if (!widget_host) { - ResetScrollSequence(); + ResetTouchpadScrollSequence(); return; } @@ -120,11 +120,18 @@ void MouseWheelPhaseHandler::SendWheelEndIfNeeded() { SendSyntheticWheelEventWithPhaseEnded(should_route_event); } - ResetScrollSequence(); + ResetTouchpadScrollSequence(); } -void MouseWheelPhaseHandler::ScrollingMayBegin() { - scroll_phase_state_ = SCROLL_MAY_BEGIN; +void MouseWheelPhaseHandler::TouchpadScrollingMayBegin() { + // End the timer-based wheel scroll sequence before starting a touchpad scroll + // sequence. + if (mouse_wheel_end_dispatch_timer_.IsRunning()) { + DCHECK_EQ(TOUCHPAD_SCROLL_STATE_UNKNOWN, touchpad_scroll_phase_state_); + DispatchPendingWheelEndEvent(); + } + + touchpad_scroll_phase_state_ = TOUCHPAD_SCROLL_MAY_BEGIN; } void MouseWheelPhaseHandler::SendSyntheticWheelEventWithPhaseEnded( @@ -169,7 +176,7 @@ bool MouseWheelPhaseHandler::IsWithinSlopRegion( // This function is called to check if breaking timer-based wheel scroll // latching sequence is needed or not, and timer-based wheel scroll latching // happens only when scroll state is unknown. - DCHECK(scroll_phase_state_ == SCROLL_STATE_UNKNOWN); + DCHECK(touchpad_scroll_phase_state_ == TOUCHPAD_SCROLL_STATE_UNKNOWN); gfx::Vector2dF current_wheel_location(wheel_event.PositionInWidget().x, wheel_event.PositionInWidget().y); return (current_wheel_location - first_wheel_location_).LengthSquared() < @@ -181,7 +188,7 @@ bool MouseWheelPhaseHandler::HasDifferentModifiers( // This function is called to check if breaking timer-based wheel scroll // latching sequence is needed or not, and timer-based wheel scroll latching // happens only when scroll state is unknown. - DCHECK(scroll_phase_state_ == SCROLL_STATE_UNKNOWN); + DCHECK(touchpad_scroll_phase_state_ == TOUCHPAD_SCROLL_STATE_UNKNOWN); return wheel_event.GetModifiers() != initial_wheel_event_.GetModifiers(); } @@ -190,7 +197,7 @@ bool MouseWheelPhaseHandler::ShouldBreakLatchingDueToDirectionChange( // This function is called to check if breaking timer-based wheel scroll // latching sequence is needed or not, and timer-based wheel scroll latching // happens only when scroll state is unknown. - DCHECK(scroll_phase_state_ == SCROLL_STATE_UNKNOWN); + DCHECK(touchpad_scroll_phase_state_ == TOUCHPAD_SCROLL_STATE_UNKNOWN); if (first_scroll_update_ack_state_ != FirstScrollUpdateAckState::kNotConsumed) return false; diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h index 343f8172d85..4f7c03d6293 100644 --- a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h +++ b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h @@ -29,15 +29,18 @@ constexpr base::TimeDelta kMaximumTimeBetweenPhaseEndedAndMomentumPhaseBegan = const double kWheelLatchingSlopRegion = 10.0; // On ChromeOS wheel events don't have phase information; However, whenever the -// user puts down or lifts their fingers a GFC or GFS is received. -enum ScrollPhaseState { +// user puts down their fingers on touchpad a GFC is received and at the end of +// touchpad scrolling when the user lifts their fingers a GFS is received. This +// enum tracks the current state of the touchpad scrolling by listening to GFC +// and GFS events. +enum TouchpadScrollPhaseState { // Scrolling with normal mouse wheels doesn't give any information about the // state of scrolling. - SCROLL_STATE_UNKNOWN = 0, + TOUCHPAD_SCROLL_STATE_UNKNOWN = 0, // Shows that the user has put their fingers down and a scroll may start. - SCROLL_MAY_BEGIN, + TOUCHPAD_SCROLL_MAY_BEGIN, // Scrolling has started and the user hasn't lift their fingers, yet. - SCROLL_IN_PROGRESS, + TOUCHPAD_SCROLL_IN_PROGRESS, }; enum class FirstScrollUpdateAckState { @@ -49,6 +52,9 @@ enum class FirstScrollUpdateAckState { kNotConsumed, }; +// The MouseWheelPhaseHandler is responsible for adding the proper phase to +// wheel events. Phase information is necessary for wheel scrolling since it +// shows the start and end of a scrolling sequence. class MouseWheelPhaseHandler { public: MouseWheelPhaseHandler(RenderWidgetHostViewBase* const host_view); @@ -59,9 +65,9 @@ class MouseWheelPhaseHandler { bool should_route_event); void DispatchPendingWheelEndEvent(); void IgnorePendingWheelEndEvent(); - void ResetScrollSequence(); - void SendWheelEndIfNeeded(); - void ScrollingMayBegin(); + void ResetTouchpadScrollSequence(); + void SendWheelEndForTouchpadScrollingIfNeeded(); + void TouchpadScrollingMayBegin(); // Used to set the timer timeout for testing. void set_mouse_wheel_end_dispatch_timeout(base::TimeDelta timeout) { @@ -89,7 +95,7 @@ class MouseWheelPhaseHandler { base::OneShotTimer mouse_wheel_end_dispatch_timer_; base::TimeDelta mouse_wheel_end_dispatch_timeout_; blink::WebMouseWheelEvent last_mouse_wheel_event_; - ScrollPhaseState scroll_phase_state_; + TouchpadScrollPhaseState touchpad_scroll_phase_state_; // This is used to break the timer based latching when the difference between // the locations of the first wheel event and the current wheel event is // larger than some threshold. The variable value is only valid while the diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc index e49d8d0eaa2..6175e84b718 100644 --- a/chromium/content/browser/renderer_host/render_process_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc @@ -2586,6 +2586,11 @@ bool RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes() { if (!base::FeatureList::IsEnabled(features::kSpareRendererForSitePerProcess)) return false; + // Spare renderer actually hurts performance on low-memory devices. See + // https://crbug.com/843775 for more details. + if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 1077) + return false; + return true; } diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc index 71c81ed240a..18be0d64dcf 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc @@ -847,6 +847,10 @@ void RenderWidgetHostViewAndroid::ShowDisambiguationPopup( tap_disambiguator_->ShowPopup(rect_pixels, zoomed_bitmap); } +void RenderWidgetHostViewAndroid::OnInterstitialPageGoingAway() { + sync_compositor_.reset(); +} + std::unique_ptr<SyntheticGestureTarget> RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() { return std::unique_ptr<SyntheticGestureTarget>( diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.h b/chromium/content/browser/renderer_host/render_widget_host_view_android.h index 4e9fef8bc8f..472e6316b7a 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_android.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.h @@ -163,6 +163,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid void DidStopFlinging() override; void ShowDisambiguationPopup(const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) override; + void OnInterstitialPageGoingAway() override; std::unique_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() override; void OnDidNavigateMainFrameToNewPage() override; diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index c099868cabc..ba3facd9161 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc @@ -696,6 +696,10 @@ class RenderWidgetHostViewAuraTest : public testing::Test { return delegates_.back().get(); } + MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() const { + return &(view_->event_handler()->mouse_wheel_phase_handler()); + } + // Sets the |view| active in TextInputManager with the given |type|. |type| // cannot be ui::TEXT_INPUT_TYPE_NONE. // Must not be called in the destruction path of |view|. @@ -2492,6 +2496,81 @@ TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest, TouchpadFlingStartResetsWheelPhaseState(); } +TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest, + ScrollingWithExternalMouseBreaksTouchpadScrollLatching) { + // The test is valid only when wheel scroll latching is enabled. + if (wheel_scrolling_mode_ == kWheelScrollingModeNone) + return; + + // Set the mouse_wheel_phase_handler_ timer timeout to a large value to make + // sure that the timer is still running when we are checking for the pending + // wheel end event after sending ui::MouseWheelEvent. + view_->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout( + TestTimeouts::action_max_timeout()); + + view_->InitAsChild(nullptr); + view_->Show(); + sink_->ClearMessages(); + + // When the user puts their fingers down a GFC is receieved. + ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL, gfx::Point(2, 2), + ui::EventTimeForNow(), 0, 0, 0, 0, 0, 2); + view_->OnScrollEvent(&fling_cancel); + + // Start touchpad scrolling by sending a ui::ET_SCROLL event. + ui::ScrollEvent scroll0(ui::ET_SCROLL, gfx::Point(2, 2), + ui::EventTimeForNow(), 0, 0, 5, 0, 5, 2); + view_->OnScrollEvent(&scroll0); + base::RunLoop().RunUntilIdle(); + MockWidgetInputHandler::MessageVector events = + GetAndResetDispatchedMessages(); + + const WebMouseWheelEvent* wheel_event = + static_cast<const WebMouseWheelEvent*>( + events[0]->ToEvent()->Event()->web_event.get()); + EXPECT_EQ("MouseWheel", GetMessageNames(events)); + EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); + events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + + // The mouse_wheel_phase_handler's timer won't be running during touchpad + // scroll. + EXPECT_FALSE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent()); + + // ACK the GSB and GSU events generated from the first touchpad wheel event. + events = GetAndResetDispatchedMessages(); + EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events)); + const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>( + events[0]->ToEvent()->Event()->web_event.get()); + EXPECT_EQ(WebInputEvent::kGestureScrollBegin, gesture_event->GetType()); + events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED); + gesture_event = static_cast<const WebGestureEvent*>( + events[1]->ToEvent()->Event()->web_event.get()); + EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType()); + events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED); + + // Start mouse wheel scrolling by sending a ui::ET_MOUSEWHEEL event. This + // should end the touchpad scrolling sequence and start a new timer-based + // wheel scrolling sequence. + ui::MouseWheelEvent wheel(gfx::Vector2d(0, 5), gfx::Point(2, 2), + gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0); + view_->OnMouseEvent(&wheel); + base::RunLoop().RunUntilIdle(); + events = GetAndResetDispatchedMessages(); + EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); + EXPECT_TRUE(events[0]->ToEvent()); + wheel_event = static_cast<const WebMouseWheelEvent*>( + events[0]->ToEvent()->Event()->web_event.get()); + EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase); + EXPECT_TRUE(events[2]->ToEvent()); + wheel_event = static_cast<const WebMouseWheelEvent*>( + events[2]->ToEvent()->Event()->web_event.get()); + EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase); + + // The mouse_wheel_phase_handler's timer will be running during mouse wheel + // scroll. + EXPECT_TRUE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent()); +} + void RenderWidgetHostViewAuraTest:: GSBWithTouchSourceStopsWheelScrollSequence() { // The test is valid only when wheel scroll latching is enabled. diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h index 9982522d4be..0a12a6666ff 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h @@ -383,6 +383,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // Returns true if this view's size have been initialized. virtual bool HasSize() const; + // Tells the view that the assocaited InterstitialPage will going away (but is + // not yet destroyed, as InterstitialPage destruction is asynchronous). The + // view may use this notification to clean up associated resources. This + // should be called before the WebContents is fully destroyed. + virtual void OnInterstitialPageGoingAway() {} + //---------------------------------------------------------------------------- // The following methods are related to IME. // TODO(ekaramad): Most of the IME methods should not stay virtual after IME diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc index 0f78c03f686..c02239a7bc5 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc @@ -433,7 +433,13 @@ void RenderWidgetHostViewChildFrame::SetTooltipText( if (!root_view) return; - root_view->GetCursorManager()->SetTooltipTextForView(this, tooltip_text); + auto* cursor_manager = root_view->GetCursorManager(); + // If there's no CursorManager then we're on Android, and setting tooltips + // is a null-opt there, so it's ok to early out. + if (!cursor_manager) + return; + + cursor_manager->SetTooltipTextForView(this, tooltip_text); } RenderWidgetHostViewBase* RenderWidgetHostViewChildFrame::GetParentView() { diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc index e046d3a5e23..69c041eed92 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc @@ -368,9 +368,14 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) { if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { bool should_route_event = ShouldRouteEvent(event); - if (host_view_->wheel_scroll_latching_enabled()) + if (host_view_->wheel_scroll_latching_enabled()) { + // End the touchpad scrolling sequence (if such exists) before handling + // a ui::ET_MOUSEWHEEL event. + mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(); + mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent( mouse_wheel_event, should_route_event); + } if (should_route_event) { host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( host_view_, &mouse_wheel_event, *event->latency()); @@ -465,11 +470,11 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) { if (event->type() == ui::ET_SCROLL_FLING_START) { RecordAction(base::UserMetricsAction("TrackpadScrollFling")); // The user has lifted their fingers. - mouse_wheel_phase_handler_.ResetScrollSequence(); + mouse_wheel_phase_handler_.ResetTouchpadScrollSequence(); } else if (event->type() == ui::ET_SCROLL_FLING_CANCEL) { // The user has put their fingers down. DCHECK_EQ(blink::kWebGestureDeviceTouchpad, gesture_event.SourceDevice()); - mouse_wheel_phase_handler_.ScrollingMayBegin(); + mouse_wheel_phase_handler_.TouchpadScrollingMayBegin(); } } @@ -568,7 +573,7 @@ void RenderWidgetHostViewEventHandler::OnGestureEvent(ui::GestureEvent* event) { // wheel based send a synthetic wheel event with kPhaseEnded to cancel // the current scroll. mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent(); - mouse_wheel_phase_handler_.SendWheelEndIfNeeded(); + mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(); } else if (event->type() == ui::ET_SCROLL_FLING_START) { RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); } @@ -580,7 +585,7 @@ void RenderWidgetHostViewEventHandler::OnGestureEvent(ui::GestureEvent* event) { // correct phase info when some of the wheel events get ignored while a // touchscreen scroll is going on. mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent(); - mouse_wheel_phase_handler_.ResetScrollSequence(); + mouse_wheel_phase_handler_.ResetTouchpadScrollSequence(); } if (ShouldRouteEvent(event)) { diff --git a/chromium/content/browser/site_per_process_browsertest.cc b/chromium/content/browser/site_per_process_browsertest.cc index 9d72cdc7599..35f13184f84 100644 --- a/chromium/content/browser/site_per_process_browsertest.cc +++ b/chromium/content/browser/site_per_process_browsertest.cc @@ -1066,6 +1066,30 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, rwhv_nested->GetCompositorViewportPixelSize()); } +// Verify an OOPIF resize handler doesn't fire immediately after load without +// the frame having been resized. See https://crbug.com/826457. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoResizeAfterIframeLoad) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(a)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + + FrameTreeNode* iframe = root->child_at(0); + GURL site_url = + embedded_test_server()->GetURL("b.com", "/page_with_resize_handler.html"); + NavigateFrameToURL(iframe, site_url); + + int resizes = -1; + EXPECT_TRUE(ExecuteScriptAndExtractInt( + iframe->current_frame_host(), + "window.domAutomationController.send(resize_count);", &resizes)); + + // Should be zero because the iframe only has its initial size from parent. + EXPECT_EQ(resizes, 0); +} + // Test that the view bounds for an out-of-process iframe are set and updated // correctly, including accounting for local frame offsets in the parent and // scroll positions. diff --git a/chromium/content/browser/web_contents/web_contents_android.cc b/chromium/content/browser/web_contents/web_contents_android.cc index 775b21206ed..5ebf1918903 100644 --- a/chromium/content/browser/web_contents/web_contents_android.cc +++ b/chromium/content/browser/web_contents/web_contents_android.cc @@ -139,17 +139,26 @@ std::string CompressAndSaveBitmap(const std::string& dir, base::AssertBlockingAllowed(); std::vector<unsigned char> data; - if (!gfx::JPEGCodec::Encode(bitmap, 85, &data)) + if (!gfx::JPEGCodec::Encode(bitmap, 85, &data)) { + LOG(ERROR) << "Failed to encode bitmap to JPEG"; return std::string(); + } base::FilePath screenshot_dir(dir); if (!base::DirectoryExists(screenshot_dir)) { - base::CreateDirectory(screenshot_dir); + if (!base::CreateDirectory(screenshot_dir)) { + LOG(ERROR) << "Failed to create screenshot directory"; + return std::string(); + } } base::FilePath screenshot_path; base::ScopedFILE out_file( base::CreateAndOpenTemporaryFileInDir(screenshot_dir, &screenshot_path)); + if (!out_file) { + LOG(ERROR) << "Failed to create temporary screenshot file"; + return std::string(); + } unsigned int bytes_written = fwrite(reinterpret_cast<const char*>(data.data()), 1, data.size(), out_file.get()); @@ -157,6 +166,7 @@ std::string CompressAndSaveBitmap(const std::string& dir, // If there were errors, don't leave a partial file around. if (bytes_written != data.size()) { base::DeleteFile(screenshot_path, false); + LOG(ERROR) << "Error writing screenshot file to disk"; return std::string(); } return screenshot_path.value(); diff --git a/chromium/content/common/swapped_out_messages.cc b/chromium/content/common/swapped_out_messages.cc index 4ee30301d62..d7747d332a2 100644 --- a/chromium/content/common/swapped_out_messages.cc +++ b/chromium/content/common/swapped_out_messages.cc @@ -33,6 +33,8 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) { case ViewHostMsg_RouteCloseEvent::ID: // Send page scale factor reset notification upon cross-process navigations. case ViewHostMsg_PageScaleFactorChanged::ID: + // Allow history.back() in OOPIFs - https://crbug.com/845923. + case ViewHostMsg_GoToEntryAtOffset::ID: return true; default: break; diff --git a/chromium/content/public/common/web_preferences.cc b/chromium/content/public/common/web_preferences.cc index c0ad7dafb92..f9308a3aa7f 100644 --- a/chromium/content/public/common/web_preferences.cc +++ b/chromium/content/public/common/web_preferences.cc @@ -157,7 +157,9 @@ WebPreferences::WebPreferences() shrinks_viewport_contents_to_fit(true), viewport_style(ViewportStyle::MOBILE), always_show_context_menu_on_touch(false), - smooth_scroll_for_find_enabled(true), + // TODO(sunyunjia): Re-enable smooth scroll for find on Android. + // https://crbug.com/845500 + smooth_scroll_for_find_enabled(false), #else viewport_meta_enabled(false), shrinks_viewport_contents_to_fit(false), diff --git a/chromium/content/renderer/loader/resource_dispatcher.cc b/chromium/content/renderer/loader/resource_dispatcher.cc index 55c99a21928..8764f8e026f 100644 --- a/chromium/content/renderer/loader/resource_dispatcher.cc +++ b/chromium/content/renderer/loader/resource_dispatcher.cc @@ -16,6 +16,7 @@ #include "base/files/file_path.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" +#include "base/rand_util.h" #include "base/strings/string_util.h" #include "base/synchronization/waitable_event.h" #include "base/task_scheduler/post_task.h" @@ -118,6 +119,21 @@ void NotifyResourceLoadComplete( std::move(resource_load_info)); } +int GetInitialRequestID() { + // Starting with a random number speculatively avoids RDH_INVALID_REQUEST_ID + // which are assumed to have been caused by restarting RequestID at 0 when + // restarting a renderer after a crash - this would cause collisions if + // requests from the previously crashed renderer are still active. See + // https://crbug.com/614281#c61 for more details about this hypothesis. + // + // To avoid increasing the likelyhood of overflowing the range of available + // RequestIDs, kMax is set to a relatively low value of 2^20 (rather than + // to something higher like 2^31). + const int kMin = 0; + const int kMax = 1 << 20; + return base::RandInt(kMin, kMax); +} + } // namespace // static @@ -125,8 +141,9 @@ int ResourceDispatcher::MakeRequestID() { // NOTE: The resource_dispatcher_host also needs probably unique // request_ids, so they count down from -2 (-1 is a special "we're // screwed value"), while the renderer process counts up. + static const int kInitialRequestID = GetInitialRequestID(); static base::AtomicSequenceNumber sequence; - return sequence.GetNext(); // We start at zero. + return kInitialRequestID + sequence.GetNext(); } ResourceDispatcher::ResourceDispatcher() |