Commit 00d64211 authored by dominich@chromium.org's avatar dominich@chromium.org

Prerender/Instant interopability.

BUG=82590
TEST=Use instant to navigate to a page that is currently being prerendered. Observe it does not crash.


Review URL: http://codereview.chromium.org/7034043

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86651 0039d316-1c4b-4281-b951-d872f2087c98
parent fe2a2ba1
......@@ -500,6 +500,11 @@ void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) {
UpdateDisplayableLoader();
}
void InstantController::SwappedTabContents(InstantLoader* loader) {
if (displayable_loader_ == loader)
delegate_->ShowInstant(displayable_loader_->preview_contents());
}
void InstantController::UpdateDisplayableLoader() {
InstantLoader* loader = NULL;
// As soon as the pending loader is displayable it becomes the current loader,
......
......@@ -184,6 +184,7 @@ class InstantController : public InstantLoaderDelegate {
InstantLoader* loader) OVERRIDE;
virtual void AddToBlacklist(InstantLoader* loader,
const GURL& url) OVERRIDE;
virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE;
private:
friend class InstantTest;
......
......@@ -25,6 +25,7 @@
#include "chrome/browser/ui/download/download_tab_helper.h"
#include "chrome/browser/ui/download/download_tab_helper_delegate.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "content/browser/renderer_host/render_view_host.h"
......@@ -144,6 +145,7 @@ void InstantLoader::FrameLoadObserver::Observe(
class InstantLoader::TabContentsDelegateImpl
: public TabContentsDelegate,
public TabContentsWrapperDelegate,
public NotificationObserver,
public TabContentsObserver,
public DownloadTabHelperDelegate {
......@@ -220,6 +222,10 @@ class InstantLoader::TabContentsDelegateImpl
NavigationType::Type navigation_type) OVERRIDE;
virtual bool ShouldShowHungRendererDialog() OVERRIDE;
// TabContentsWrapperDelegate:
virtual void SwapTabContents(TabContentsWrapper* old_tc,
TabContentsWrapper* new_tc) OVERRIDE;
// TabContentsObserver:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
......@@ -554,6 +560,15 @@ bool InstantLoader::TabContentsDelegateImpl::ShouldShowHungRendererDialog() {
return false;
}
// If this is being called, something is swapping in to our preview_contents_
// before we've added it to the tab strip.
void InstantLoader::TabContentsDelegateImpl::SwapTabContents(
TabContentsWrapper* old_tc,
TabContentsWrapper* new_tc) {
loader_->ReplacePreviewContents(old_tc, new_tc);
}
bool InstantLoader::TabContentsDelegateImpl::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
......@@ -995,21 +1010,55 @@ void InstantLoader::SendBoundsToPage(bool force_if_waiting) {
}
}
void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) {
TabContents* new_contents =
new TabContents(
tab_contents->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
preview_contents_.reset(new TabContentsWrapper(new_contents));
void InstantLoader::ReplacePreviewContents(TabContentsWrapper* old_tc,
TabContentsWrapper* new_tc) {
DCHECK(old_tc == preview_contents_);
// We release here without deleting so that the caller still has reponsibility
// for deleting the TabContentsWrapper.
ignore_result(preview_contents_.release());
preview_contents_.reset(new_tc);
// Make sure the new preview contents acts like the old one.
SetupPreviewContents(old_tc);
// Cleanup the old preview contents.
old_tc->download_tab_helper()->set_delegate(NULL);
old_tc->tab_contents()->set_delegate(NULL);
old_tc->set_delegate(NULL);
#if defined(OS_MACOSX)
registrar_.Remove(this,
NotificationType::RENDER_VIEW_HOST_CHANGED,
Source<NavigationController>(&old_tc->controller()));
#endif
registrar_.Remove(this,
NotificationType::NAV_ENTRY_COMMITTED,
Source<NavigationController>(&old_tc->controller()));
// We prerendered so we should be ready to show. If we're ready, swap in
// immediately, otherwise show the preview as normal.
if (ready_)
delegate_->SwappedTabContents(this);
else
ShowPreview();
}
void InstantLoader::SetupPreviewContents(TabContentsWrapper* tab_contents) {
preview_contents_->set_delegate(preview_tab_contents_delegate_.get());
preview_contents_->tab_contents()->set_delegate(
preview_tab_contents_delegate_.get());
preview_contents_->blocked_content_tab_helper()->SetAllContentsBlocked(true);
preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this));
new_contents->set_delegate(preview_tab_contents_delegate_.get());
// Propagate the max page id. That way if we end up merging the two
// NavigationControllers (which happens if we commit) none of the page ids
// will overlap.
int32 max_page_id = tab_contents->tab_contents()->GetMaxPageID();
if (max_page_id != -1)
preview_contents_->controller().set_max_restored_page_id(max_page_id + 1);
preview_contents_->download_tab_helper()->set_delegate(
preview_tab_contents_delegate_.get());
gfx::Rect tab_bounds;
tab_contents->view()->GetContainerBounds(&tab_bounds);
preview_contents_->view()->SizeContents(tab_bounds.size());
#if defined(OS_MACOSX)
// If |preview_contents_| does not currently have a RWHV, we will call
// SetTakesFocusOnlyOnMouseDown() as a result of the
......@@ -1029,5 +1078,18 @@ void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) {
NotificationType::NAV_ENTRY_COMMITTED,
Source<NavigationController>(&preview_contents_->controller()));
gfx::Rect tab_bounds;
tab_contents->view()->GetContainerBounds(&tab_bounds);
preview_contents_->view()->SizeContents(tab_bounds.size());
}
void InstantLoader::CreatePreviewContents(TabContentsWrapper* tab_contents) {
TabContents* new_contents =
new TabContents(
tab_contents->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
preview_contents_.reset(new TabContentsWrapper(new_contents));
preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this));
SetupPreviewContents(tab_contents);
preview_contents_->tab_contents()->ShowContents();
}
......@@ -150,6 +150,15 @@ class InstantLoader : public NotificationObserver {
// waiting on the load and |force_if_loading| is false this does nothing.
void SendBoundsToPage(bool force_if_loading);
// Called when the TabContentsDelegate wants to swap a new TabContentsWrapper
// into our |preview_contents_|.
void ReplacePreviewContents(TabContentsWrapper* old_tc,
TabContentsWrapper* new_tc);
// Called to set up the |preview_contents_| based on |tab_contents| when it is
// created or replaced.
void SetupPreviewContents(TabContentsWrapper* tab_contents);
// Creates and sets the preview TabContentsWrapper.
void CreatePreviewContents(TabContentsWrapper* tab_contents);
......
......@@ -45,6 +45,9 @@ class InstantLoaderDelegate {
// Adds the specified url to the set of urls instant won't prefetch for.
virtual void AddToBlacklist(InstantLoader* loader, const GURL& url) = 0;
// Invoked if the loader swaps to a different TabContents.
virtual void SwappedTabContents(InstantLoader* loader) = 0;
protected:
virtual ~InstantLoaderDelegate() {}
};
......
......@@ -39,6 +39,9 @@ class InstantLoaderDelegateImpl : public InstantLoaderDelegate {
const GURL& url) OVERRIDE {
}
virtual void SwappedTabContents(InstantLoader* loader) OVERRIDE {
}
private:
DISALLOW_COPY_AND_ASSIGN(InstantLoaderDelegateImpl);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment