Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(858)

Side by Side Diff: components/password_manager/core/browser/login_database.cc

Issue 644053003: [Password Manager] Add UMA stats for custom passphrase users. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); 112 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec());
111 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); 113 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec());
112 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); 114 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click);
113 } 115 }
114 116
115 void AddCallback(int err, sql::Statement* /*stmt*/) { 117 void AddCallback(int err, sql::Statement* /*stmt*/) {
116 if (err == 19 /*SQLITE_CONSTRAINT*/) 118 if (err == 19 /*SQLITE_CONSTRAINT*/)
117 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; 119 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form";
118 } 120 }
119 121
122 // UMA_* macros assume that the name never changes. This is a helper function
123 // where this assumption doesn't hold.
124 void LogDynamicUMAStat(const std::string& name,
125 int sample,
126 int min,
127 int max,
128 int bucket_size) {
129 base::HistogramBase* counter = base::Histogram::FactoryGet(
130 name,
131 min,
132 max,
133 bucket_size,
134 base::HistogramBase::kUmaTargetedHistogramFlag);
135 counter->Add(sample);
136 }
137
120 } // namespace 138 } // namespace
121 139
122 LoginDatabase::LoginDatabase() { 140 LoginDatabase::LoginDatabase() {
123 } 141 }
124 142
125 LoginDatabase::~LoginDatabase() { 143 LoginDatabase::~LoginDatabase() {
126 } 144 }
127 145
128 bool LoginDatabase::Init(const base::FilePath& db_path) { 146 bool LoginDatabase::Init(const base::FilePath& db_path) {
129 // Set pragmas for a small, private database (based on WebDatabase). 147 // Set pragmas for a small, private database (based on WebDatabase).
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 } 288 }
271 if (!db_.Execute("CREATE INDEX logins_signon ON " 289 if (!db_.Execute("CREATE INDEX logins_signon ON "
272 "logins (signon_realm)")) { 290 "logins (signon_realm)")) {
273 NOTREACHED(); 291 NOTREACHED();
274 return false; 292 return false;
275 } 293 }
276 } 294 }
277 return true; 295 return true;
278 } 296 }
279 297
280 void LoginDatabase::ReportMetrics(const std::string& sync_username) { 298 void LoginDatabase::ReportMetrics(PasswordManagerClient* client) {
281 sql::Statement s(db_.GetCachedStatement( 299 sql::Statement s(db_.GetCachedStatement(
282 SQL_FROM_HERE, 300 SQL_FROM_HERE,
283 "SELECT signon_realm, blacklisted_by_user, COUNT(username_value) " 301 "SELECT signon_realm, blacklisted_by_user, COUNT(username_value) "
284 "FROM logins GROUP BY signon_realm, blacklisted_by_user")); 302 "FROM logins GROUP BY signon_realm, blacklisted_by_user"));
285 303
286 if (!s.is_valid()) 304 if (!s.is_valid())
287 return; 305 return;
288 306
307 std::string custom_passphrase;
vabr (Chromium) 2014/10/13 09:24:18 Should we have a non-empty value describing the si
Garrett Casto 2014/10/13 20:57:56 Yeah, seems reasonable. I was assuming that there
308 if (client->IsPasswordSyncEnabled(ONLY_CUSTOM_PASSPHRASE_USERS)) {
309 custom_passphrase = "WithCustomPassphrase";
310 }
311
289 int total_accounts = 0; 312 int total_accounts = 0;
290 int blacklisted_sites = 0; 313 int blacklisted_sites = 0;
291 while (s.Step()) { 314 while (s.Step()) {
292 int blacklisted = s.ColumnInt(1); 315 int blacklisted = s.ColumnInt(1);
293 int accounts_per_site = s.ColumnInt(2); 316 int accounts_per_site = s.ColumnInt(2);
294 if (blacklisted) { 317 if (blacklisted) {
295 ++blacklisted_sites; 318 ++blacklisted_sites;
296 } else { 319 } else {
297 total_accounts += accounts_per_site; 320 total_accounts += accounts_per_site;
298 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.AccountsPerSite", 321 LogDynamicUMAStat(base::StringPrintf("PasswordManager.AccountsPerSite%s",
299 accounts_per_site, 0, 32, 6); 322 custom_passphrase.c_str()),
323 accounts_per_site,
324 0,
325 32,
326 6);
300 } 327 }
301 } 328 }
302 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.TotalAccounts", 329 LogDynamicUMAStat(base::StringPrintf("PasswordManager.TotalAccounts%s",
303 total_accounts, 0, 32, 6); 330 custom_passphrase.c_str()),
304 UMA_HISTOGRAM_CUSTOM_COUNTS("PasswordManager.BlacklistedSites", 331 total_accounts,
305 blacklisted_sites, 0, 32, 6); 332 0,
333 32,
334 6);
335 LogDynamicUMAStat(base::StringPrintf("PasswordManager.BlacklistedSites%s",
336 custom_passphrase.c_str()),
337 blacklisted_sites,
338 0,
339 32,
340 6);
306 341
307 sql::Statement usage_statement(db_.GetCachedStatement( 342 sql::Statement usage_statement(db_.GetCachedStatement(
308 SQL_FROM_HERE, 343 SQL_FROM_HERE,
309 "SELECT password_type, times_used FROM logins")); 344 "SELECT password_type, times_used FROM logins"));
310 345
311 if (!usage_statement.is_valid()) 346 if (!usage_statement.is_valid())
312 return; 347 return;
313 348
314 while (usage_statement.Step()) { 349 while (usage_statement.Step()) {
315 PasswordForm::Type type = static_cast<PasswordForm::Type>( 350 PasswordForm::Type type = static_cast<PasswordForm::Type>(
316 usage_statement.ColumnInt(0)); 351 usage_statement.ColumnInt(0));
317 352
318 if (type == PasswordForm::TYPE_GENERATED) { 353 if (type == PasswordForm::TYPE_GENERATED) {
319 UMA_HISTOGRAM_CUSTOM_COUNTS( 354 LogDynamicUMAStat(
320 "PasswordManager.TimesGeneratedPasswordUsed", 355 base::StringPrintf("PasswordManager.TimesGeneratedPasswordUsed%s",
321 usage_statement.ColumnInt(1), 0, 100, 10); 356 custom_passphrase.c_str()),
357 usage_statement.ColumnInt(1),
358 0,
359 100,
360 10);
322 } else { 361 } else {
323 UMA_HISTOGRAM_CUSTOM_COUNTS( 362 LogDynamicUMAStat(
324 "PasswordManager.TimesPasswordUsed", 363 base::StringPrintf("PasswordManager.TimesPasswordUsed%s",
325 usage_statement.ColumnInt(1), 0, 100, 10); 364 custom_passphrase.c_str()),
365 usage_statement.ColumnInt(1),
366 0,
367 100,
368 10);
326 } 369 }
327 } 370 }
328 371
329 bool syncing_account_saved = false; 372 bool syncing_account_saved = false;
373 std::string sync_username = client->GetSyncUsername();
330 if (!sync_username.empty()) { 374 if (!sync_username.empty()) {
331 sql::Statement sync_statement(db_.GetCachedStatement( 375 sql::Statement sync_statement(db_.GetCachedStatement(
332 SQL_FROM_HERE, 376 SQL_FROM_HERE,
333 "SELECT username_value FROM logins " 377 "SELECT username_value FROM logins "
334 "WHERE signon_realm == ?")); 378 "WHERE signon_realm == ?"));
335 sync_statement.BindString( 379 sync_statement.BindString(
336 0, GaiaUrls::GetInstance()->gaia_url().GetOrigin().spec()); 380 0, GaiaUrls::GetInstance()->gaia_url().GetOrigin().spec());
337 381
338 if (!sync_statement.is_valid()) 382 if (!sync_statement.is_valid())
339 return; 383 return;
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 806
763 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { 807 bool LoginDatabase::DeleteAndRecreateDatabaseFile() {
764 DCHECK(db_.is_open()); 808 DCHECK(db_.is_open());
765 meta_table_.Reset(); 809 meta_table_.Reset();
766 db_.Close(); 810 db_.Close();
767 sql::Connection::Delete(db_path_); 811 sql::Connection::Delete(db_path_);
768 return Init(db_path_); 812 return Init(db_path_);
769 } 813 }
770 814
771 } // namespace password_manager 815 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698