1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/password_manager/password_manager_metrics_util.h"
7 #include "base/basictypes.h"
8 #include "base/metrics/histogram.h"
9 #include "base/numerics/safe_conversions.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "chrome/common/pref_names.h"
20 using base::ListValue
;
21 using base::FundamentalValue
;
23 namespace password_manager_metrics_util
{
27 // The number of domain groups.
28 const size_t kNumGroups
= 2u * kGroupsPerDomain
;
30 // |kDomainMapping| contains each monitored website together with all ids of
31 // groups which contain the website. Each website appears in
32 // |kGroupsPerDomain| groups, and each group includes an equal number of
33 // websites, so that no two websites have the same set of groups that they
34 // belong to. All ids are in the range [1, |kNumGroups|].
35 // For more information about the algorithm used see http://goo.gl/vUuFd5.
36 struct DomainGroupsPair
{
37 const char* const domain_name
;
38 const size_t group_ids
[kGroupsPerDomain
];
40 const DomainGroupsPair kDomainMapping
[] = {
41 {"google.com", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
42 {"yahoo.com", {1, 2, 3, 4, 5, 11, 12, 13, 14, 15}},
43 {"baidu.com", {1, 2, 3, 4, 6, 7, 11, 12, 16, 17}},
44 {"wikipedia.org", {1, 2, 3, 4, 5, 6, 11, 12, 16, 18}},
45 {"linkedin.com", {1, 6, 8, 11, 13, 14, 15, 16, 17, 19}},
46 {"twitter.com", {5, 6, 7, 8, 9, 11, 13, 17, 19, 20}},
47 {"facebook.com", {7, 8, 9, 10, 13, 14, 16, 17, 18, 20}},
48 {"amazon.com", {2, 5, 9, 10, 12, 14, 15, 18, 19, 20}},
49 {"ebay.com", {3, 7, 9, 10, 14, 15, 17, 18, 19, 20}},
50 {"tumblr.com", {4, 8, 10, 12, 13, 15, 16, 18, 19, 20}},
52 const size_t kNumDomains
= arraysize(kDomainMapping
);
54 // For every monitored domain, this function chooses which of the groups
55 // containing that domain should be used for reporting. That number is chosen
56 // randomly and stored in the user's preferences.
57 size_t GetGroupIndex(size_t domain_index
, PrefService
* pref_service
) {
58 DCHECK_LT(domain_index
, kNumDomains
);
60 const base::ListValue
* group_indices
=
61 pref_service
->GetList(prefs::kPasswordManagerGroupsForDomains
);
63 if (!group_indices
->GetInteger(domain_index
, &result
)) {
64 ListPrefUpdate
group_indices_updater(
65 pref_service
, prefs::kPasswordManagerGroupsForDomains
);
66 // This value has not been generated yet.
68 base::checked_cast
<int>(base::RandGenerator(kGroupsPerDomain
));
69 group_indices_updater
->Set(domain_index
, new FundamentalValue(result
));
71 return base::checked_cast
<size_t>(result
);
76 size_t MonitoredDomainGroupId(const std::string
& url_host
,
77 PrefService
* pref_service
) {
79 for (size_t i
= 0; i
< kNumDomains
; ++i
) {
80 if (url
.DomainIs(kDomainMapping
[i
].domain_name
))
81 return kDomainMapping
[i
].group_ids
[GetGroupIndex(i
, pref_service
)];
86 void LogUMAHistogramEnumeration(const std::string
& name
,
89 DCHECK_LT(sample
, boundary_value
);
91 // Note: This leaks memory, which is expected behavior.
92 base::HistogramBase
* histogram
=
93 base::LinearHistogram::FactoryGet(
98 base::HistogramBase::kUmaTargetedHistogramFlag
);
99 histogram
->Add(sample
);
102 void LogUMAHistogramBoolean(const std::string
& name
, bool sample
) {
103 // Note: This leaks memory, which is expected behavior.
104 base::HistogramBase
* histogram
=
105 base::BooleanHistogram::FactoryGet(
107 base::Histogram::kNoFlags
);
108 histogram
->AddBoolean(sample
);
111 std::string
GroupIdToString(size_t group_id
) {
112 DCHECK_LE(group_id
, kNumGroups
);
114 return "group_" + base::IntToString(group_id
);
115 return std::string();
118 } // namespace password_manager_metrics_util