15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/web_contents/aura/image_window_delegate.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/view_messages.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/browser/render_widget_host_view.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/layout.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/layer.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/canvas.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/image/image_png_rep.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns true if the entry's URL or any of the URLs in entry's redirect chain 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// match |url|. 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool DoesEntryMatchURL(NavigationEntry* entry, const GURL& url) { 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (entry->GetURL() == url) 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<GURL>& redirect_chain = entry->GetRedirectChain(); 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<GURL>::const_iterator it = redirect_chain.begin(); 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != redirect_chain.end(); 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it++) { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (*it == url) 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A LayerDelegate that paints an image for the layer. 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ImageLayerDelegate : public ui::LayerDelegate { 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ImageLayerDelegate() {} 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~ImageLayerDelegate() {} 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetImage(const gfx::Image& image) { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_ = image; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_size_ = image.AsImageSkia().size(); 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Image& image() const { return image_; } 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Overridden from ui::LayerDelegate: 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (image_.IsEmpty()) { 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) canvas->DrawColor(SK_ColorWHITE); 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkISize size = canvas->sk_canvas()->getDeviceSize(); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (size.width() != image_size_.width() || 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size.height() != image_size_.height()) { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawColor(SK_ColorWHITE); 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) canvas->DrawImageInt(image_.AsImageSkia(), 0, 0); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnDelegatedFrameDamage( 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Rect& damage_rect_in_dip) OVERRIDE {} 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called when the layer's device scale factor has changed. 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE { 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Invoked prior to the bounds changing. The returned closured is run after 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the bounds change. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::Closure(); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Image image_; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Size image_size_; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageLayerDelegate); 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Responsible for fading out and deleting the layer of the overlay window. 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class OverlayDismissAnimator 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public ui::LayerAnimationObserver { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Takes ownership of the layer. 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit OverlayDismissAnimator(scoped_ptr<ui::Layer> layer) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : layer_(layer.Pass()) { 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(layer_.get()); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Starts the fadeout animation on the layer. When the animation finishes, 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the object deletes itself along with the layer. 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Animate() { 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(layer_.get()); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimator* animator = layer_->GetAnimator(); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This makes SetOpacity() animate with default duration (which could be 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // zero, e.g. when running tests). 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings(animator); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) animator->AddObserver(this); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) layer_->SetOpacity(0); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Overridden from ui::LayerAnimationObserver 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnLayerAnimationEnded( 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE { 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delete this; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnLayerAnimationAborted( 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delete this; 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnLayerAnimationScheduled( 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimationSequence* sequence) OVERRIDE {} 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~OverlayDismissAnimator() {} 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ui::Layer> layer_; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OverscrollNavigationOverlay::OverscrollNavigationOverlay( 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebContentsImpl* web_contents) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : web_contents_(web_contents), 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_delegate_(NULL), 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) loading_complete_(false), 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) received_paint_update_(false), 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) slide_direction_(SLIDE_UNKNOWN) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OverscrollNavigationOverlay::~OverscrollNavigationOverlay() { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::StartObserving() { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) loading_complete_ = false; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) received_paint_update_ = false; 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) overlay_dismiss_layer_.reset(); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Observe(web_contents_); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make sure the overlay window is on top. 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (window_.get() && window_->parent()) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_->parent()->StackChildAtTop(window_.get()); 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Assumes the navigation has been initiated. 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NavigationEntry* pending_entry = 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch web_contents_->GetController().GetPendingEntry(); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Save url of the pending entry to identify when it loads and paints later. 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Under some circumstances navigation can leave a null pending entry - 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // see comments in NavigationControllerImpl::NavigateToPendingEntry(). 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending_entry_url_ = pending_entry ? pending_entry->GetURL() : GURL(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::SetOverlayWindow( 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<aura::Window> window, 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ImageWindowDelegate* delegate) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_ = window.Pass(); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (window_.get() && window_->parent()) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_->parent()->StackChildAtTop(window_.get()); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_delegate_ = delegate; 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (window_.get() && delegate->has_image()) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_slider_.reset(new WindowSlider(this, 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_->parent(), 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_.get())); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slide_direction_ = SLIDE_UNKNOWN; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_slider_.reset(); 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::StopObservingIfDone() { 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Normally we dismiss the overlay once we receive a paint update, however 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // for in-page navigations DidFirstVisuallyNonEmptyPaint() does not get 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // called, and we rely on loading_complete_ for those cases. 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!received_paint_update_ && !loading_complete_) 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If a slide is in progress, then do not destroy the window or the slide. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (window_slider_.get() && window_slider_->IsSlideInProgress()) 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The layer to be animated by OverlayDismissAnimator 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ui::Layer> overlay_dismiss_layer; 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (overlay_dismiss_layer_) 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) overlay_dismiss_layer = overlay_dismiss_layer_.Pass(); 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) else if (window_.get()) 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) overlay_dismiss_layer = window_->AcquireLayer(); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Observe(NULL); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_slider_.reset(); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_.reset(); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image_delegate_ = NULL; 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (overlay_dismiss_layer.get()) { 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // OverlayDismissAnimator deletes overlay_dismiss_layer and itself when the 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // animation completes. 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (new OverlayDismissAnimator(overlay_dismiss_layer.Pass()))->Animate(); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ui::Layer* OverscrollNavigationOverlay::CreateSlideLayer(int offset) { 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const NavigationControllerImpl& controller = web_contents_->GetController(); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller.GetEntryAtOffset(offset)); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Image image; 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (entry && entry->screenshot().get()) { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<gfx::ImagePNGRep> image_reps; 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f)); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) image = gfx::Image(image_reps); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!layer_delegate_) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layer_delegate_.reset(new ImageLayerDelegate()); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layer_delegate_->SetImage(image); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layer->set_delegate(layer_delegate_.get()); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return layer; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ui::Layer* OverscrollNavigationOverlay::CreateBackLayer() { 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!web_contents_->GetController().CanGoBack()) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slide_direction_ = SLIDE_BACK; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CreateSlideLayer(-1); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ui::Layer* OverscrollNavigationOverlay::CreateFrontLayer() { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!web_contents_->GetController().CanGoForward()) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slide_direction_ = SLIDE_FRONT; 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CreateSlideLayer(1); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid OverscrollNavigationOverlay::OnWindowSlideCompleting() { 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (slide_direction_ == SLIDE_UNKNOWN) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Perform the navigation. 250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (slide_direction_ == SLIDE_BACK) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents_->GetController().GoBack(); 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (slide_direction_ == SLIDE_FRONT) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents_->GetController().GoForward(); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Reset state and wait for the new navigation page to complete 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // loading/painting. 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StartObserving(); 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OverscrollNavigationOverlay::OnWindowSlideCompleted( 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ui::Layer> layer) { 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (slide_direction_ == SLIDE_UNKNOWN) { 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch window_slider_.reset(); 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch StopObservingIfDone(); 267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Change the image used for the overlay window. 271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_delegate_->SetImage(layer_delegate_->image()); 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch window_->layer()->SetTransform(gfx::Transform()); 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size())); 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch slide_direction_ = SLIDE_UNKNOWN; 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We may end up dismissing the overlay before it has a chance to repaint, so 27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // set the slider layer to be the one animated by OverlayDismissAnimator. 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (layer.get()) 27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) overlay_dismiss_layer_ = layer.Pass(); 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) StopObservingIfDone(); 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::OnWindowSlideAborted() { 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StopObservingIfDone(); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::OnWindowSliderDestroyed() { 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We only want to take an action here if WindowSlider is being destroyed 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // outside of OverscrollNavigationOverlay. If window_slider_.get() is NULL, 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // then OverscrollNavigationOverlay is the one destroying WindowSlider, and 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // we don't need to do anything. 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This check prevents StopObservingIfDone() being called multiple times 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (including recursively) for a single event. 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window_slider_.get()) { 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The slider has just been destroyed. Release the ownership. 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WindowSlider* slider ALLOW_UNUSED = window_slider_.release(); 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StopObservingIfDone(); 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() { 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NavigationEntry* visible_entry = 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_contents_->GetController().GetVisibleEntry(); 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (pending_entry_url_.is_empty() || 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DoesEntryMatchURL(visible_entry, pending_entry_url_)) { 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) received_paint_update_ = true; 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StopObservingIfDone(); 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OverscrollNavigationOverlay::DidStopLoading(RenderViewHost* host) { 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Don't compare URLs in this case - it's possible they won't match if 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // a gesture-nav initiated navigation was interrupted by some other in-site 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // navigation ((e.g., from a script, or from a bookmark). 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci loading_complete_ = true; 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StopObservingIfDone(); 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 319