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

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

Issue 12434004: Move remaining Autofill code to //components/autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix long lines Created 7 years, 9 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 | 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/callback.h"
9 #include "base/cpu.h"
10 #include "base/logging.h"
11 #include "base/strings/string_split.h"
12 #include "base/sys_info.h"
13 #include "base/time.h"
14 #include "base/utf_string_conversions.h"
15 #include "base/values.h"
16 #include "chrome/browser/autofill/risk/proto/fingerprint.pb.h"
17 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/browser/font_list_async.h"
19 #include "content/public/browser/gpu_data_manager.h"
20 #include "content/public/browser/gpu_data_manager_observer.h"
21 #include "content/public/browser/plugin_service.h"
22 #include "content/public/browser/render_widget_host.h"
23 #include "content/public/browser/render_widget_host_view.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_contents_view.h"
26 #include "content/public/common/content_client.h"
27 #include "content/public/common/gpu_info.h"
28 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebScreenInfo.h"
30 #include "ui/gfx/rect.h"
31 #include "ui/gfx/screen.h"
32 #include "webkit/plugins/webplugininfo.h"
33
34 using WebKit::WebScreenInfo;
35
36 namespace autofill {
37 namespace risk {
38
39 namespace {
40
41 const int32 kFingerprinterVersion = 1;
42
43 // Returns the delta between the local timezone and UTC.
44 base::TimeDelta GetTimezoneOffset() {
45 base::Time utc = base::Time::Now();
46
47 base::Time::Exploded local;
48 utc.LocalExplode(&local);
49
50 return base::Time::FromUTCExploded(local) - utc;
51 }
52
53 // Returns the concatenation of the operating system name and version, e.g.
54 // "Mac OS X 10.6.8".
55 std::string GetOperatingSystemVersion() {
56 return base::SysInfo::OperatingSystemName() + " " +
57 base::SysInfo::OperatingSystemVersion();
58 }
59
60 // Adds the list of |fonts| to the |machine|.
61 void AddFontsToFingerprint(const base::ListValue& fonts,
62 Fingerprint_MachineCharacteristics* machine) {
63 for (base::ListValue::const_iterator it = fonts.begin();
64 it != fonts.end(); ++it) {
65 // Each item in the list is a two-element list such that the first element
66 // is the font family and the second is the font name.
67 const base::ListValue* font_description;
68 bool success = (*it)->GetAsList(&font_description);
69 DCHECK(success);
70
71 std::string font_name;
72 success = font_description->GetString(1, &font_name);
73 DCHECK(success);
74
75 machine->add_font(font_name);
76 }
77 }
78
79 // Adds the list of |plugins| to the |machine|.
80 void AddPluginsToFingerprint(const std::vector<webkit::WebPluginInfo>& plugins,
81 Fingerprint_MachineCharacteristics* machine) {
82 for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
83 it != plugins.end(); ++it) {
84 Fingerprint_MachineCharacteristics_Plugin* plugin =
85 machine->add_plugin();
86 plugin->set_name(UTF16ToUTF8(it->name));
87 plugin->set_description(UTF16ToUTF8(it->desc));
88 for (std::vector<webkit::WebPluginMimeType>::const_iterator mime_type =
89 it->mime_types.begin();
90 mime_type != it->mime_types.end(); ++mime_type) {
91 plugin->add_mime_type(mime_type->mime_type);
92 }
93 plugin->set_version(UTF16ToUTF8(it->version));
94 }
95 }
96
97 // Adds the list of HTTP accept languages to the |machine|.
98 void AddAcceptLanguagesToFingerprint(
99 const std::string& accept_languages_str,
100 Fingerprint_MachineCharacteristics* machine) {
101 std::vector<std::string> accept_languages;
102 base::SplitString(accept_languages_str, ',', &accept_languages);
103 for (std::vector<std::string>::const_iterator it = accept_languages.begin();
104 it != accept_languages.end(); ++it) {
105 machine->add_requested_language(*it);
106 }
107 }
108
109 // Writes
110 // (a) the number of screens,
111 // (b) the primary display's screen size,
112 // (c) the screen's color depth, and
113 // (d) the size of the screen unavailable to web page content,
114 // i.e. the Taskbar size on Windows
115 // into the |machine|.
116 void AddScreenInfoToFingerprint(const WebScreenInfo& screen_info,
117 Fingerprint_MachineCharacteristics* machine) {
118 // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312
119 machine->set_screen_count(
120 gfx::Screen::GetNativeScreen()->GetNumDisplays());
121
122 gfx::Size screen_size =
123 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
124 machine->mutable_screen_size()->set_width(screen_size.width());
125 machine->mutable_screen_size()->set_height(screen_size.height());
126
127 machine->set_screen_color_depth(screen_info.depth);
128
129 gfx::Rect screen_rect(screen_info.rect);
130 gfx::Rect available_rect(screen_info.availableRect);
131 gfx::Rect unavailable_rect = gfx::SubtractRects(screen_rect, available_rect);
132 machine->mutable_unavailable_screen_size()->set_width(
133 unavailable_rect.width());
134 machine->mutable_unavailable_screen_size()->set_height(
135 unavailable_rect.height());
136 }
137
138 // Writes info about the machine's CPU into the |machine|.
139 void AddCpuInfoToFingerprint(Fingerprint_MachineCharacteristics* machine) {
140 base::CPU cpu;
141 machine->mutable_cpu()->set_vendor_name(cpu.vendor_name());
142 machine->mutable_cpu()->set_brand(cpu.cpu_brand());
143 }
144
145 // Writes info about the machine's GPU into the |machine|.
146 void AddGpuInfoToFingerprint(Fingerprint_MachineCharacteristics* machine) {
147 const content::GPUInfo& gpu_info =
148 content::GpuDataManager::GetInstance()->GetGPUInfo();
149 DCHECK(gpu_info.finalized);
150
151 Fingerprint_MachineCharacteristics_Graphics* graphics =
152 machine->mutable_graphics_card();
153 graphics->set_vendor_id(gpu_info.gpu.vendor_id);
154 graphics->set_device_id(gpu_info.gpu.device_id);
155 graphics->set_driver_version(gpu_info.driver_version);
156 graphics->set_driver_date(gpu_info.driver_date);
157
158 Fingerprint_MachineCharacteristics_Graphics_PerformanceStatistics*
159 gpu_performance = graphics->mutable_performance_statistics();
160 gpu_performance->set_graphics_score(gpu_info.performance_stats.graphics);
161 gpu_performance->set_gaming_score(gpu_info.performance_stats.gaming);
162 gpu_performance->set_overall_score(gpu_info.performance_stats.overall);
163 }
164
165 // Waits for all asynchronous data required for the fingerprint to be loaded;
166 // then fills out the fingerprint.
167 class FingerprintDataLoader : public content::GpuDataManagerObserver {
168 public:
169 FingerprintDataLoader(
170 int64 gaia_id,
171 const gfx::Rect& window_bounds,
172 const gfx::Rect& content_bounds,
173 const WebScreenInfo& screen_info,
174 const std::string& version,
175 const std::string& charset,
176 const std::string& accept_languages,
177 const base::Time& install_time,
178 const base::Callback<void(scoped_ptr<Fingerprint>)>& callback);
179
180 private:
181 virtual ~FingerprintDataLoader();
182
183 // content::GpuDataManagerObserver:
184 virtual void OnGpuInfoUpdate() OVERRIDE;
185
186 // Callbacks for asynchronously loaded data.
187 void OnGotFonts(scoped_ptr<base::ListValue> fonts);
188 void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
189
190 // If all of the asynchronous data has been loaded, calls |callback_| with
191 // the fingerprint data.
192 void MaybeFillFingerprint();
193
194 // Calls |callback_| with the fingerprint 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 WebScreenInfo screen_info_;
205 const std::string version_;
206 const std::string charset_;
207 const std::string accept_languages_;
208 const base::Time install_time_;
209
210 // Data that will be loaded asynchronously.
211 scoped_ptr<base::ListValue> fonts_;
212 std::vector<webkit::WebPluginInfo> plugins_;
213 bool has_loaded_plugins_;
214
215 // The callback that will be called once all the data is available.
216 base::Callback<void(scoped_ptr<Fingerprint>)> callback_;
217
218 DISALLOW_COPY_AND_ASSIGN(FingerprintDataLoader);
219 };
220
221 FingerprintDataLoader::FingerprintDataLoader(
222 int64 gaia_id,
223 const gfx::Rect& window_bounds,
224 const gfx::Rect& content_bounds,
225 const WebScreenInfo& screen_info,
226 const std::string& version,
227 const std::string& charset,
228 const std::string& accept_languages,
229 const base::Time& install_time,
230 const base::Callback<void(scoped_ptr<Fingerprint>)>& callback)
231 : gpu_data_manager_(content::GpuDataManager::GetInstance()),
232 gaia_id_(gaia_id),
233 window_bounds_(window_bounds),
234 content_bounds_(content_bounds),
235 screen_info_(screen_info),
236 version_(version),
237 charset_(charset),
238 accept_languages_(accept_languages),
239 install_time_(install_time),
240 has_loaded_plugins_(false),
241 callback_(callback) {
242 DCHECK(!install_time_.is_null());
243
244 // TODO(isherman): Investigating http://crbug.com/174296
245 LOG(WARNING) << "Loading fingerprint data.";
246
247 // Load GPU data if needed.
248 if (!gpu_data_manager_->IsCompleteGpuInfoAvailable()) {
249 // TODO(isherman): Investigating http://crbug.com/174296
250 LOG(WARNING) << "Loading GPU data.";
251
252 gpu_data_manager_->AddObserver(this);
253 gpu_data_manager_->RequestCompleteGpuInfoIfNeeded();
254 } else {
255 // TODO(isherman): Investigating http://crbug.com/174296
256 LOG(WARNING) << "GPU data already loaded.";
257 }
258
259 // Load plugin data.
260 content::PluginService::GetInstance()->GetPlugins(
261 base::Bind(&FingerprintDataLoader::OnGotPlugins, base::Unretained(this)));
262
263 // Load font data.
264 content::GetFontListAsync(
265 base::Bind(&FingerprintDataLoader::OnGotFonts, base::Unretained(this)));
266 }
267
268 FingerprintDataLoader::~FingerprintDataLoader() {
269 }
270
271 void FingerprintDataLoader::OnGpuInfoUpdate() {
272 if (!gpu_data_manager_->IsCompleteGpuInfoAvailable()) {
273 // TODO(isherman): Investigating http://crbug.com/174296
274 LOG(WARNING) << "OnGpuInfoUpdate() called without complete GPU info.";
275 return;
276 }
277
278 // TODO(isherman): Investigating http://crbug.com/174296
279 LOG(WARNING) << "Loaded GPU data.";
280
281 gpu_data_manager_->RemoveObserver(this);
282 MaybeFillFingerprint();
283 }
284
285 void FingerprintDataLoader::OnGotFonts(scoped_ptr<base::ListValue> fonts) {
286 // TODO(isherman): Investigating http://crbug.com/174296
287 LOG(WARNING) << "Loaded fonts.";
288
289 DCHECK(!fonts_);
290 fonts_.reset(fonts.release());
291 MaybeFillFingerprint();
292 }
293
294 void FingerprintDataLoader::OnGotPlugins(
295 const std::vector<webkit::WebPluginInfo>& plugins) {
296 // TODO(isherman): Investigating http://crbug.com/174296
297 LOG(WARNING) << "Loaded plugins.";
298
299 DCHECK(!has_loaded_plugins_);
300 has_loaded_plugins_ = true;
301 plugins_ = plugins;
302 MaybeFillFingerprint();
303 }
304
305 void FingerprintDataLoader::MaybeFillFingerprint() {
306 // TODO(isherman): Investigating http://crbug.com/174296
307 LOG(WARNING) << "GPU data: "
308 << (gpu_data_manager_->IsCompleteGpuInfoAvailable() ?
309 "loaded" :
310 "waiting");
311 LOG(WARNING) << "Fonts: "
312 << (fonts_ ? "loaded" : "waiting");
313 LOG(WARNING) << "Plugins: "
314 << (has_loaded_plugins_ ? "loaded" : "waiting");
315
316 // If all of the data has been loaded, fill the fingerprint and clean up.
317 if (gpu_data_manager_->IsCompleteGpuInfoAvailable() &&
318 fonts_ &&
319 has_loaded_plugins_) {
320 FillFingerprint();
321 delete this;
322 }
323 }
324
325 void FingerprintDataLoader::FillFingerprint() {
326 scoped_ptr<Fingerprint> fingerprint(new Fingerprint);
327 Fingerprint_MachineCharacteristics* machine =
328 fingerprint->mutable_machine_characteristics();
329
330 machine->set_operating_system_build(GetOperatingSystemVersion());
331 // We use the delta between the install time and the Unix epoch, in hours.
332 machine->set_browser_install_time_hours(
333 (install_time_ - base::Time::UnixEpoch()).InHours());
334 machine->set_utc_offset_ms(GetTimezoneOffset().InMilliseconds());
335 machine->set_browser_language(
336 content::GetContentClient()->browser()->GetApplicationLocale());
337 machine->set_charset(charset_);
338 machine->set_user_agent(content::GetContentClient()->GetUserAgent());
339 machine->set_ram(base::SysInfo::AmountOfPhysicalMemory());
340 machine->set_browser_build(version_);
341 AddFontsToFingerprint(*fonts_, machine);
342 AddPluginsToFingerprint(plugins_, machine);
343 AddAcceptLanguagesToFingerprint(accept_languages_, machine);
344 AddScreenInfoToFingerprint(screen_info_, machine);
345 AddCpuInfoToFingerprint(machine);
346 AddGpuInfoToFingerprint(machine);
347
348 // TODO(isherman): Store the partition size of the hard drives?
349
350 Fingerprint_TransientState* transient_state =
351 fingerprint->mutable_transient_state();
352 Fingerprint_Dimension* inner_window_size =
353 transient_state->mutable_inner_window_size();
354 inner_window_size->set_width(content_bounds_.width());
355 inner_window_size->set_height(content_bounds_.height());
356 Fingerprint_Dimension* outer_window_size =
357 transient_state->mutable_outer_window_size();
358 outer_window_size->set_width(window_bounds_.width());
359 outer_window_size->set_height(window_bounds_.height());
360
361 // TODO(isherman): Record network performance data, which is theoretically
362 // available to JS.
363
364 // TODO(isherman): Record user behavior data.
365
366 Fingerprint_Metadata* metadata = fingerprint->mutable_metadata();
367 metadata->set_timestamp_ms(
368 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
369 metadata->set_gaia_id(gaia_id_);
370 metadata->set_fingerprinter_version(kFingerprinterVersion);
371
372 callback_.Run(fingerprint.Pass());
373 }
374
375 } // namespace
376
377 void GetFingerprint(
378 int64 gaia_id,
379 const gfx::Rect& window_bounds,
380 const content::WebContents& web_contents,
381 const std::string& version,
382 const std::string& charset,
383 const std::string& accept_languages,
384 const base::Time& install_time,
385 const base::Callback<void(scoped_ptr<Fingerprint>)>& callback) {
386 gfx::Rect content_bounds;
387 web_contents.GetView()->GetContainerBounds(&content_bounds);
388
389 WebKit::WebScreenInfo screen_info;
390 content::RenderWidgetHostView* host_view =
391 web_contents.GetRenderWidgetHostView();
392 if (host_view)
393 host_view->GetRenderWidgetHost()->GetWebScreenInfo(&screen_info);
394
395 internal::GetFingerprintInternal(
396 gaia_id, window_bounds, content_bounds, screen_info, version, charset,
397 accept_languages, install_time, callback);
398 }
399
400 namespace internal {
401
402 void GetFingerprintInternal(
403 int64 gaia_id,
404 const gfx::Rect& window_bounds,
405 const gfx::Rect& content_bounds,
406 const WebKit::WebScreenInfo& screen_info,
407 const std::string& version,
408 const std::string& charset,
409 const std::string& accept_languages,
410 const base::Time& install_time,
411 const base::Callback<void(scoped_ptr<Fingerprint>)>& callback) {
412 // Begin loading all of the data that we need to load asynchronously.
413 // This class is responsible for freeing its own memory.
414 new FingerprintDataLoader(gaia_id, window_bounds, content_bounds, screen_info,
415 version, charset, accept_languages, install_time,
416 callback);
417 }
418
419 } // namespace internal
420
421 } // namespace risk
422 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/autofill/risk/fingerprint.h ('k') | chrome/browser/autofill/risk/fingerprint_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698