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

Side by Side Diff: chrome/browser/autofill/risk/fingerprint.cc

Issue 11612017: [Autofill] Add protobuf for Google Wallet risk parameters and a utility function for filling it out. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clean up! Created 8 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/autofill/risk/fingerprint.h"
6
7 #include "base/bind.h"
8 #include "base/cpu.h"
9 #include "base/logging.h"
10 #include "base/string_split.h"
11 #include "base/sys_info.h"
12 #include "base/time.h"
13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/autofill/risk/proto/fingerprint.pb.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/common/chrome_version_info.h"
18 #include "chrome/common/pref_names.h"
19 #include "content/public/browser/content_browser_client.h"
20 #include "content/public/browser/font_list_async.h"
21 #include "content/public/browser/gpu_data_manager.h"
22 #include "content/public/browser/gpu_data_manager_observer.h"
23 #include "content/public/browser/plugin_service.h"
24 #include "content/public/common/content_client.h"
25 #include "content/public/common/gpu_info.h"
26 #include "ui/gfx/rect.h"
27 #include "ui/gfx/screen.h"
28 #include "webkit/plugins/webplugininfo.h"
29
30 namespace autofill {
31 namespace risk {
32
33 namespace {
34
35 const int32 kFingerprinterVersion = 1;
36
37 // Returns the delta between |timestamp| and the Unix epoch, in milliseconds.
38 int64 GetMillisecondsSinceEpoch(const base::Time& timestamp) {
39 return (timestamp - base::Time::UnixEpoch()).InMilliseconds();
40 }
41
42 // Returns the time at which Chrome was installed, in milliseconds since the
43 // epoch.
44 int64 GetInstallTimeMs() {
45 // TODO(isherman): If we keep this implementation, the metric should probably
46 // be renamed; or at least the comments for it should be updated.
47 PrefService* prefs = g_browser_process->local_state();
48 base::Time install_time = base::Time::FromTimeT(
49 prefs->GetInt64(prefs::kUninstallMetricsInstallDate));
50 // The install date should always be available and initialized.
51 DCHECK(!install_time.is_null());
52 return GetMillisecondsSinceEpoch(install_time);
53 }
54
55 // Returns the delta between the local timezone and UTC, in milliseconds.
56 int64 GetTimezoneOffsetMs() {
57 base::Time now = base::Time::Now();
58
59 base::Time::Exploded utc;
60 now.UTCExplode(&utc);
61
62 base::Time::Exploded local;
63 now.LocalExplode(&local);
64
65 base::TimeDelta delta =
66 base::Time::FromUTCExploded(local) - base::Time::FromUTCExploded(utc);
67 return delta.InMilliseconds();
68 }
69
70 // Returns the concatenation of the operating system name and version, e.g.
71 // "Mac OS X 10.6.8".
72 std::string GetOperatingSystemVersion() {
73 return
74 base::SysInfo::OperatingSystemName() + " " +
75 base::SysInfo::OperatingSystemVersion();
76 }
77
78 // Adds the list of |fonts| to the |fingerprint|.
79 void AddFontsToFingerprint(const base::ListValue& fonts,
80 Fingerprint_MachineCharacteristics* fingerprint) {
81 for (base::ListValue::const_iterator it = fonts.begin();
82 it != fonts.end(); ++it) {
83 // Each item in the list is a two-element list such that the first element
84 // is the font family and the second is the font name.
85 const base::ListValue* font_description;
86 bool success = (*it)->GetAsList(&font_description);
87 DCHECK(success);
88
89 std::string font_name;
90 success = font_description->GetString(1, &font_name);
91 DCHECK(success);
92
93 fingerprint->add_font(font_name);
94 }
95 }
96
97 // Adds the list of |plugins| to the |fingerprint|.
98 void AddPluginsToFingerprint(const std::vector<webkit::WebPluginInfo>& plugins,
99 Fingerprint_MachineCharacteristics* fingerprint) {
100 for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
101 it != plugins.end(); ++it) {
102 Fingerprint_MachineCharacteristics_Plugin* plugin =
103 fingerprint->add_plugin();
104 plugin->set_name(UTF16ToUTF8(it->name));
105 plugin->set_description(UTF16ToUTF8(it->desc));
106 for (std::vector<webkit::WebPluginMimeType>::const_iterator mime_type =
107 it->mime_types.begin();
108 mime_type != it->mime_types.end(); ++mime_type) {
109 plugin->add_mime_type(mime_type->mime_type);
110 }
111 plugin->set_version(UTF16ToUTF8(it->version));
112 }
113 }
114
115 // Adds the list of HTTP accept languages in |prefs| to the |fingerprint|.
116 void AddAcceptLanguagesToFingerprint(
117 const std::string& accept_languages_str,
118 Fingerprint_MachineCharacteristics* fingerprint) {
119 std::vector<std::string> accept_languages;
120 base::SplitString(accept_languages_str, ',', &accept_languages);
121 for (std::vector<std::string>::const_iterator it = accept_languages.begin();
122 it != accept_languages.end(); ++it) {
123 fingerprint->add_requested_language(*it);
124 }
125 }
126
127 // Writes the number of screens and the primary display's screen size into the
128 // |fingerprint|.
129 void AddScreenInfoToFingerprint(
130 Fingerprint_MachineCharacteristics* fingerprint) {
131 // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312
132 fingerprint->set_screen_count(
133 gfx::Screen::GetNativeScreen()->GetNumDisplays());
134
135 gfx::Size screen_size =
136 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
137 fingerprint->mutable_screen_size()->set_width(screen_size.width());
138 fingerprint->mutable_screen_size()->set_height(screen_size.height());
139 }
140
141 // Writes info about the machine's CPU into the |fingerprint|.
142 void AddCpuInfoToFingerprint(Fingerprint_MachineCharacteristics* fingerprint) {
143 base::CPU cpu;
144 fingerprint->mutable_cpu()->set_vendor_name(cpu.vendor_name());
145 fingerprint->mutable_cpu()->set_brand(cpu.cpu_brand());
146 }
147
148 // Writes info about the machine's GPU into the |fingerprint|.
149 void AddGpuInfoToFingerprint(Fingerprint_MachineCharacteristics* fingerprint) {
150 const content::GPUInfo& gpu_info =
151 content::GpuDataManager::GetInstance()->GetGPUInfo();
152 DCHECK(gpu_info.finalized);
153
154 Fingerprint_MachineCharacteristics_Graphics* graphics =
155 fingerprint->mutable_graphics_card();
156 graphics->set_vendor_id(gpu_info.gpu.vendor_id);
157 graphics->set_device_id(gpu_info.gpu.device_id);
158 graphics->set_driver_version(gpu_info.driver_version);
159 graphics->set_driver_date(gpu_info.driver_date);
160
161 Fingerprint_MachineCharacteristics_Graphics_PerformanceStatistics*
162 gpu_performance = graphics->mutable_performance_statistics();
163 gpu_performance->set_graphics_score(gpu_info.performance_stats.graphics);
164 gpu_performance->set_gaming_score(gpu_info.performance_stats.gaming);
165 gpu_performance->set_overall_score(gpu_info.performance_stats.overall);
166 }
167
168 // Waits for all asynchronous data required for the fingerprint to be loaded;
169 // then fills out the fingerprint.
170 class FingerprintDataLoader : public content::GpuDataManagerObserver {
171 public:
172 FingerprintDataLoader(int64 gaia_id,
173 const gfx::Rect& window_bounds,
174 const gfx::Rect& content_bounds,
175 const PrefService& prefs,
176 scoped_ptr<Fingerprint> fingerprint);
177
178 private:
179 virtual ~FingerprintDataLoader();
180
181 // content::GpuDataManagerObserver:
182 virtual void OnGpuInfoUpdate() OVERRIDE;
183 virtual void OnVideoMemoryUsageStatsUpdate(
184 const content::GPUVideoMemoryUsageStats& video_memory_usage_stats)
185 OVERRIDE;
186
187 // Callbacks for asynchronously loaded data.
188 void OnGotFonts(scoped_ptr<base::ListValue> fonts);
189 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
190
191 // If all of the asynchronous data has been loaded, fills |fingerprint_| with
192 // the data.
193 void MaybeFillFingerprint();
Evan Stade 2012/12/20 21:33:27 nit: \n
Ilya Sherman 2012/12/21 04:51:23 Done.
194 // Fills |fingerprint_| with the data.
195 void FillFingerprint();
196
197 // The GPU data provider.
198 content::GpuDataManager* const gpu_data_manager_;
199
200 // Data that will be passed on to the next loading phase.
201 const int64 gaia_id_;
202 const gfx::Rect window_bounds_;
203 const gfx::Rect content_bounds_;
204 const std::string charset_;
205 const std::string accept_languages_;
206 scoped_ptr<Fingerprint> fingerprint_;
207
208 // Data that will be loaded asynchronously.
209 scoped_ptr<base::ListValue> fonts_;
210 std::vector<webkit::WebPluginInfo> plugins_;
211 bool has_loaded_plugins_;
212
213 DISALLOW_COPY_AND_ASSIGN(FingerprintDataLoader);
214 };
215
216 FingerprintDataLoader::FingerprintDataLoader(
217 int64 gaia_id,
218 const gfx::Rect& window_bounds,
219 const gfx::Rect& content_bounds,
220 const PrefService& prefs,
221 scoped_ptr<Fingerprint> fingerprint)
222 : gpu_data_manager_(content::GpuDataManager::GetInstance()),
223 gaia_id_(gaia_id),
224 window_bounds_(window_bounds),
225 content_bounds_(content_bounds),
226 charset_(prefs.GetString(prefs::kDefaultCharset)),
227 accept_languages_(prefs.GetString(prefs::kAcceptLanguages)),
228 fingerprint_(fingerprint.Pass()),
229 has_loaded_plugins_(false) {
230 // Load GPU data if needed.
231 if (!gpu_data_manager_->IsCompleteGpuInfoAvailable()) {
232 gpu_data_manager_->AddObserver(this);
233 gpu_data_manager_->RequestCompleteGpuInfoIfNeeded();
234 }
235
236 // Load plugin data.
237 content::PluginService::GetInstance()->GetPlugins(
238 base::Bind(&FingerprintDataLoader::OnGotPlugins, base::Unretained(this)));
239
240 // Load font data.
241 content::GetFontListAsync(
242 base::Bind(&FingerprintDataLoader::OnGotFonts, base::Unretained(this)));
243
244 }
245
246 FingerprintDataLoader::~FingerprintDataLoader() {
247 }
248
249 void FingerprintDataLoader::OnGpuInfoUpdate() {
250 if (!gpu_data_manager_->IsCompleteGpuInfoAvailable())
251 return;
252
253 gpu_data_manager_->RemoveObserver(this);
254 MaybeFillFingerprint();
255 }
256
257 void FingerprintDataLoader::OnVideoMemoryUsageStatsUpdate(
258 const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) {
259 }
260
261 void FingerprintDataLoader::OnGotFonts(scoped_ptr<base::ListValue> fonts) {
262 DCHECK(!fonts_);
263 fonts_.reset(fonts.release());
264 MaybeFillFingerprint();
265 }
266
267 void FingerprintDataLoader::OnGotPlugins(
268 const std::vector<webkit::WebPluginInfo>& plugins) {
269 DCHECK(!has_loaded_plugins_);
270 has_loaded_plugins_ = true;
271 plugins_ = plugins;
272 MaybeFillFingerprint();
273 }
274
275 void FingerprintDataLoader::MaybeFillFingerprint() {
276 // If all of the data has been loaded, fill the fingerprint and clean up.
277 if (gpu_data_manager_->IsCompleteGpuInfoAvailable() &&
278 fonts_ &&
279 has_loaded_plugins_) {
280 FillFingerprint();
281 delete this;
282 }
283 }
284
285 void FingerprintDataLoader::FillFingerprint() {
286 Fingerprint_MachineCharacteristics* machine =
287 fingerprint_->mutable_machine_characteristics();
288
289 machine->set_operating_system_build(GetOperatingSystemVersion());
290 machine->set_browser_install_time_ms(GetInstallTimeMs());
291 machine->set_utc_offset_ms(GetTimezoneOffsetMs());
292 machine->set_browser_language(
293 content::GetContentClient()->browser()->GetApplicationLocale());
294 machine->set_charset(charset_);
295 machine->set_user_agent(content::GetContentClient()->GetUserAgent());
296 machine->set_ram(base::SysInfo::AmountOfPhysicalMemory());
297 machine->set_browser_build(chrome::VersionInfo().Version());
298 AddFontsToFingerprint(*fonts_.get(), machine);
299 AddPluginsToFingerprint(plugins_, machine);
300 AddAcceptLanguagesToFingerprint(accept_languages_, machine);
301 AddScreenInfoToFingerprint(machine);
302 AddCpuInfoToFingerprint(machine);
303 AddGpuInfoToFingerprint(machine);
304
305 // TODO(isherman): Store the user's screen color depth by refactoring the code
306 // for RenderWidgetHostImpl::GetWebScreenInfo().
307 // TODO(isherman): Store the user's unavailable screen size, likewise by
308 // fetching the WebScreenInfo that RenderWidgetHostImpl::GetWebScreenInfo()
309 // provides.
310 // TODO(isherman): Store the partition size of the hard drives?
311
312 Fingerprint_TransientState* transient_state =
313 fingerprint_->mutable_transient_state();
314 Fingerprint_Dimension* inner_window_size =
315 transient_state->mutable_inner_window_size();
316 inner_window_size->set_width(window_bounds_.width());
317 inner_window_size->set_height(window_bounds_.height());
318 Fingerprint_Dimension* outer_window_size =
319 transient_state->mutable_outer_window_size();
320 outer_window_size->set_width(content_bounds_.width());
321 outer_window_size->set_height(content_bounds_.height());
322
323 // TODO(isherman): Record network performance data, which is theoretically
324 // available to JS.
325
326 // TODO(isherman): Record user behavior data.
327
328 Fingerprint_Metadata* metadata = fingerprint_->mutable_metadata();
329 metadata->set_timestamp_ms(GetMillisecondsSinceEpoch(base::Time::Now()));
330 metadata->set_gaia_id(gaia_id_);
331 metadata->set_fingerprinter_version(kFingerprinterVersion);
332 }
333
Evan Stade 2012/12/20 21:33:27 nit: one less newline
Ilya Sherman 2012/12/21 04:51:23 Done.
334
335 } // namespace
336
337 void GetFingerprint(int64 gaia_id,
338 const gfx::Rect& window_bounds,
339 const gfx::Rect& content_bounds,
340 const PrefService& prefs,
341 scoped_ptr<Fingerprint> fingerprint) {
342 // TODO(isherman): Add a DCHECK that the ToS have been accepted prior to
343 // calling into this method.
344
345 // Begin loading all of the data that we need to load asynchronously.
346 // This class is responsible for freeing its own memory.
347 new FingerprintDataLoader(gaia_id, window_bounds, content_bounds, prefs,
348 fingerprint.Pass());
349 }
350
351 } // namespace risk
352 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698