Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/password_manager/core/browser/login_database.h" | 5 #include "components/password_manager/core/browser/login_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/pickle.h" | 14 #include "base/pickle.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/stringprintf.h" | |
| 16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 17 #include "components/autofill/core/common/password_form.h" | 18 #include "components/autofill/core/common/password_form.h" |
| 19 #include "components/password_manager/core/browser/password_manager_client.h" | |
| 18 #include "google_apis/gaia/gaia_auth_util.h" | 20 #include "google_apis/gaia/gaia_auth_util.h" |
| 19 #include "google_apis/gaia/gaia_urls.h" | 21 #include "google_apis/gaia/gaia_urls.h" |
| 20 #include "sql/connection.h" | 22 #include "sql/connection.h" |
| 21 #include "sql/statement.h" | 23 #include "sql/statement.h" |
| 22 #include "sql/transaction.h" | 24 #include "sql/transaction.h" |
| 23 | 25 |
| 24 using autofill::PasswordForm; | 26 using autofill::PasswordForm; |
| 25 | 27 |
| 26 namespace password_manager { | 28 namespace password_manager { |
| 27 | 29 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); | 110 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); |
| 109 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); | 111 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); |
| 110 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); | 112 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); |
| 111 } | 113 } |
| 112 | 114 |
| 113 void AddCallback(int err, sql::Statement* /*stmt*/) { | 115 void AddCallback(int err, sql::Statement* /*stmt*/) { |
| 114 if (err == 19 /*SQLITE_CONSTRAINT*/) | 116 if (err == 19 /*SQLITE_CONSTRAINT*/) |
| 115 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; | 117 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; |
| 116 } | 118 } |
| 117 | 119 |
| 120 // UMA_* macros assume that the name never changes. This is a helper function | |
| 121 // where this assumption doesn't hold. | |
| 122 void LogDynamicUMAStat(const std::string& name, | |
| 123 int sample, | |
| 124 int min, | |
| 125 int max, | |
| 126 int bucket_size) { | |
| 127 base::HistogramBase* counter = base::Histogram::FactoryGet( | |
| 128 name, | |
| 129 min, | |
| 130 max, | |
| 131 bucket_size, | |
| 132 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 133 counter->Add(sample); | |
| 134 } | |
| 135 | |
| 118 } // namespace | 136 } // namespace |
| 119 | 137 |
| 120 LoginDatabase::LoginDatabase() { | 138 LoginDatabase::LoginDatabase() { |
| 121 } | 139 } |
| 122 | 140 |
| 123 LoginDatabase::~LoginDatabase() { | 141 LoginDatabase::~LoginDatabase() { |
| 124 } | 142 } |
| 125 | 143 |
| 126 bool LoginDatabase::Init(const base::FilePath& db_path) { | 144 bool LoginDatabase::Init(const base::FilePath& db_path) { |
| 127 // Set pragmas for a small, private database (based on WebDatabase). | 145 // Set pragmas for a small, private database (based on WebDatabase). |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 } | 292 } |
| 275 if (!db_.Execute("CREATE INDEX logins_signon ON " | 293 if (!db_.Execute("CREATE INDEX logins_signon ON " |
| 276 "logins (signon_realm)")) { | 294 "logins (signon_realm)")) { |
| 277 NOTREACHED(); | 295 NOTREACHED(); |
| 278 return false; | 296 return false; |
| 279 } | 297 } |
| 280 } | 298 } |
| 281 return true; | 299 return true; |
| 282 } | 300 } |
| 283 | 301 |
| 284 void LoginDatabase::ReportMetrics(const std::string& sync_username) { | 302 void LoginDatabase::ReportMetrics(PasswordManagerClient* client) { |
| 285 sql::Statement s(db_.GetCachedStatement( | 303 sql::Statement s(db_.GetCachedStatement( |
| 286 SQL_FROM_HERE, | 304 SQL_FROM_HERE, |
| 287 "SELECT signon_realm, blacklisted_by_user, COUNT(username_value) " | 305 "SELECT signon_realm, blacklisted_by_user, COUNT(username_value) " |
| 288 "FROM logins GROUP BY signon_realm, blacklisted_by_user")); | 306 "FROM logins GROUP BY signon_realm, blacklisted_by_user")); |
| 289 | 307 |
| 290 if (!s.is_valid()) | 308 if (!s.is_valid()) |
| 291 return; | 309 return; |
| 292 | 310 |
| 311 std::string custom_passphrase = "WithoutCustomPassphrase"; | |
| 312 if (client->IsPasswordSyncEnabled(ONLY_CUSTOM_PASSPHRASE)) { | |
| 313 custom_passphrase = "WithCustomPassphrase"; | |
| 314 } | |
| 315 | |
| 293 int total_accounts = 0; | 316 int total_accounts = 0; |
| 294 int blacklisted_sites = 0; | 317 int blacklisted_sites = 0; |
| 295 while (s.Step()) { | 318 while (s.Step()) { |
| 296 int blacklisted = s.ColumnInt(1); | 319 int blacklisted = s.ColumnInt(1); |
| 297 int accounts_per_site = s.ColumnInt(2); | 320 int accounts_per_site = s.ColumnInt(2); |
| 298 if (blacklisted) { | 321 if (blacklisted) { |
| 299 ++blacklisted_sites; | 322 ++blacklisted_sites; |
| 300 } else { | 323 } else { |
| 301 total_accounts += accounts_per_site; | 324 total_accounts += accounts_per_site; |
| 302 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.AccountsPerSite", | 325 LogDynamicUMAStat(base::StringPrintf("PasswordManager.AccountsPerSite%s", |
| 303 accounts_per_site, 0, 32, 6); | 326 custom_passphrase.c_str()), |
| 327 accounts_per_site, | |
| 328 0, | |
| 329 32, | |
| 330 6); | |
| 304 } | 331 } |
| 305 } | 332 } |
| 306 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.TotalAccounts", | 333 LogDynamicUMAStat(base::StringPrintf("PasswordManager.TotalAccounts%s", |
| 307 total_accounts, 0, 32, 6); | 334 custom_passphrase.c_str()), |
| 308 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.BlacklistedSites", | 335 total_accounts, |
| 309 blacklisted_sites, 0, 32, 6); | 336 0, |
| 337 32, | |
| 338 6); | |
| 339 LogDynamicUMAStat(base::StringPrintf("PasswordManager.BlacklistedSites%s", | |
| 340 custom_passphrase.c_str()), | |
| 341 blacklisted_sites, | |
| 342 0, | |
| 343 32, | |
| 344 6); | |
| 310 | 345 |
| 311 sql::Statement usage_statement(db_.GetCachedStatement( | 346 sql::Statement usage_statement(db_.GetCachedStatement( |
| 312 SQL_FROM_HERE, | 347 SQL_FROM_HERE, |
| 313 "SELECT password_type, times_used FROM logins")); | 348 "SELECT password_type, times_used FROM logins")); |
| 314 | 349 |
| 315 if (!usage_statement.is_valid()) | 350 if (!usage_statement.is_valid()) |
| 316 return; | 351 return; |
| 317 | 352 |
| 318 while (usage_statement.Step()) { | 353 while (usage_statement.Step()) { |
| 319 PasswordForm::Type type = static_cast<PasswordForm::Type>( | 354 PasswordForm::Type type = static_cast<PasswordForm::Type>( |
| 320 usage_statement.ColumnInt(0)); | 355 usage_statement.ColumnInt(0)); |
| 321 | 356 |
| 322 if (type == PasswordForm::TYPE_GENERATED) { | 357 if (type == PasswordForm::TYPE_GENERATED) { |
| 323 UMA_HISTOGRAM_CUSTOM_COUNTS( | 358 LogDynamicUMAStat( |
| 324 "PasswordManager.TimesGeneratedPasswordUsed", | 359 base::StringPrintf("PasswordManager.TimesGeneratedPasswordUsed%s", |
| 325 usage_statement.ColumnInt(1), 0, 100, 10); | 360 custom_passphrase.c_str()), |
| 361 usage_statement.ColumnInt(1), | |
| 362 0, | |
| 363 100, | |
| 364 10); | |
| 326 } else { | 365 } else { |
| 327 UMA_HISTOGRAM_CUSTOM_COUNTS( | 366 LogDynamicUMAStat( |
| 328 "PasswordManager.TimesPasswordUsed", | 367 base::StringPrintf("PasswordManager.TimesPasswordUsed%s", |
| 329 usage_statement.ColumnInt(1), 0, 100, 10); | 368 custom_passphrase.c_str()), |
| 369 usage_statement.ColumnInt(1), | |
| 370 0, | |
| 371 100, | |
| 372 10); | |
|
Alexei Svitkine (slow)
2014/10/15 15:15:31
Instead of repeating these params, how about makin
Garrett Casto
2014/10/16 22:52:10
Done.
| |
| 330 } | 373 } |
| 331 } | 374 } |
| 332 | 375 |
| 333 bool syncing_account_saved = false; | 376 bool syncing_account_saved = false; |
| 377 std::string sync_username = client->GetSyncUsername(); | |
| 334 if (!sync_username.empty()) { | 378 if (!sync_username.empty()) { |
| 335 sql::Statement sync_statement(db_.GetCachedStatement( | 379 sql::Statement sync_statement(db_.GetCachedStatement( |
| 336 SQL_FROM_HERE, | 380 SQL_FROM_HERE, |
| 337 "SELECT username_value FROM logins " | 381 "SELECT username_value FROM logins " |
| 338 "WHERE signon_realm == ?")); | 382 "WHERE signon_realm == ?")); |
| 339 sync_statement.BindString( | 383 sync_statement.BindString( |
| 340 0, GaiaUrls::GetInstance()->gaia_url().GetOrigin().spec()); | 384 0, GaiaUrls::GetInstance()->gaia_url().GetOrigin().spec()); |
| 341 | 385 |
| 342 if (!sync_statement.is_valid()) | 386 if (!sync_statement.is_valid()) |
| 343 return; | 387 return; |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 | 808 |
| 765 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { | 809 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { |
| 766 DCHECK(db_.is_open()); | 810 DCHECK(db_.is_open()); |
| 767 meta_table_.Reset(); | 811 meta_table_.Reset(); |
| 768 db_.Close(); | 812 db_.Close(); |
| 769 sql::Connection::Delete(db_path_); | 813 sql::Connection::Delete(db_path_); |
| 770 return Init(db_path_); | 814 return Init(db_path_); |
| 771 } | 815 } |
| 772 | 816 |
| 773 } // namespace password_manager | 817 } // namespace password_manager |
| OLD | NEW |