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