blob: 04ed554260ac754cf8b39facb93a98c8d368c7c1 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prerender/prerender_tab_helper.h"
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "chrome/browser/prerender/prerender_histograms.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/web_contents.h"
using content::WebContents;
DEFINE_WEB_CONTENTS_USER_DATA_KEY(prerender::PrerenderTabHelper);
namespace prerender {
PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
origin_(ORIGIN_NONE),
weak_factory_(this) {}
PrerenderTabHelper::~PrerenderTabHelper() {
}
void PrerenderTabHelper::DidGetRedirectForResourceRequest(
const content::ResourceRedirectDetails& details) {
if (details.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
return;
MainFrameUrlDidChange(details.new_url);
}
void PrerenderTabHelper::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame() ||
!navigation_handle->HasCommitted() ||
navigation_handle->IsErrorPage()) {
return;
}
url_ = navigation_handle->GetURL();
PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
if (!prerender_manager)
return;
if (prerender_manager->IsWebContentsPrerendering(web_contents(), NULL))
return;
prerender_manager->RecordNavigation(url_);
}
void PrerenderTabHelper::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
// Determine the origin.
PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
if (prerender_manager)
prerender_manager->IsWebContentsPrerendering(web_contents(), &origin_);
if (navigation_handle->IsSameDocument())
return;
if (!navigation_handle->IsInMainFrame())
return;
MainFrameUrlDidChange(navigation_handle->GetURL());
}
void PrerenderTabHelper::MainFrameUrlDidChange(const GURL& url) {
url_ = url;
}
PrerenderManager* PrerenderTabHelper::MaybeGetPrerenderManager() const {
return PrerenderManagerFactory::GetForBrowserContext(
web_contents()->GetBrowserContext());
}
base::TimeTicks PrerenderTabHelper::GetTimeTicksFromPrerenderManager() const {
// Prerender browser tests should always have a PrerenderManager when mocking
// out tick clock.
PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
if (prerender_manager)
return prerender_manager->GetCurrentTimeTicks();
// Fall back to returning the same value as PrerenderManager would have
// returned in production.
return base::TimeTicks::Now();
}
bool PrerenderTabHelper::IsPrerendering() {
PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
if (!prerender_manager)
return false;
return prerender_manager->IsWebContentsPrerendering(web_contents(), NULL);
}
void PrerenderTabHelper::PrerenderSwappedIn() {
DCHECK(!IsPrerendering());
swap_ticks_ = GetTimeTicksFromPrerenderManager();
}
} // namespace prerender