1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/component_metrics_provider.h"
6
7 #include <string>
8 #include <string_view>
9
10 #include "base/containers/fixed_flat_map.h"
11 #include "base/hash/hash.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "components/component_updater/component_updater_service.h"
14 #include "third_party/metrics_proto/system_profile.pb.h"
15
16 namespace metrics {
17
18 namespace {
19
20 // Extracts the first 32 bits of a fingerprint string, excluding the fingerprint
21 // format specifier - see the fingerprint format specification at
22 // https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md
Trim(const std::string & fp)23 uint32_t Trim(const std::string& fp) {
24 const auto len_prefix = fp.find(".");
25 if (len_prefix == std::string::npos) {
26 return 0;
27 }
28 uint32_t result = 0;
29 if (base::HexStringToUInt(fp.substr(len_prefix + 1, 8), &result)) {
30 return result;
31 }
32 return 0;
33 }
34
35 } // namespace
36
ComponentMetricsProvider(std::unique_ptr<ComponentMetricsProviderDelegate> components_info_delegate)37 ComponentMetricsProvider::ComponentMetricsProvider(
38 std::unique_ptr<ComponentMetricsProviderDelegate> components_info_delegate)
39 : components_info_delegate_(std::move(components_info_delegate)) {}
40
41 ComponentMetricsProvider::~ComponentMetricsProvider() = default;
42
43 // static
CrxIdToComponentId(const std::string & app_id)44 SystemProfileProto_ComponentId ComponentMetricsProvider::CrxIdToComponentId(
45 const std::string& app_id) {
46 static constexpr auto kComponentMap = base::MakeFixedFlatMap<
47 std::string_view, SystemProfileProto_ComponentId>({
48 {"aagaghndoahmfdbmfnajfklaomcanlnh",
49 SystemProfileProto_ComponentId_REAL_TIME_URL_CHECKS_ALLOWLIST},
50 {"bjbdkfoakgmkndalgpadobhgbhhoanho",
51 SystemProfileProto_ComponentId_EPSON_INKJET_PRINTER_ESCPR},
52 {"cdoopinbipdmaefofkedmagbfmdcjnaa",
53 SystemProfileProto_ComponentId_CROW_DOMAIN_LIST},
54 {"cjfkbpdpjpdldhclahpfgnlhpodlpnba",
55 SystemProfileProto_ComponentId_VR_ASSETS},
56 {"ckjlcfmdbdglblbjglepgnoekdnkoklc",
57 SystemProfileProto_ComponentId_PEPPER_FLASH_CHROMEOS},
58 {"cocncanleafgejenidihemfflagifjic",
59 SystemProfileProto_ComponentId_COMMERCE_HEURISTICS},
60 {"copjbmjbojbakpaedmpkhmiplmmehfck",
61 SystemProfileProto_ComponentId_INTERVENTION_POLICY_DATABASE},
62 {"dgeeihjgkpfplghdiaomabiakidhjnnn",
63 SystemProfileProto_ComponentId_GROWTH_CAMPAIGNS},
64 {"dhlpobdgcjafebgbbhjdnapejmpkgiie",
65 SystemProfileProto_ComponentId_DESKTOP_SHARING_HUB},
66 {"eeigpngbgcognadeebkilcpcaedhellh",
67 SystemProfileProto_ComponentId_AUTOFILL_STATES},
68 {"efniojlnjndmcbiieegkicadnoecjjef",
69 SystemProfileProto_ComponentId_PKI_METADATA},
70 {"ehgidpndbllacpjalkiimkbadgjfnnmc",
71 SystemProfileProto_ComponentId_THIRD_PARTY_MODULE_LIST},
72 {"ehpjbaiafkpkmhjocnenjbbhmecnfcjb",
73 SystemProfileProto_ComponentId_LACROS_DOGFOOD_STABLE},
74 {"fellaebeeieagcalnmmpapfioejgihci",
75 SystemProfileProto_ComponentId_APP_PROVISIONING},
76 {"fhbeibbmaepakgdkkmjgldjajgpkkhfj",
77 SystemProfileProto_ComponentId_CELLULAR},
78 {"fookoiellkocclipolgaceabajejjcnp",
79 SystemProfileProto_ComponentId_DOWNLOADABLE_STRINGS},
80 {"gcmjkmgdlgnkkcocmoeiminaijmmjnii",
81 SystemProfileProto_ComponentId_SUBRESOURCE_FILTER},
82 {"gelhpeofhffbaeegmemklllhfdifagmb",
83 SystemProfileProto_ComponentId_SPEECH_SYNTHESIS_SV_SE},
84 {"ggkkehgbnfjpeggfpleeakpidbkibbmn",
85 SystemProfileProto_ComponentId_CROWD_DENY},
86 {"ghiclnejioiofblmbphpgbhaojnkempa",
87 SystemProfileProto_ComponentId_SMART_DIM},
88 {"giekcmmlnklenlaomppkphknjmnnpneh",
89 SystemProfileProto_ComponentId_SSL_ERROR_ASSISTANT},
90 {"gjpajnddmedjmcklfflllocelehklffm",
91 SystemProfileProto_ComponentId_RTANALYTICS_LIGHT},
92 {"gkmgaooipdjhmangpemjhigmamcehddo",
93 SystemProfileProto_ComponentId_SW_REPORTER},
94 {"gncenodapghbnkfkoognegdnjoeegmkp",
95 SystemProfileProto_ComponentId_STAR_CUPS_DRIVER},
96 {"goaoclndmgofblfopkopecdpfhljclbd",
97 SystemProfileProto_ComponentId_SODA_FR_FR},
98 {"gonpemdgkjcecdgbnaabipppbmgfggbe",
99 SystemProfileProto_ComponentId_FIRST_PARTY_SETS},
100 {"hfnkpimlhhgieaddgfemjhofmfblmnib",
101 SystemProfileProto_ComponentId_CRL_SET},
102 {"hkifppleldbgkdlijbdfkdpedggaopda",
103 SystemProfileProto_ComponentId_LACROS_DOGFOOD_CANARY},
104 {"hnfmbeciphpghlfgpjfbcdifbknombnk",
105 SystemProfileProto_ComponentId_LACROS_DOGFOOD_BETA},
106 {"hnimpnehoodheedghdeeijklkeaacbdc",
107 SystemProfileProto_ComponentId_PNACL},
108 {"icnkogojpkfjeajonkmlplionaamopkf", SystemProfileProto_ComponentId_SODA},
109 {"ihnlcenocehgdaegdmhbidjhnhdchfmm",
110 SystemProfileProto_ComponentId_RECOVERY_IMPROVED},
111 {"imefjhfbkmcmebodilednhmaccmincoa",
112 SystemProfileProto_ComponentId_CLIENT_SIDE_PHISHING},
113 {"jamhcnnkihinmdlkakkaopbjbbcngflc",
114 SystemProfileProto_ComponentId_HYPHENATION},
115 {"jclgnikdalajmocbnlgieibfmlejnhmg",
116 SystemProfileProto_ComponentId_SODA_DE_DE},
117 {"jdmajdolkmhiifibdijabfojmfjmfkpb",
118 SystemProfileProto_ComponentId_DEMO_MODE_RESOURCES},
119 {"jflhchccmppkfebkiaminageehmchikm",
120 SystemProfileProto_ComponentId_THIRD_PARTY_COOKIE_DEPRECATION_METADATA},
121 {"jflookgnkcckhobaglndicnbbgbonegd",
122 SystemProfileProto_ComponentId_SAFETY_TIPS},
123 {"jhefnhlmpagbceldaobdpcjhkknfjohi",
124 SystemProfileProto_ComponentId_SODA_IT_IT},
125 {"jkcckmaejhmbhagbcebpejbihcnighdb",
126 SystemProfileProto_ComponentId_SODA_ES_ES},
127 {"kdbdaidmledpgkihpopchgmjikgkjclh",
128 SystemProfileProto_ComponentId_DESKTOP_SCREENSHOT_EDITOR},
129 {"kfoklmclfodeliojeaekpoflbkkhojea",
130 SystemProfileProto_ComponentId_ORIGIN_TRIALS},
131 {"khaoiebndkojlmppeemjhbpbandiljpe",
132 SystemProfileProto_ComponentId_FILE_TYPE_POLICIES},
133 {"kiabhabjdbkjdpjbpigfodbdjmbglcoo",
134 SystemProfileProto_ComponentId_TRUST_TOKEN_KEY_COMMITMENTS},
135 {"laoigpblnllgcgjnjnllmfolckpjlhki",
136 SystemProfileProto_ComponentId_MEI_PRELOAD},
137 {"ldobopbhiamakmncndpkeelenhdmgfhk",
138 SystemProfileProto_ComponentId_LACROS_DOGFOOD_DEV},
139 {"lgmfmojpadlamoidaolfpjpjcondabgm",
140 SystemProfileProto_ComponentId_DEMO_MODE_APP},
141 {"llkgjffcdpffmhiakmfcdcblohccpfmo",
142 SystemProfileProto_ComponentId_ORIGIN_TRIALS}, // Alternate ID
143 {"lmelglejhemejginpboagddgdfbepgmp",
144 SystemProfileProto_ComponentId_OPTIMIZATION_HINTS},
145 {"mfhmdacoffpmifoibamicehhklffanao",
146 SystemProfileProto_ComponentId_SCREEN_AI},
147 {"mimojjlkmoijpicakmndhoigimigcmbb",
148 SystemProfileProto_ComponentId_PEPPER_FLASH},
149 {"mjdmdobabdmfcbaakcaadileafkmifen",
150 SystemProfileProto_ComponentId_RTANALYTICS_FULL},
151 {"neifaoindggfcjicffkgpmnlppeffabd",
152 SystemProfileProto_ComponentId_MEDIA_FOUNDATION_WIDEVINE_CDM},
153 {"npdjjkjlcidkjlamlmmdelcjbcpdjocm",
154 SystemProfileProto_ComponentId_RECOVERY},
155 {"obedbbhbpmojnkanicioggnmelmoomoc",
156 SystemProfileProto_ComponentId_ON_DEVICE_HEAD_SUGGEST},
157 {"oegebmmcimckjhkhbggblnkjloogjdfg",
158 SystemProfileProto_ComponentId_SODA_EN_US},
159 {"oimompecagnajdejgnnjijobebaeigek",
160 SystemProfileProto_ComponentId_WIDEVINE_CDM},
161 {"ojhpjlocmbogdgmfpkhlaaeamibhnphh",
162 SystemProfileProto_ComponentId_ZXCVBN_DATA},
163 {"ojjgnpkioondelmggbekfhllhdaimnho",
164 SystemProfileProto_ComponentId_STH_SET},
165 {"ojnjgapiepgciobpecnafnoeaegllfld",
166 SystemProfileProto_ComponentId_CROS_TERMINA},
167 {"onhpjgkfgajmkkeniaoflicgokpaebfa",
168 SystemProfileProto_ComponentId_SODA_JA_JP},
169 {"cffplpkejcbdpfnfabnjikeicbedmifn",
170 SystemProfileProto_ComponentId_MASKED_DOMAIN_LIST},
171 });
172
173 const auto result = kComponentMap.find(app_id);
174 if (result == kComponentMap.end()) {
175 return SystemProfileProto_ComponentId_UNKNOWN;
176 }
177 return result->second;
178 }
179
180 // static
HashCohortId(const std::string & cohort_id)181 uint32_t ComponentMetricsProvider::HashCohortId(const std::string& cohort_id) {
182 return base::PersistentHash(cohort_id.substr(0, cohort_id.find_last_of(":")));
183 }
184
ProvideSystemProfileMetrics(SystemProfileProto * system_profile)185 void ComponentMetricsProvider::ProvideSystemProfileMetrics(
186 SystemProfileProto* system_profile) {
187 for (const auto& component : components_info_delegate_->GetComponents()) {
188 const auto id = ComponentMetricsProvider::CrxIdToComponentId(component.id);
189 // Ignore any unknown components - in practice these are the
190 // SupervisedUserWhitelists, which we do not want to transmit to UMA or
191 // Crash.
192 if (id == SystemProfileProto_ComponentId_UNKNOWN) {
193 continue;
194 }
195 auto* proto = system_profile->add_chrome_component();
196 proto->set_component_id(id);
197 proto->set_version(component.version.GetString());
198 proto->set_omaha_fingerprint(Trim(component.fingerprint));
199 proto->set_cohort_hash(
200 ComponentMetricsProvider::HashCohortId(component.cohort_id));
201 }
202 }
203
204 } // namespace metrics
205