summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-16 23:33:28 +0000
committertburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-16 23:33:28 +0000
commitc831a652ec307806bc3a90f4b30942f03960f6e0 (patch)
tree2ed8cd7a84a3b0ea055c5f0ae05e02c25a9d30d8
parentc2f3435e3c74fe127af027528126b06dc11e8d66 (diff)
downloadchromium_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.cc42
-rw-r--r--chrome/browser/browsing_data/browsing_data_remover.h8
-rw-r--r--chrome/browser/predictors/logged_in_predictor_table.cc125
-rw-r--r--chrome/browser/predictors/logged_in_predictor_table.h54
-rw-r--r--chrome/browser/predictors/predictor_database.cc11
-rw-r--r--chrome/browser/predictors/predictor_database.h2
-rw-r--r--chrome/browser/prerender/prerender_field_trial.cc24
-rw-r--r--chrome/browser/prerender/prerender_field_trial.h3
-rw-r--r--chrome/browser/prerender/prerender_manager.cc15
-rw-r--r--chrome/browser/prerender/prerender_manager.h8
-rw-r--r--chrome/browser/prerender/prerender_manager_factory.cc2
-rw-r--r--chrome/browser/prerender/prerender_tab_helper.cc79
-rw-r--r--chrome/browser/prerender/prerender_tab_helper.h30
-rw-r--r--chrome/chrome_browser.gypi2
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',