Chromium Code Reviews| Index: chrome/browser/prerender/prerender_local_predictor.cc |
| =================================================================== |
| --- chrome/browser/prerender/prerender_local_predictor.cc (revision 0) |
| +++ chrome/browser/prerender/prerender_local_predictor.cc (revision 0) |
| @@ -0,0 +1,136 @@ |
| +// 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_local_predictor.h" |
| + |
| +#include "base/timer.h" |
| +#include "chrome/browser/prerender/prerender_manager.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/history/history.h" |
| +#include "chrome/browser/history/history_database.h" |
| +#include "content/public/browser/browser_thread.h" |
| + |
| +using content::BrowserThread; |
| + |
| +namespace prerender { |
| + |
| +namespace { |
| + |
| +// Task to lookup the URL for a given URLID. |
| +class GetURLForURLIDTask : public HistoryDBTask { |
| + public: |
| + GetURLForURLIDTask(PrerenderLocalPredictor* local_predictor, |
| + history::URLID url_id) |
| + : local_predictor_(local_predictor), |
| + url_id_(url_id), |
| + success_(false) { |
| + } |
| + virtual bool RunOnDBThread(history::HistoryBackend* backend, |
| + history::HistoryDatabase* db) { |
| + history::URLRow url_row; |
| + success_ = db->GetURLRow(url_id_, &url_row); |
| + if (success_) |
| + url_ = url_row.url(); |
| + return true; |
| + } |
| + virtual void DoneRunOnMainThread() { |
| + if (success_) |
| + local_predictor_->OnLookupURL(url_id_, url_); |
| + } |
| + private: |
| + PrerenderLocalPredictor* local_predictor_; |
| + history::URLID url_id_; |
| + bool success_; |
| + GURL url_; |
| + DISALLOW_COPY_AND_ASSIGN(GetURLForURLIDTask); |
| +}; |
| + |
| +// Task to load history from the visit database on startup. |
| +class GetVisitHistoryTask : public HistoryDBTask { |
| + public: |
| + GetVisitHistoryTask(PrerenderLocalPredictor* local_predictor, |
| + int max_visits) |
| + : local_predictor_(local_predictor), |
| + max_visits_(max_visits), |
| + visit_history_(new std::vector<history::BriefVisitInfo>) { |
| + } |
| + virtual bool RunOnDBThread(history::HistoryBackend* backend, |
| + history::HistoryDatabase* db) { |
| + db->GetBriefVisitInfoOfMostRecentVisits(max_visits_, visit_history_.get()); |
| + return true; |
| + } |
| + virtual void DoneRunOnMainThread() { |
| + local_predictor_->OnGetInitialVisitHistory(visit_history_.release()); |
| + } |
| + private: |
| + PrerenderLocalPredictor* local_predictor_; |
| + int max_visits_; |
| + scoped_ptr<std::vector<history::BriefVisitInfo> > visit_history_; |
| + DISALLOW_COPY_AND_ASSIGN(GetVisitHistoryTask); |
| +}; |
| + |
| +}; |
| + |
| +HistoryService* PrerenderLocalPredictor::GetHistoryIfExists() const { |
| + Profile* profile = prerender_manager_->profile(); |
| + if (!profile) |
| + return NULL; |
| + return profile->GetHistoryServiceWithoutCreating(); |
| +} |
| + |
| +PrerenderLocalPredictor::PrerenderLocalPredictor( |
| + PrerenderManager* prerender_manager) |
| + : prerender_manager_(prerender_manager), |
| + visit_history_initialized_(false) { |
| + if (MessageLoop::current()) { |
| + timer_.Start(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(kInitDelayMs), |
| + this, |
| + &PrerenderLocalPredictor::Init); |
|
cbentzel
2012/04/17 20:28:16
Potential for a use-after-free here if the Predict
tburkard
2012/04/17 20:51:36
Shouldn't, because timer_ takes care of this (when
cbentzel
2012/04/17 20:57:51
Yeah, you are right.
|
| + } |
| +} |
| + |
| +void PrerenderLocalPredictor::OnGetInitialVisitHistory( |
| + std::vector<history::BriefVisitInfo>* visit_history) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(!visit_history_initialized_); |
| + visit_history_.reset(visit_history); |
| + visit_history_initialized_ = true; |
| +} |
| + |
| +void PrerenderLocalPredictor::Init() { |
| + HistoryService* history = GetHistoryIfExists(); |
| + if (!history) { |
| + // TODO(tburkard): Record this somewhere (eg histogram) and/or try again |
| + // later. |
| + return; |
| + } |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + history->ScheduleDBTask( |
| + new GetVisitHistoryTask(this, kMaxVisitHistory), |
| + &history_db_consumer_); |
| + history->AddVisitDatabaseObserver(this); |
| +} |
| + |
| +void PrerenderLocalPredictor::OnAddVisit(history::BriefVisitInfo info) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + HistoryService* history = GetHistoryIfExists(); |
| + if (history) { |
| + history->ScheduleDBTask( |
| + new GetURLForURLIDTask(this, info.url_id), |
|
cbentzel
2012/04/17 20:28:16
Why do you need to do this? I thought the whole pu
tburkard
2012/04/17 20:51:36
I will eventually need to lookup URLs when I want
cbentzel
2012/04/17 20:57:51
OK. I'd just remove it for now.
|
| + &history_db_consumer_); |
| + } |
| +} |
| + |
| +PrerenderLocalPredictor::~PrerenderLocalPredictor() { |
| + HistoryService* history = GetHistoryIfExists(); |
| + if (history) |
| + history->RemoveVisitDatabaseObserver(this); |
| +} |
| + |
| +void PrerenderLocalPredictor::OnLookupURL(history::URLID url_id, GURL url) { |
| + |
| +} |
| + |
| +} // namespace prerender |