| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/web_contents/aura/overscroll_navigation_overlay.h" | 5 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/metrics/user_metrics.h" | 13 #include "base/metrics/user_metrics.h" |
| 14 #include "content/browser/frame_host/navigation_entry_impl.h" | 14 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 15 #include "content/browser/renderer_host/render_view_host_impl.h" | 15 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 16 #include "content/browser/web_contents/aura/overscroll_window_delegate.h" | 16 #include "content/browser/web_contents/aura/overscroll_window_delegate.h" |
| 17 #include "content/browser/web_contents/aura/uma_navigation_type.h" | |
| 18 #include "content/browser/web_contents/web_contents_impl.h" | 17 #include "content/browser/web_contents/web_contents_impl.h" |
| 19 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
| 20 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
| 22 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
| 23 #include "ui/base/layout.h" | 22 #include "ui/base/layout.h" |
| 24 #include "ui/compositor/layer.h" | 23 #include "ui/compositor/layer.h" |
| 25 #include "ui/compositor/layer_animation_observer.h" | 24 #include "ui/compositor/layer_animation_observer.h" |
| 26 #include "ui/compositor/paint_recorder.h" | 25 #include "ui/compositor/paint_recorder.h" |
| 27 #include "ui/compositor/scoped_layer_animation_settings.h" | 26 #include "ui/compositor/scoped_layer_animation_settings.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 41 const std::vector<GURL>& redirect_chain = entry->GetRedirectChain(); | 40 const std::vector<GURL>& redirect_chain = entry->GetRedirectChain(); |
| 42 for (std::vector<GURL>::const_iterator it = redirect_chain.begin(); | 41 for (std::vector<GURL>::const_iterator it = redirect_chain.begin(); |
| 43 it != redirect_chain.end(); | 42 it != redirect_chain.end(); |
| 44 it++) { | 43 it++) { |
| 45 if (*it == url) | 44 if (*it == url) |
| 46 return true; | 45 return true; |
| 47 } | 46 } |
| 48 return false; | 47 return false; |
| 49 } | 48 } |
| 50 | 49 |
| 51 UmaNavigationType GetUmaNavigationType( | |
| 52 OverscrollNavigationOverlay::NavigationDirection direction, | |
| 53 OverscrollSource source) { | |
| 54 if (direction == OverscrollNavigationOverlay::NONE || | |
| 55 source == OverscrollSource::NONE) | |
| 56 return NAVIGATION_TYPE_NONE; | |
| 57 if (direction == OverscrollNavigationOverlay::BACK) | |
| 58 return source == OverscrollSource::TOUCHPAD | |
| 59 ? UmaNavigationType::BACK_TOUCHPAD | |
| 60 : UmaNavigationType::BACK_TOUCHSCREEN; | |
| 61 DCHECK_EQ(direction, OverscrollNavigationOverlay::FORWARD); | |
| 62 return source == OverscrollSource::TOUCHPAD | |
| 63 ? UmaNavigationType::FORWARD_TOUCHPAD | |
| 64 : UmaNavigationType::FORWARD_TOUCHSCREEN; | |
| 65 } | |
| 66 | |
| 67 // Records UMA historgram and also user action for the cancelled overscroll. | 50 // Records UMA historgram and also user action for the cancelled overscroll. |
| 68 void RecordCancelled(OverscrollNavigationOverlay::NavigationDirection direction, | 51 void RecordCancelled(NavigationDirection direction, OverscrollSource source) { |
| 69 OverscrollSource source) { | |
| 70 UMA_HISTOGRAM_ENUMERATION("Overscroll.Cancelled3", | 52 UMA_HISTOGRAM_ENUMERATION("Overscroll.Cancelled3", |
| 71 GetUmaNavigationType(direction, source), | 53 GetUmaNavigationType(direction, source), |
| 72 NAVIGATION_TYPE_COUNT); | 54 NAVIGATION_TYPE_COUNT); |
| 73 if (direction == OverscrollNavigationOverlay::BACK) | 55 if (direction == NavigationDirection::BACK) |
| 74 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Back")); | 56 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Back")); |
| 75 else | 57 else |
| 76 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Forward")); | 58 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Forward")); |
| 77 } | 59 } |
| 78 | 60 |
| 79 } // namespace | 61 } // namespace |
| 80 | 62 |
| 81 // Responsible for fading out and deleting the layer of the overlay window. | 63 // Responsible for fading out and deleting the layer of the overlay window. |
| 82 class OverlayDismissAnimator | 64 class OverlayDismissAnimator |
| 83 : public ui::LayerAnimationObserver { | 65 : public ui::LayerAnimationObserver { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 ~OverlayDismissAnimator() override {} | 98 ~OverlayDismissAnimator() override {} |
| 117 | 99 |
| 118 std::unique_ptr<ui::Layer> layer_; | 100 std::unique_ptr<ui::Layer> layer_; |
| 119 | 101 |
| 120 DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator); | 102 DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator); |
| 121 }; | 103 }; |
| 122 | 104 |
| 123 OverscrollNavigationOverlay::OverscrollNavigationOverlay( | 105 OverscrollNavigationOverlay::OverscrollNavigationOverlay( |
| 124 WebContentsImpl* web_contents, | 106 WebContentsImpl* web_contents, |
| 125 aura::Window* web_contents_window) | 107 aura::Window* web_contents_window) |
| 126 : direction_(NONE), | 108 : direction_(NavigationDirection::NONE), |
| 127 web_contents_(web_contents), | 109 web_contents_(web_contents), |
| 128 loading_complete_(false), | 110 loading_complete_(false), |
| 129 received_paint_update_(false), | 111 received_paint_update_(false), |
| 130 owa_(new OverscrollWindowAnimation(this)), | 112 owa_(new OverscrollWindowAnimation(this)), |
| 131 web_contents_window_(web_contents_window) { | 113 web_contents_window_(web_contents_window) { |
| 132 } | 114 } |
| 133 | 115 |
| 134 OverscrollNavigationOverlay::~OverscrollNavigationOverlay() { | 116 OverscrollNavigationOverlay::~OverscrollNavigationOverlay() { |
| 135 aura::Window* event_window = GetMainWindow(); | 117 aura::Window* event_window = GetMainWindow(); |
| 136 if (owa_->is_active() && event_window) | 118 if (owa_->is_active() && event_window) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( | 162 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( |
| 181 owa_.get(), GetImageForDirection(direction_)); | 163 owa_.get(), GetImageForDirection(direction_)); |
| 182 std::unique_ptr<aura::Window> window(new aura::Window(overscroll_delegate)); | 164 std::unique_ptr<aura::Window> window(new aura::Window(overscroll_delegate)); |
| 183 window->set_owned_by_parent(false); | 165 window->set_owned_by_parent(false); |
| 184 window->SetTransparent(true); | 166 window->SetTransparent(true); |
| 185 window->Init(ui::LAYER_TEXTURED); | 167 window->Init(ui::LAYER_TEXTURED); |
| 186 window->layer()->SetMasksToBounds(false); | 168 window->layer()->SetMasksToBounds(false); |
| 187 window->SetName("OverscrollOverlay"); | 169 window->SetName("OverscrollOverlay"); |
| 188 web_contents_window_->AddChild(window.get()); | 170 web_contents_window_->AddChild(window.get()); |
| 189 aura::Window* event_window = GetMainWindow(); | 171 aura::Window* event_window = GetMainWindow(); |
| 190 if (direction_ == FORWARD) | 172 if (direction_ == NavigationDirection::FORWARD) |
| 191 web_contents_window_->StackChildAbove(window.get(), event_window); | 173 web_contents_window_->StackChildAbove(window.get(), event_window); |
| 192 else | 174 else |
| 193 web_contents_window_->StackChildBelow(window.get(), event_window); | 175 web_contents_window_->StackChildBelow(window.get(), event_window); |
| 194 window->SetBounds(bounds); | 176 window->SetBounds(bounds); |
| 195 // Set capture on the window that is receiving the overscroll events so that | 177 // Set capture on the window that is receiving the overscroll events so that |
| 196 // trackpad scroll gestures keep targetting it even if the mouse pointer moves | 178 // trackpad scroll gestures keep targetting it even if the mouse pointer moves |
| 197 // off its bounds. | 179 // off its bounds. |
| 198 event_window->SetCapture(); | 180 event_window->SetCapture(); |
| 199 window->Show(); | 181 window->Show(); |
| 200 return window; | 182 return window; |
| 201 } | 183 } |
| 202 | 184 |
| 203 const gfx::Image OverscrollNavigationOverlay::GetImageForDirection( | 185 const gfx::Image OverscrollNavigationOverlay::GetImageForDirection( |
| 204 NavigationDirection direction) const { | 186 NavigationDirection direction) const { |
| 205 const NavigationControllerImpl& controller = web_contents_->GetController(); | 187 const NavigationControllerImpl& controller = web_contents_->GetController(); |
| 206 const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( | 188 const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( |
| 207 controller.GetEntryAtOffset(direction == FORWARD ? 1 : -1)); | 189 controller.GetEntryAtOffset( |
| 190 direction == NavigationDirection::FORWARD ? 1 : -1)); |
| 208 | 191 |
| 209 if (entry && entry->screenshot().get()) { | 192 if (entry && entry->screenshot().get()) { |
| 210 std::vector<gfx::ImagePNGRep> image_reps; | 193 std::vector<gfx::ImagePNGRep> image_reps; |
| 211 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f)); | 194 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f)); |
| 212 return gfx::Image(image_reps); | 195 return gfx::Image(image_reps); |
| 213 } | 196 } |
| 214 return gfx::Image(); | 197 return gfx::Image(); |
| 215 } | 198 } |
| 216 | 199 |
| 217 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateFrontWindow( | 200 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateFrontWindow( |
| 218 const gfx::Rect& bounds) { | 201 const gfx::Rect& bounds) { |
| 219 if (!web_contents_->GetController().CanGoForward()) | 202 if (!web_contents_->GetController().CanGoForward()) |
| 220 return nullptr; | 203 return nullptr; |
| 221 direction_ = FORWARD; | 204 direction_ = NavigationDirection::FORWARD; |
| 222 return CreateOverlayWindow(bounds); | 205 return CreateOverlayWindow(bounds); |
| 223 } | 206 } |
| 224 | 207 |
| 225 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateBackWindow( | 208 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateBackWindow( |
| 226 const gfx::Rect& bounds) { | 209 const gfx::Rect& bounds) { |
| 227 if (!web_contents_->GetController().CanGoBack()) | 210 if (!web_contents_->GetController().CanGoBack()) |
| 228 return nullptr; | 211 return nullptr; |
| 229 direction_ = BACK; | 212 direction_ = NavigationDirection::BACK; |
| 230 return CreateOverlayWindow(bounds); | 213 return CreateOverlayWindow(bounds); |
| 231 } | 214 } |
| 232 | 215 |
| 233 aura::Window* OverscrollNavigationOverlay::GetMainWindow() const { | 216 aura::Window* OverscrollNavigationOverlay::GetMainWindow() const { |
| 234 if (window_) | 217 if (window_) |
| 235 return window_.get(); | 218 return window_.get(); |
| 236 return web_contents_->IsBeingDestroyed() | 219 return web_contents_->IsBeingDestroyed() |
| 237 ? nullptr | 220 ? nullptr |
| 238 : web_contents_->GetContentNativeView(); | 221 : web_contents_->GetContentNativeView(); |
| 239 } | 222 } |
| 240 | 223 |
| 241 void OverscrollNavigationOverlay::OnOverscrollCompleting() { | 224 void OverscrollNavigationOverlay::OnOverscrollCompleting() { |
| 242 aura::Window* main_window = GetMainWindow(); | 225 aura::Window* main_window = GetMainWindow(); |
| 243 if (!main_window) | 226 if (!main_window) |
| 244 return; | 227 return; |
| 245 main_window->ReleaseCapture(); | 228 main_window->ReleaseCapture(); |
| 246 } | 229 } |
| 247 | 230 |
| 248 void OverscrollNavigationOverlay::OnOverscrollCompleted( | 231 void OverscrollNavigationOverlay::OnOverscrollCompleted( |
| 249 std::unique_ptr<aura::Window> window) { | 232 std::unique_ptr<aura::Window> window) { |
| 250 DCHECK(direction_ != NONE); | 233 DCHECK_NE(direction_, NavigationDirection::NONE); |
| 251 aura::Window* main_window = GetMainWindow(); | 234 aura::Window* main_window = GetMainWindow(); |
| 252 if (!main_window) { | 235 if (!main_window) { |
| 253 RecordCancelled(direction_, owa_->overscroll_source()); | 236 RecordCancelled(direction_, owa_->overscroll_source()); |
| 254 return; | 237 return; |
| 255 } | 238 } |
| 256 | 239 |
| 257 main_window->SetTransform(gfx::Transform()); | 240 main_window->SetTransform(gfx::Transform()); |
| 258 window_ = std::move(window); | 241 window_ = std::move(window); |
| 259 // Make sure the window is in its default position. | 242 // Make sure the window is in its default position. |
| 260 window_->SetBounds(gfx::Rect(web_contents_window_->bounds().size())); | 243 window_->SetBounds(gfx::Rect(web_contents_window_->bounds().size())); |
| 261 window_->SetTransform(gfx::Transform()); | 244 window_->SetTransform(gfx::Transform()); |
| 262 // Make sure the overlay window is on top. | 245 // Make sure the overlay window is on top. |
| 263 web_contents_window_->StackChildAtTop(window_.get()); | 246 web_contents_window_->StackChildAtTop(window_.get()); |
| 264 | 247 |
| 265 // Make sure we can navigate first, as other factors can trigger a navigation | 248 // Make sure we can navigate first, as other factors can trigger a navigation |
| 266 // during an overscroll gesture and navigating without history produces a | 249 // during an overscroll gesture and navigating without history produces a |
| 267 // crash. | 250 // crash. |
| 268 bool navigated = false; | 251 bool navigated = false; |
| 269 if (direction_ == FORWARD && web_contents_->GetController().CanGoForward()) { | 252 if (direction_ == NavigationDirection::FORWARD && |
| 253 web_contents_->GetController().CanGoForward()) { |
| 270 web_contents_->GetController().GoForward(); | 254 web_contents_->GetController().GoForward(); |
| 271 navigated = true; | 255 navigated = true; |
| 272 } else if (direction_ == BACK && web_contents_->GetController().CanGoBack()) { | 256 } else if (direction_ == NavigationDirection::BACK && |
| 257 web_contents_->GetController().CanGoBack()) { |
| 273 web_contents_->GetController().GoBack(); | 258 web_contents_->GetController().GoBack(); |
| 274 navigated = true; | 259 navigated = true; |
| 275 } else { | 260 } else { |
| 276 // We need to dismiss the overlay without navigating as soon as the | 261 // We need to dismiss the overlay without navigating as soon as the |
| 277 // overscroll finishes. | 262 // overscroll finishes. |
| 278 RecordCancelled(direction_, owa_->overscroll_source()); | 263 RecordCancelled(direction_, owa_->overscroll_source()); |
| 279 loading_complete_ = true; | 264 loading_complete_ = true; |
| 280 } | 265 } |
| 281 | 266 |
| 282 if (navigated) { | 267 if (navigated) { |
| 283 UMA_HISTOGRAM_ENUMERATION( | 268 UMA_HISTOGRAM_ENUMERATION( |
| 284 "Overscroll.Navigated3", | 269 "Overscroll.Navigated3", |
| 285 GetUmaNavigationType(direction_, owa_->overscroll_source()), | 270 GetUmaNavigationType(direction_, owa_->overscroll_source()), |
| 286 NAVIGATION_TYPE_COUNT); | 271 NAVIGATION_TYPE_COUNT); |
| 287 if (direction_ == BACK) | 272 if (direction_ == NavigationDirection::BACK) |
| 288 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Back")); | 273 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Back")); |
| 289 else | 274 else |
| 290 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Forward")); | 275 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Forward")); |
| 291 StartObserving(); | 276 StartObserving(); |
| 292 } | 277 } |
| 293 | 278 |
| 294 direction_ = NONE; | 279 direction_ = NavigationDirection::NONE; |
| 295 StopObservingIfDone(); | 280 StopObservingIfDone(); |
| 296 } | 281 } |
| 297 | 282 |
| 298 void OverscrollNavigationOverlay::OnOverscrollCancelled() { | 283 void OverscrollNavigationOverlay::OnOverscrollCancelled() { |
| 299 RecordCancelled(direction_, owa_->overscroll_source()); | 284 RecordCancelled(direction_, owa_->overscroll_source()); |
| 300 aura::Window* main_window = GetMainWindow(); | 285 aura::Window* main_window = GetMainWindow(); |
| 301 if (!main_window) | 286 if (!main_window) |
| 302 return; | 287 return; |
| 303 main_window->ReleaseCapture(); | 288 main_window->ReleaseCapture(); |
| 304 direction_ = NONE; | 289 direction_ = NavigationDirection::NONE; |
| 305 StopObservingIfDone(); | 290 StopObservingIfDone(); |
| 306 } | 291 } |
| 307 | 292 |
| 308 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { | 293 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { |
| 309 NavigationEntry* visible_entry = | 294 NavigationEntry* visible_entry = |
| 310 web_contents_->GetController().GetVisibleEntry(); | 295 web_contents_->GetController().GetVisibleEntry(); |
| 311 if (pending_entry_url_.is_empty() || | 296 if (pending_entry_url_.is_empty() || |
| 312 DoesEntryMatchURL(visible_entry, pending_entry_url_)) { | 297 DoesEntryMatchURL(visible_entry, pending_entry_url_)) { |
| 313 received_paint_update_ = true; | 298 received_paint_update_ = true; |
| 314 StopObservingIfDone(); | 299 StopObservingIfDone(); |
| 315 } | 300 } |
| 316 } | 301 } |
| 317 | 302 |
| 318 void OverscrollNavigationOverlay::DidStopLoading() { | 303 void OverscrollNavigationOverlay::DidStopLoading() { |
| 319 // Don't compare URLs in this case - it's possible they won't match if | 304 // Don't compare URLs in this case - it's possible they won't match if |
| 320 // a gesture-nav initiated navigation was interrupted by some other in-site | 305 // a gesture-nav initiated navigation was interrupted by some other in-site |
| 321 // navigation (e.g., from a script, or from a bookmark). | 306 // navigation (e.g., from a script, or from a bookmark). |
| 322 loading_complete_ = true; | 307 loading_complete_ = true; |
| 323 StopObservingIfDone(); | 308 StopObservingIfDone(); |
| 324 } | 309 } |
| 325 | 310 |
| 326 } // namespace content | 311 } // namespace content |
| OLD | NEW |