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 |