diff options
author | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-16 23:33:28 +0000 |
---|---|---|
committer | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-16 23:33:28 +0000 |
commit | c831a652ec307806bc3a90f4b30942f03960f6e0 (patch) | |
tree | 2ed8cd7a84a3b0ea055c5f0ae05e02c25a9d30d8 | |
parent | c2f3435e3c74fe127af027528126b06dc11e8d66 (diff) | |
download | chromium_src-c831a652ec307806bc3a90f4b30942f03960f6e0.zip chromium_src-c831a652ec307806bc3a90f4b30942f03960f6e0.tar.gz chromium_src-c831a652ec307806bc3a90f4b30942f03960f6e0.tar.bz2 |
Add the LoggedIn Predictor, to detect which websites a user is likely
logged into (or has been logged into).
R=shishir@chromium.org, bauerb@chromium.org
Review URL: https://codereview.chromium.org/13903018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194484 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browsing_data/browsing_data_remover.cc | 42 | ||||
-rw-r--r-- | chrome/browser/browsing_data/browsing_data_remover.h | 8 | ||||
-rw-r--r-- | chrome/browser/predictors/logged_in_predictor_table.cc | 125 | ||||
-rw-r--r-- | chrome/browser/predictors/logged_in_predictor_table.h | 54 | ||||
-rw-r--r-- | chrome/browser/predictors/predictor_database.cc | 11 | ||||
-rw-r--r-- | chrome/browser/predictors/predictor_database.h | 2 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_field_trial.cc | 24 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_field_trial.h | 3 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.cc | 15 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.h | 8 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager_factory.cc | 2 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_tab_helper.cc | 79 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_tab_helper.h | 30 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
14 files changed, 404 insertions, 1 deletions
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc index f6ddee7..4fd4308 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.cc +++ b/chrome/browser/browsing_data/browsing_data_remover.cc @@ -30,6 +30,9 @@ #include "chrome/browser/net/predictor.h" #include "chrome/browser/password_manager/password_store.h" #include "chrome/browser/password_manager/password_store_factory.h" +#include "chrome/browser/predictors/logged_in_predictor_table.h" +#include "chrome/browser/predictors/predictor_database.h" +#include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/profiles/profile.h" @@ -140,6 +143,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile, waiting_for_clear_history_(false), waiting_for_clear_hostname_resolution_cache_(false), waiting_for_clear_local_storage_(false), + waiting_for_clear_logged_in_predictor_(false), waiting_for_clear_nacl_cache_(false), waiting_for_clear_network_predictor_(false), waiting_for_clear_networking_history_(false), @@ -339,6 +343,9 @@ void BrowsingDataRemover::RemoveImpl(int remove_mask, base::Bind(&BrowsingDataRemover::ClearCookiesOnIOThread, base::Unretained(this), base::Unretained(rq_context))); } + // Also delete the LoggedIn Predictor, which tries to keep track of which + // sites a user is logged into. + ClearLoggedInPredictor(); #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) // Clear the safebrowsing cookies only if time period is for "all time". It @@ -574,6 +581,7 @@ bool BrowsingDataRemover::AllDone() { !waiting_for_clear_cookies_count_&& !waiting_for_clear_history_ && !waiting_for_clear_local_storage_ && + !waiting_for_clear_logged_in_predictor_ && !waiting_for_clear_session_storage_ && !waiting_for_clear_networking_history_ && !waiting_for_clear_server_bound_certs_ && @@ -643,6 +651,40 @@ void BrowsingDataRemover::ClearHostnameResolutionCacheOnIOThread( base::Unretained(this))); } +void BrowsingDataRemover::OnClearedLoggedInPredictor() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(waiting_for_clear_logged_in_predictor_); + waiting_for_clear_logged_in_predictor_ = false; + NotifyAndDeleteIfDone(); +} + +void BrowsingDataRemover::ClearLoggedInPredictor() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!waiting_for_clear_logged_in_predictor_); + + predictors::PredictorDatabase* predictor_db = + predictors::PredictorDatabaseFactory::GetForProfile(profile_); + if (!predictor_db) + return; + + predictors::LoggedInPredictorTable* logged_in_table = + predictor_db->logged_in_table(); + if (!logged_in_table) + return; + + waiting_for_clear_logged_in_predictor_ = true; + + BrowserThread::PostTaskAndReply( + BrowserThread::DB, + FROM_HERE, + base::Bind(&predictors::LoggedInPredictorTable::DeleteAllCreatedBetween, + logged_in_table, + delete_begin_, + delete_end_), + base::Bind(&BrowsingDataRemover::OnClearedLoggedInPredictor, + base::Unretained(this))); +} + void BrowsingDataRemover::OnClearedNetworkPredictor() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); waiting_for_clear_network_predictor_ = false; diff --git a/chrome/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h index fbb563e..2abe9e2 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.h +++ b/chrome/browser/browsing_data/browsing_data_remover.h @@ -244,6 +244,13 @@ class BrowsingDataRemover : public content::NotificationObserver // Invoked on the IO thread to clear the hostname resolution cache. void ClearHostnameResolutionCacheOnIOThread(IOThread* io_thread); + // Callback when the LoggedIn Predictor has been cleared. + // Clears the respective waiting flag and invokes NotifyAndDeleteIfDone. + void OnClearedLoggedInPredictor(); + + // Clears the LoggedIn Predictor. + void ClearLoggedInPredictor(); + // Callback when speculative data in the network Predictor has been cleared. // Clears the respective waiting flag and invokes NotifyAndDeleteIfDone. void OnClearedNetworkPredictor(); @@ -402,6 +409,7 @@ class BrowsingDataRemover : public content::NotificationObserver bool waiting_for_clear_history_; bool waiting_for_clear_hostname_resolution_cache_; bool waiting_for_clear_local_storage_; + bool waiting_for_clear_logged_in_predictor_; bool waiting_for_clear_nacl_cache_; bool waiting_for_clear_network_predictor_; bool waiting_for_clear_networking_history_; diff --git a/chrome/browser/predictors/logged_in_predictor_table.cc b/chrome/browser/predictors/logged_in_predictor_table.cc new file mode 100644 index 0000000..f251ba6 --- /dev/null +++ b/chrome/browser/predictors/logged_in_predictor_table.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2013 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/predictors/logged_in_predictor_table.h" + +#include <algorithm> +#include <utility> +#include "base/logging.h" +#include "base/metrics/histogram.h" +#include "base/stringprintf.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "sql/statement.h" + +using content::BrowserThread; +using sql::Statement; +using std::string; + +namespace { + +const char kTableName[] = "logged_in_predictor"; + +} // namespace + +namespace predictors { + +LoggedInPredictorTable::LoggedInPredictorTable() + : PredictorTableBase() { +} + +LoggedInPredictorTable::~LoggedInPredictorTable() { +} + +string LoggedInPredictorTable::GetKey(const GURL& url) const { + string effective_domain( + net::RegistryControlledDomainService::GetDomainAndRegistry(url.host())); + if (effective_domain.empty()) + effective_domain = url.host(); + + // Strip off a preceding ".", if present. + if (!effective_domain.empty() && effective_domain[0] == '.') + return effective_domain.substr(1); + return effective_domain; +} + +void LoggedInPredictorTable::Add(const GURL& url) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + if (CantAccessDatabase()) + return; + + Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE, + base::StringPrintf("INSERT OR IGNORE INTO %s (domain, time) VALUES (?,?)", + kTableName).c_str())); + + statement.BindString(0, GetKey(url)); + statement.BindInt64(1, base::Time::Now().ToInternalValue()); + + statement.Run(); +} + +void LoggedInPredictorTable::HasUserLoggedIn(const GURL& url, bool* is_present, + bool* lookup_succeeded) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + *lookup_succeeded = false; + if (CantAccessDatabase()) + return; + + Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE, + base::StringPrintf("SELECT count(*) FROM %s WHERE domain=?", + kTableName).c_str())); + + statement.BindString(0, GetKey(url)); + + if (statement.Step()) { + *is_present = (statement.ColumnInt(0) > 0); + *lookup_succeeded = true; + } +} + +void LoggedInPredictorTable::DeleteAllCreatedBetween( + const base::Time& delete_begin, const base::Time& delete_end) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + if (CantAccessDatabase()) + return; + + Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE, + base::StringPrintf("DELETE FROM %s WHERE time >= ? AND time <= ?", + kTableName).c_str())); + + statement.BindInt64(0, delete_begin.ToInternalValue()); + statement.BindInt64(1, delete_end.ToInternalValue()); + + statement.Run(); +} + +void LoggedInPredictorTable::CreateTableIfNonExistent() { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + if (CantAccessDatabase()) + return; + + sql::Connection* db = DB(); + if (db->DoesTableExist(kTableName)) + return; + + const char* table_creator = + "CREATE TABLE %s (domain TEXT, time INTEGER, PRIMARY KEY(domain))"; + + if (!db->Execute(base::StringPrintf(table_creator, kTableName).c_str())) + ResetDB(); +} + +void LoggedInPredictorTable::LogDatabaseStats() { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + if (CantAccessDatabase()) + return; + + Statement statement(DB()->GetCachedStatement(SQL_FROM_HERE, + base::StringPrintf("SELECT count(*) FROM %s", kTableName).c_str())); + if (statement.Step()) + UMA_HISTOGRAM_COUNTS("LoggedInPredictor.TableRowCount", + statement.ColumnInt(0)); +} + +} // namespace predictors diff --git a/chrome/browser/predictors/logged_in_predictor_table.h b/chrome/browser/predictors/logged_in_predictor_table.h new file mode 100644 index 0000000..4f2abce --- /dev/null +++ b/chrome/browser/predictors/logged_in_predictor_table.h @@ -0,0 +1,54 @@ +// Copyright (c) 2013 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. + +#ifndef CHROME_BROWSER_PREDICTORS_LOGGED_IN_PREDICTOR_TABLE_H_ +#define CHROME_BROWSER_PREDICTORS_LOGGED_IN_PREDICTOR_TABLE_H_ + +#include <string> + +#include "base/time.h" +#include "chrome/browser/predictors/predictor_table_base.h" +#include "googleurl/src/gurl.h" + +namespace sql { +class Statement; +} + +namespace predictors { + +// Interface for database table to keep track of what sites a user is logged +// in to. +// All methods except the constructor and destructor need to be called on the DB +// thread. +// Manages one table { domain (primary key), added_timestamp }. +class LoggedInPredictorTable : public PredictorTableBase { + public: + // Adds the relevant part of the domain of the URL provided to the database + // as the user having performed a login action. + void Add(const GURL& url); + // Checks whether for the relevant part of the domain of the URL provided, + // the user has performed a login action in the past. + void HasUserLoggedIn(const GURL& url, bool* is_present, + bool* lookup_succeeded); + void DeleteAllCreatedBetween(const base::Time& delete_begin, + const base::Time& delete_end); + + private: + friend class PredictorDatabaseInternal; + + LoggedInPredictorTable(); + virtual ~LoggedInPredictorTable(); + + // PredictorTableBase methods. + virtual void CreateTableIfNonExistent() OVERRIDE; + virtual void LogDatabaseStats() OVERRIDE; + + std::string GetKey(const GURL& url) const; + + DISALLOW_COPY_AND_ASSIGN(LoggedInPredictorTable); +}; + +} // namespace predictors + +#endif // CHROME_BROWSER_PREDICTORS_LOGGED_IN_PREDICTOR_TABLE_H_ diff --git a/chrome/browser/predictors/predictor_database.cc b/chrome/browser/predictors/predictor_database.cc index 69e088d..f619491 100644 --- a/chrome/browser/predictors/predictor_database.cc +++ b/chrome/browser/predictors/predictor_database.cc @@ -11,6 +11,7 @@ #include "base/metrics/histogram.h" #include "base/stringprintf.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" +#include "chrome/browser/predictors/logged_in_predictor_table.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "chrome/browser/prerender/prerender_field_trial.h" @@ -58,6 +59,7 @@ class PredictorDatabaseInternal // TODO(shishir): These tables may not need to be refcounted. Maybe move them // to using a WeakPtr instead. scoped_refptr<AutocompleteActionPredictorTable> autocomplete_table_; + scoped_refptr<LoggedInPredictorTable> logged_in_table_; scoped_refptr<ResourcePrefetchPredictorTables> resource_prefetch_tables_; DISALLOW_COPY_AND_ASSIGN(PredictorDatabaseInternal); @@ -68,6 +70,7 @@ PredictorDatabaseInternal::PredictorDatabaseInternal(Profile* profile) : db_path_(profile->GetPath().Append(kPredictorDatabaseName)), db_(new sql::Connection()), autocomplete_table_(new AutocompleteActionPredictorTable()), + logged_in_table_(new LoggedInPredictorTable()), resource_prefetch_tables_(new ResourcePrefetchPredictorTables()) { ResourcePrefetchPredictorConfig config; is_resource_prefetch_predictor_enabled_ = @@ -89,6 +92,7 @@ void PredictorDatabaseInternal::Initialize() { return; autocomplete_table_->Initialize(db_.get()); + logged_in_table_->Initialize(db_.get()); resource_prefetch_tables_->Initialize(db_.get()); LogDatabaseStats(); @@ -98,6 +102,7 @@ void PredictorDatabaseInternal::SetCancelled() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); autocomplete_table_->SetCancelled(); + logged_in_table_->SetCancelled(); resource_prefetch_tables_->SetCancelled(); } @@ -111,6 +116,7 @@ void PredictorDatabaseInternal::LogDatabaseStats() { static_cast<int>(db_size / 1024)); autocomplete_table_->LogDatabaseStats(); + logged_in_table_->LogDatabaseStats(); if (is_resource_prefetch_predictor_enabled_) resource_prefetch_tables_->LogDatabaseStats(); } @@ -133,6 +139,11 @@ scoped_refptr<AutocompleteActionPredictorTable> return db_->autocomplete_table_; } +scoped_refptr<LoggedInPredictorTable> + PredictorDatabase::logged_in_table() { + return db_->logged_in_table_; +} + scoped_refptr<ResourcePrefetchPredictorTables> PredictorDatabase::resource_prefetch_tables() { return db_->resource_prefetch_tables_; diff --git a/chrome/browser/predictors/predictor_database.h b/chrome/browser/predictors/predictor_database.h index 1692e33..fcdfd4d 100644 --- a/chrome/browser/predictors/predictor_database.h +++ b/chrome/browser/predictors/predictor_database.h @@ -17,6 +17,7 @@ class Connection; namespace predictors { class AutocompleteActionPredictorTable; +class LoggedInPredictorTable; class PredictorDatabaseInternal; class ResourcePrefetchPredictorTables; @@ -27,6 +28,7 @@ class PredictorDatabase : public ProfileKeyedService { scoped_refptr<AutocompleteActionPredictorTable> autocomplete_table(); scoped_refptr<ResourcePrefetchPredictorTables> resource_prefetch_tables(); + scoped_refptr<LoggedInPredictorTable> logged_in_table(); // Used for testing. sql::Connection* GetDatabase(); diff --git a/chrome/browser/prerender/prerender_field_trial.cc b/chrome/browser/prerender/prerender_field_trial.cc index 6ff8c6a..312c9fb 100644 --- a/chrome/browser/prerender/prerender_field_trial.cc +++ b/chrome/browser/prerender/prerender_field_trial.cc @@ -29,6 +29,10 @@ int g_omnibox_trial_default_group_number = kint32min; const char kLocalPredictorTrialName[] = "PrerenderLocalPredictor"; const char kLocalPredictorEnabledGroup[] = "Enabled"; +const char kLoggedInPredictorTrialName[] = "PrerenderLoggedInPredictor"; +const char kLoggedInPredictorEnabledGroup[] = "Enabled"; +const char kLoggedInPredictorDisabledGroup[] = "Disabled"; + void SetupPrefetchFieldTrial() { chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); if (channel == chrome::VersionInfo::CHANNEL_STABLE || @@ -141,6 +145,7 @@ void SetupPrerenderFieldTrial() { } // end namespace void ConfigureOmniboxPrerender(); +void ConfigureLoggedInPredictor(); void ConfigurePrefetchAndPrerender(const CommandLine& command_line) { enum PrerenderOption { @@ -197,6 +202,7 @@ void ConfigurePrefetchAndPrerender(const CommandLine& command_line) { } ConfigureOmniboxPrerender(); + ConfigureLoggedInPredictor(); } void ConfigureOmniboxPrerender() { @@ -217,6 +223,19 @@ void ConfigureOmniboxPrerender() { kDisabledProbability); } +void ConfigureLoggedInPredictor() { + chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); + if (channel == chrome::VersionInfo::CHANNEL_STABLE || + channel == chrome::VersionInfo::CHANNEL_BETA) { + return; + } + scoped_refptr<FieldTrial> logged_in_predictor_trial( + FieldTrialList::FactoryGetFieldTrial( + kLoggedInPredictorTrialName, 100, + kLoggedInPredictorDisabledGroup, 2013, 12, 31, NULL)); + logged_in_predictor_trial->AppendGroup(kLoggedInPredictorEnabledGroup, 100); +} + bool IsOmniboxEnabled(Profile* profile) { if (!profile) return false; @@ -250,4 +269,9 @@ bool IsLocalPredictorEnabled() { kLocalPredictorEnabledGroup; } +bool IsLoggedInPredictorEnabled() { + return base::FieldTrialList::FindFullName(kLoggedInPredictorTrialName) == + kLoggedInPredictorEnabledGroup; +} + } // namespace prerender diff --git a/chrome/browser/prerender/prerender_field_trial.h b/chrome/browser/prerender/prerender_field_trial.h index 534cb89..7ce9d9a 100644 --- a/chrome/browser/prerender/prerender_field_trial.h +++ b/chrome/browser/prerender/prerender_field_trial.h @@ -24,6 +24,9 @@ bool IsOmniboxEnabled(Profile* profile); // Returns true iff the Prerender Local Predictor is enabled. bool IsLocalPredictorEnabled(); +// Returns true iff the LoggedIn Predictor is enabled. +bool IsLoggedInPredictorEnabled(); + } // namespace prerender #endif // CHROME_BROWSER_PRERENDER_PRERENDER_FIELD_TRIAL_H_ diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index 7210591..8b08265 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc @@ -22,6 +22,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/common/cancelable_request.h" #include "chrome/browser/favicon/favicon_tab_helper.h" +#include "chrome/browser/predictors/logged_in_predictor_table.h" +#include "chrome/browser/predictors/predictor_database.h" +#include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/browser/prerender/prerender_condition.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/prerender/prerender_field_trial.h" @@ -205,6 +208,13 @@ PrerenderManager::PrerenderManager(Profile* profile, if (IsLocalPredictorEnabled()) local_predictor_.reset(new PrerenderLocalPredictor(this)); + if (IsLoggedInPredictorEnabled() && !profile_->IsOffTheRecord()) { + predictors::PredictorDatabase* predictor_db = + predictors::PredictorDatabaseFactory::GetForProfile(profile); + if (predictor_db) + logged_in_predictor_table_ = predictor_db->logged_in_table(); + } + // Certain experiments override our default config_ values. switch (PrerenderManager::GetMode()) { case PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP: @@ -226,6 +236,11 @@ PrerenderManager::~PrerenderManager() { DCHECK(to_delete_prerenders_.empty()); } +scoped_refptr<predictors::LoggedInPredictorTable> +PrerenderManager::logged_in_predictor_table() { + return logged_in_predictor_table_; +} + void PrerenderManager::Shutdown() { DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); STLDeleteElements(&prerender_conditions_); diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index 9b0b7fc..fc4495a 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h @@ -40,6 +40,10 @@ namespace gfx { class Size; } +namespace predictors { +class LoggedInPredictorTable; +} + #if defined(COMPILER_GCC) namespace BASE_HASH_NAMESPACE { @@ -272,6 +276,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, virtual base::Time GetCurrentTime() const; virtual base::TimeTicks GetCurrentTimeTicks() const; + scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table(); + protected: class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { public: @@ -573,6 +579,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, scoped_ptr<PrerenderLocalPredictor> local_predictor_; + scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_; + DISALLOW_COPY_AND_ASSIGN(PrerenderManager); }; diff --git a/chrome/browser/prerender/prerender_manager_factory.cc b/chrome/browser/prerender/prerender_manager_factory.cc index f676d08..6d9cdb4 100644 --- a/chrome/browser/prerender/prerender_manager_factory.cc +++ b/chrome/browser/prerender/prerender_manager_factory.cc @@ -7,6 +7,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_dependency_manager.h" @@ -38,6 +39,7 @@ PrerenderManagerFactory::PrerenderManagerFactory() DependsOn(extensions::ExtensionSystemFactory::GetInstance()); // PrerenderLocalPredictor observers the history visit DB. DependsOn(HistoryServiceFactory::GetInstance()); + DependsOn(predictors::PredictorDatabaseFactory::GetInstance()); } PrerenderManagerFactory::~PrerenderManagerFactory() { diff --git a/chrome/browser/prerender/prerender_tab_helper.cc b/chrome/browser/prerender/prerender_tab_helper.cc index e74186e..bd04fd2 100644 --- a/chrome/browser/prerender/prerender_tab_helper.cc +++ b/chrome/browser/prerender/prerender_tab_helper.cc @@ -7,13 +7,18 @@ #include "base/metrics/histogram.h" #include "base/strings/string_number_conversions.h" #include "base/time.h" +#include "chrome/browser/predictors/logged_in_predictor_table.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/browser_thread.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" +#include "content/public/common/frame_navigate_params.h" #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/rect.h" @@ -128,7 +133,8 @@ class PrerenderTabHelper::PixelStats { }; PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) { + : content::WebContentsObserver(web_contents), + weak_factory_(this) { } PrerenderTabHelper::~PrerenderTabHelper() { @@ -138,6 +144,8 @@ void PrerenderTabHelper::ProvisionalChangeToMainFrameUrl( const GURL& url, content::RenderViewHost* render_view_host) { url_ = url; + RecordEvent(EVENT_MAINFRAME_CHANGE); + RecordEventIfLoggedInURL(EVENT_MAINFRAME_CHANGE_DOMAIN_LOGGED_IN, url); PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); if (!prerender_manager) return; @@ -154,6 +162,9 @@ void PrerenderTabHelper::DidCommitProvisionalLoadForFrame( content::RenderViewHost* render_view_host) { if (!is_main_frame) return; + RecordEvent(EVENT_MAINFRAME_COMMIT); + RecordEventIfLoggedInURL(EVENT_MAINFRAME_COMMIT_DOMAIN_LOGGED_IN, + validated_url); url_ = validated_url; PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); if (!prerender_manager) @@ -210,11 +221,40 @@ void PrerenderTabHelper::DidStartProvisionalLoadForFrame( } } +void PrerenderTabHelper::DidNavigateAnyFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) { + scoped_refptr<predictors::LoggedInPredictorTable> logged_in_table = + MaybeGetLoggedInTable(); + if (params.password_form.origin.is_valid() && logged_in_table.get()) { + content::BrowserThread::PostTask( + content::BrowserThread::DB, FROM_HERE, + base::Bind(&predictors::LoggedInPredictorTable::Add, + logged_in_table, + params.url)); + RecordEvent(EVENT_LOGIN_ACTION_ADDED); + } +} + PrerenderManager* PrerenderTabHelper::MaybeGetPrerenderManager() const { return PrerenderManagerFactory::GetForProfile( Profile::FromBrowserContext(web_contents()->GetBrowserContext())); } +scoped_refptr<predictors::LoggedInPredictorTable> +PrerenderTabHelper::MaybeGetLoggedInTable() const { + RecordEvent(EVENT_LOGGED_IN_TABLE_REQUESTED); + PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); + if (prerender_manager) { + predictors::LoggedInPredictorTable* result = + prerender_manager->logged_in_predictor_table(); + if (result) + RecordEvent(EVENT_LOGGED_IN_TABLE_PRESENT); + return result; + } + return NULL; +} + bool PrerenderTabHelper::IsPrerendering() { PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); if (!prerender_manager) @@ -249,4 +289,41 @@ void PrerenderTabHelper::PrerenderSwappedIn() { } } +void PrerenderTabHelper::RecordEvent(PrerenderTabHelper::Event event) const { + UMA_HISTOGRAM_ENUMERATION("Prerender.TabHelperEvent", + event, PrerenderTabHelper::EVENT_MAX_VALUE); +} + +void PrerenderTabHelper::RecordEventIfLoggedInURL( + PrerenderTabHelper::Event event, const GURL& url) { + scoped_refptr<predictors::LoggedInPredictorTable> logged_in_table = + MaybeGetLoggedInTable(); + if (!logged_in_table.get()) + return; + scoped_ptr<bool> is_present(new bool); + scoped_ptr<bool> lookup_succeeded(new bool); + bool* is_present_ptr = is_present.get(); + bool* lookup_succeeded_ptr = lookup_succeeded.get(); + content::BrowserThread::PostTaskAndReply( + content::BrowserThread::DB, FROM_HERE, + base::Bind(&predictors::LoggedInPredictorTable::HasUserLoggedIn, + logged_in_table, + url, + is_present_ptr, + lookup_succeeded_ptr), + base::Bind(&PrerenderTabHelper::RecordEventIfLoggedInURLResult, + weak_factory_.GetWeakPtr(), + event, + base::Passed(&is_present), + base::Passed(&lookup_succeeded))); +} + +void PrerenderTabHelper::RecordEventIfLoggedInURLResult( + PrerenderTabHelper::Event event, + scoped_ptr<bool> is_present, + scoped_ptr<bool> lookup_succeeded) { + if (*lookup_succeeded && *is_present) + RecordEvent(event); +} + } // namespace prerender diff --git a/chrome/browser/prerender/prerender_tab_helper.h b/chrome/browser/prerender/prerender_tab_helper.h index 4c47e3b..92fa567 100644 --- a/chrome/browser/prerender/prerender_tab_helper.h +++ b/chrome/browser/prerender/prerender_tab_helper.h @@ -6,11 +6,16 @@ #define CHROME_BROWSER_PRERENDER_PRERENDER_TAB_HELPER_H_ #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/time.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "googleurl/src/gurl.h" +namespace predictors { +class LoggedInPredictorTable; +} + namespace prerender { class PrerenderManager; @@ -21,6 +26,17 @@ class PrerenderTabHelper : public content::WebContentsObserver, public content::WebContentsUserData<PrerenderTabHelper> { public: + enum Event { + EVENT_LOGGED_IN_TABLE_REQUESTED = 0, + EVENT_LOGGED_IN_TABLE_PRESENT = 1, + EVENT_MAINFRAME_CHANGE = 2, + EVENT_MAINFRAME_CHANGE_DOMAIN_LOGGED_IN = 3, + EVENT_MAINFRAME_COMMIT = 4, + EVENT_MAINFRAME_COMMIT_DOMAIN_LOGGED_IN = 5, + EVENT_LOGIN_ACTION_ADDED = 6, + EVENT_MAX_VALUE + }; + virtual ~PrerenderTabHelper(); // content::WebContentsObserver implementation. @@ -43,6 +59,10 @@ class PrerenderTabHelper const GURL& validated_url, content::PageTransition transition_type, content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DidNavigateAnyFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) OVERRIDE; + // Called when this prerendered WebContents has just been swapped in. void PrerenderSwappedIn(); @@ -50,6 +70,10 @@ class PrerenderTabHelper explicit PrerenderTabHelper(content::WebContents* web_contents); friend class content::WebContentsUserData<PrerenderTabHelper>; + void RecordEvent(Event event) const; + void RecordEventIfLoggedInURL(Event event, const GURL& url); + void RecordEventIfLoggedInURLResult(Event event, scoped_ptr<bool> is_present, + scoped_ptr<bool> lookup_succeeded); // Helper class to compute pixel-based stats on the paint progress // between when a prerendered page is swapped in and when the onload event // fires. @@ -59,6 +83,10 @@ class PrerenderTabHelper // Retrieves the PrerenderManager, or NULL, if none was found. PrerenderManager* MaybeGetPrerenderManager() const; + // Retrieves the LoggedInPredictorTable, or NULL, if none was found. + scoped_refptr<predictors::LoggedInPredictorTable> + MaybeGetLoggedInTable() const; + // Returns whether the WebContents being observed is currently prerendering. bool IsPrerendering(); @@ -77,6 +105,8 @@ class PrerenderTabHelper // Current URL being loaded. GURL url_; + base::WeakPtrFactory<PrerenderTabHelper> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PrerenderTabHelper); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index cda5d6c..87b8981 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1336,6 +1336,8 @@ 'browser/predictors/autocomplete_action_predictor_factory.h', 'browser/predictors/autocomplete_action_predictor_table.cc', 'browser/predictors/autocomplete_action_predictor_table.h', + 'browser/predictors/logged_in_predictor_table.cc', + 'browser/predictors/logged_in_predictor_table.h', 'browser/predictors/predictor_database.cc', 'browser/predictors/predictor_database.h', 'browser/predictors/predictor_database_factory.cc', |