| 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 "content/browser/frame_host/navigation_entry_impl.h" | 13 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 14 #include "content/browser/renderer_host/render_view_host_impl.h" | 14 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 15 #include "content/browser/web_contents/aura/overscroll_window_delegate.h" | 15 #include "content/browser/web_contents/aura/overscroll_window_delegate.h" |
| 16 #include "content/browser/web_contents/aura/uma_navigation_type.h" |
| 16 #include "content/browser/web_contents/web_contents_impl.h" | 17 #include "content/browser/web_contents/web_contents_impl.h" |
| 17 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
| 18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
| 21 #include "content/public/browser/user_metrics.h" |
| 20 #include "ui/aura/window.h" | 22 #include "ui/aura/window.h" |
| 21 #include "ui/base/layout.h" | 23 #include "ui/base/layout.h" |
| 22 #include "ui/compositor/layer.h" | 24 #include "ui/compositor/layer.h" |
| 23 #include "ui/compositor/layer_animation_observer.h" | 25 #include "ui/compositor/layer_animation_observer.h" |
| 24 #include "ui/compositor/paint_recorder.h" | 26 #include "ui/compositor/paint_recorder.h" |
| 25 #include "ui/compositor/scoped_layer_animation_settings.h" | 27 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 26 #include "ui/gfx/canvas.h" | 28 #include "ui/gfx/canvas.h" |
| 27 #include "ui/gfx/image/image_png_rep.h" | 29 #include "ui/gfx/image/image_png_rep.h" |
| 28 | 30 |
| 29 namespace content { | 31 namespace content { |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 // Returns true if the entry's URL or any of the URLs in entry's redirect chain | 34 // Returns true if the entry's URL or any of the URLs in entry's redirect chain |
| 33 // match |url|. | 35 // match |url|. |
| 34 bool DoesEntryMatchURL(NavigationEntry* entry, const GURL& url) { | 36 bool DoesEntryMatchURL(NavigationEntry* entry, const GURL& url) { |
| 35 if (!entry) | 37 if (!entry) |
| 36 return false; | 38 return false; |
| 37 if (entry->GetURL() == url) | 39 if (entry->GetURL() == url) |
| 38 return true; | 40 return true; |
| 39 const std::vector<GURL>& redirect_chain = entry->GetRedirectChain(); | 41 const std::vector<GURL>& redirect_chain = entry->GetRedirectChain(); |
| 40 for (std::vector<GURL>::const_iterator it = redirect_chain.begin(); | 42 for (std::vector<GURL>::const_iterator it = redirect_chain.begin(); |
| 41 it != redirect_chain.end(); | 43 it != redirect_chain.end(); |
| 42 it++) { | 44 it++) { |
| 43 if (*it == url) | 45 if (*it == url) |
| 44 return true; | 46 return true; |
| 45 } | 47 } |
| 46 return false; | 48 return false; |
| 47 } | 49 } |
| 48 | 50 |
| 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. |
| 68 void RecordCancelled(OverscrollNavigationOverlay::NavigationDirection direction, |
| 69 OverscrollSource source) { |
| 70 UMA_HISTOGRAM_ENUMERATION("Overscroll.Cancelled3", |
| 71 GetUmaNavigationType(direction, source), |
| 72 NAVIGATION_TYPE_COUNT); |
| 73 if (direction == OverscrollNavigationOverlay::BACK) |
| 74 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Back")); |
| 75 else |
| 76 RecordAction(base::UserMetricsAction("Overscroll_Cancelled.Forward")); |
| 77 } |
| 78 |
| 49 } // namespace | 79 } // namespace |
| 50 | 80 |
| 51 // Responsible for fading out and deleting the layer of the overlay window. | 81 // Responsible for fading out and deleting the layer of the overlay window. |
| 52 class OverlayDismissAnimator | 82 class OverlayDismissAnimator |
| 53 : public ui::LayerAnimationObserver { | 83 : public ui::LayerAnimationObserver { |
| 54 public: | 84 public: |
| 55 // Takes ownership of the layer. | 85 // Takes ownership of the layer. |
| 56 explicit OverlayDismissAnimator(std::unique_ptr<ui::Layer> layer) | 86 explicit OverlayDismissAnimator(std::unique_ptr<ui::Layer> layer) |
| 57 : layer_(std::move(layer)) { | 87 : layer_(std::move(layer)) { |
| 58 CHECK(layer_.get()); | 88 CHECK(layer_.get()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 window_.reset(); | 167 window_.reset(); |
| 138 (new OverlayDismissAnimator(std::move(dismiss_layer)))->Animate(); | 168 (new OverlayDismissAnimator(std::move(dismiss_layer)))->Animate(); |
| 139 Observe(nullptr); | 169 Observe(nullptr); |
| 140 received_paint_update_ = false; | 170 received_paint_update_ = false; |
| 141 loading_complete_ = false; | 171 loading_complete_ = false; |
| 142 } | 172 } |
| 143 | 173 |
| 144 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateOverlayWindow( | 174 std::unique_ptr<aura::Window> OverscrollNavigationOverlay::CreateOverlayWindow( |
| 145 const gfx::Rect& bounds) { | 175 const gfx::Rect& bounds) { |
| 146 UMA_HISTOGRAM_ENUMERATION( | 176 UMA_HISTOGRAM_ENUMERATION( |
| 147 "Overscroll.Started2", direction_, NAVIGATION_COUNT); | 177 "Overscroll.Started3", |
| 178 GetUmaNavigationType(direction_, owa_->overscroll_source()), |
| 179 NAVIGATION_TYPE_COUNT); |
| 148 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( | 180 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( |
| 149 owa_.get(), GetImageForDirection(direction_)); | 181 owa_.get(), GetImageForDirection(direction_)); |
| 150 std::unique_ptr<aura::Window> window(new aura::Window(overscroll_delegate)); | 182 std::unique_ptr<aura::Window> window(new aura::Window(overscroll_delegate)); |
| 151 window->set_owned_by_parent(false); | 183 window->set_owned_by_parent(false); |
| 152 window->SetTransparent(true); | 184 window->SetTransparent(true); |
| 153 window->Init(ui::LAYER_TEXTURED); | 185 window->Init(ui::LAYER_TEXTURED); |
| 154 window->layer()->SetMasksToBounds(false); | 186 window->layer()->SetMasksToBounds(false); |
| 155 window->SetName("OverscrollOverlay"); | 187 window->SetName("OverscrollOverlay"); |
| 156 web_contents_window_->AddChild(window.get()); | 188 web_contents_window_->AddChild(window.get()); |
| 157 aura::Window* event_window = GetMainWindow(); | 189 aura::Window* event_window = GetMainWindow(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 if (!main_window) | 243 if (!main_window) |
| 212 return; | 244 return; |
| 213 main_window->ReleaseCapture(); | 245 main_window->ReleaseCapture(); |
| 214 } | 246 } |
| 215 | 247 |
| 216 void OverscrollNavigationOverlay::OnOverscrollCompleted( | 248 void OverscrollNavigationOverlay::OnOverscrollCompleted( |
| 217 std::unique_ptr<aura::Window> window) { | 249 std::unique_ptr<aura::Window> window) { |
| 218 DCHECK(direction_ != NONE); | 250 DCHECK(direction_ != NONE); |
| 219 aura::Window* main_window = GetMainWindow(); | 251 aura::Window* main_window = GetMainWindow(); |
| 220 if (!main_window) { | 252 if (!main_window) { |
| 221 UMA_HISTOGRAM_ENUMERATION( | 253 RecordCancelled(direction_, owa_->overscroll_source()); |
| 222 "Overscroll.Cancelled", direction_, NAVIGATION_COUNT); | |
| 223 return; | 254 return; |
| 224 } | 255 } |
| 225 | 256 |
| 226 main_window->SetTransform(gfx::Transform()); | 257 main_window->SetTransform(gfx::Transform()); |
| 227 window_ = std::move(window); | 258 window_ = std::move(window); |
| 228 // Make sure the window is in its default position. | 259 // Make sure the window is in its default position. |
| 229 window_->SetBounds(gfx::Rect(web_contents_window_->bounds().size())); | 260 window_->SetBounds(gfx::Rect(web_contents_window_->bounds().size())); |
| 230 window_->SetTransform(gfx::Transform()); | 261 window_->SetTransform(gfx::Transform()); |
| 231 // Make sure the overlay window is on top. | 262 // Make sure the overlay window is on top. |
| 232 web_contents_window_->StackChildAtTop(window_.get()); | 263 web_contents_window_->StackChildAtTop(window_.get()); |
| 233 | 264 |
| 234 // Make sure we can navigate first, as other factors can trigger a navigation | 265 // Make sure we can navigate first, as other factors can trigger a navigation |
| 235 // during an overscroll gesture and navigating without history produces a | 266 // during an overscroll gesture and navigating without history produces a |
| 236 // crash. | 267 // crash. |
| 237 bool navigated = false; | 268 bool navigated = false; |
| 238 if (direction_ == FORWARD && web_contents_->GetController().CanGoForward()) { | 269 if (direction_ == FORWARD && web_contents_->GetController().CanGoForward()) { |
| 239 web_contents_->GetController().GoForward(); | 270 web_contents_->GetController().GoForward(); |
| 240 navigated = true; | 271 navigated = true; |
| 241 } else if (direction_ == BACK && web_contents_->GetController().CanGoBack()) { | 272 } else if (direction_ == BACK && web_contents_->GetController().CanGoBack()) { |
| 242 web_contents_->GetController().GoBack(); | 273 web_contents_->GetController().GoBack(); |
| 243 navigated = true; | 274 navigated = true; |
| 244 } else { | 275 } else { |
| 245 // We need to dismiss the overlay without navigating as soon as the | 276 // We need to dismiss the overlay without navigating as soon as the |
| 246 // overscroll finishes. | 277 // overscroll finishes. |
| 247 UMA_HISTOGRAM_ENUMERATION( | 278 RecordCancelled(direction_, owa_->overscroll_source()); |
| 248 "Overscroll.Cancelled", direction_, NAVIGATION_COUNT); | |
| 249 loading_complete_ = true; | 279 loading_complete_ = true; |
| 250 } | 280 } |
| 251 | 281 |
| 252 if (navigated) { | 282 if (navigated) { |
| 253 UMA_HISTOGRAM_ENUMERATION( | 283 UMA_HISTOGRAM_ENUMERATION( |
| 254 "Overscroll.Navigated2", direction_, NAVIGATION_COUNT); | 284 "Overscroll.Navigated3", |
| 285 GetUmaNavigationType(direction_, owa_->overscroll_source()), |
| 286 NAVIGATION_TYPE_COUNT); |
| 287 if (direction_ == BACK) |
| 288 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Back")); |
| 289 else |
| 290 RecordAction(base::UserMetricsAction("Overscroll_Navigated.Forward")); |
| 255 StartObserving(); | 291 StartObserving(); |
| 256 } | 292 } |
| 257 | 293 |
| 258 direction_ = NONE; | 294 direction_ = NONE; |
| 259 StopObservingIfDone(); | 295 StopObservingIfDone(); |
| 260 } | 296 } |
| 261 | 297 |
| 262 void OverscrollNavigationOverlay::OnOverscrollCancelled() { | 298 void OverscrollNavigationOverlay::OnOverscrollCancelled() { |
| 263 UMA_HISTOGRAM_ENUMERATION( | 299 RecordCancelled(direction_, owa_->overscroll_source()); |
| 264 "Overscroll.Cancelled", direction_, NAVIGATION_COUNT); | |
| 265 aura::Window* main_window = GetMainWindow(); | 300 aura::Window* main_window = GetMainWindow(); |
| 266 if (!main_window) | 301 if (!main_window) |
| 267 return; | 302 return; |
| 268 main_window->ReleaseCapture(); | 303 main_window->ReleaseCapture(); |
| 269 direction_ = NONE; | 304 direction_ = NONE; |
| 270 StopObservingIfDone(); | 305 StopObservingIfDone(); |
| 271 } | 306 } |
| 272 | 307 |
| 273 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { | 308 void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { |
| 274 NavigationEntry* visible_entry = | 309 NavigationEntry* visible_entry = |
| 275 web_contents_->GetController().GetVisibleEntry(); | 310 web_contents_->GetController().GetVisibleEntry(); |
| 276 if (pending_entry_url_.is_empty() || | 311 if (pending_entry_url_.is_empty() || |
| 277 DoesEntryMatchURL(visible_entry, pending_entry_url_)) { | 312 DoesEntryMatchURL(visible_entry, pending_entry_url_)) { |
| 278 received_paint_update_ = true; | 313 received_paint_update_ = true; |
| 279 StopObservingIfDone(); | 314 StopObservingIfDone(); |
| 280 } | 315 } |
| 281 } | 316 } |
| 282 | 317 |
| 283 void OverscrollNavigationOverlay::DidStopLoading() { | 318 void OverscrollNavigationOverlay::DidStopLoading() { |
| 284 // Don't compare URLs in this case - it's possible they won't match if | 319 // Don't compare URLs in this case - it's possible they won't match if |
| 285 // a gesture-nav initiated navigation was interrupted by some other in-site | 320 // a gesture-nav initiated navigation was interrupted by some other in-site |
| 286 // navigation (e.g., from a script, or from a bookmark). | 321 // navigation (e.g., from a script, or from a bookmark). |
| 287 loading_complete_ = true; | 322 loading_complete_ = true; |
| 288 StopObservingIfDone(); | 323 StopObservingIfDone(); |
| 289 } | 324 } |
| 290 | 325 |
| 291 } // namespace content | 326 } // namespace content |
| OLD | NEW |