fingerprint.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Generating a fingerprint consists of two major steps:
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//   (1) Gather all the necessary data.
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//   (2) Write it into a protocol buffer.
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Step (2) is as simple as it sounds -- it's really just a matter of copying
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// data.  Step (1) requires waiting on several asynchronous callbacks, which are
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// managed by the FingerprintDataLoader class.
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "components/autofill/content/browser/risk/fingerprint.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/cpu.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_info.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/font_list_async.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/geolocation_provider.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/gpu_data_manager.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/gpu_data_manager_observer.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/plugin_service.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_widget_host.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/geoposition.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_info.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRect.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebScreenInfo.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "webkit/plugins/webplugininfo.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using WebKit::WebScreenInfo;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace autofill {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace risk {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int32 kFingerprinterVersion = 1;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the delta between the local timezone and UTC.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta GetTimezoneOffset() {
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const base::Time utc = base::Time::Now();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time::Exploded local;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  utc.LocalExplode(&local);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::Time::FromUTCExploded(local) - utc;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the concatenation of the operating system name and version, e.g.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// "Mac OS X 10.6.8".
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GetOperatingSystemVersion() {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::SysInfo::OperatingSystemName() + " " +
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::SysInfo::OperatingSystemVersion();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Fingerprint::MachineCharacteristics::BrowserFeature
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DialogTypeToBrowserFeature(DialogType dialog_type) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (dialog_type) {
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DIALOG_TYPE_AUTOCHECKOUT:
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return Fingerprint::MachineCharacteristics::FEATURE_AUTOCHECKOUT;
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DIALOG_TYPE_REQUEST_AUTOCOMPLETE:
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return Fingerprint::MachineCharacteristics::FEATURE_REQUEST_AUTOCOMPLETE;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED();
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Fingerprint::MachineCharacteristics::FEATURE_UNKNOWN;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Adds the list of |fonts| to the |machine|.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddFontsToFingerprint(const base::ListValue& fonts,
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           Fingerprint::MachineCharacteristics* machine) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::ListValue::const_iterator it = fonts.begin();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != fonts.end(); ++it) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Each item in the list is a two-element list such that the first element
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is the font family and the second is the font name.
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::ListValue* font_description = NULL;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success = (*it)->GetAsList(&font_description);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string font_name;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    success = font_description->GetString(1, &font_name);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(success);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    machine->add_font(font_name);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Adds the list of |plugins| to the |machine|.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddPluginsToFingerprint(const std::vector<webkit::WebPluginInfo>& plugins,
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             Fingerprint::MachineCharacteristics* machine) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != plugins.end(); ++it) {
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Fingerprint::MachineCharacteristics::Plugin* plugin =
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        machine->add_plugin();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    plugin->set_name(UTF16ToUTF8(it->name));
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    plugin->set_description(UTF16ToUTF8(it->desc));
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (std::vector<webkit::WebPluginMimeType>::const_iterator mime_type =
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             it->mime_types.begin();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         mime_type != it->mime_types.end(); ++mime_type) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      plugin->add_mime_type(mime_type->mime_type);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    plugin->set_version(UTF16ToUTF8(it->version));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Adds the list of HTTP accept languages to the |machine|.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddAcceptLanguagesToFingerprint(
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& accept_languages_str,
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Fingerprint::MachineCharacteristics* machine) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> accept_languages;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(accept_languages_str, ',', &accept_languages);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it = accept_languages.begin();
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != accept_languages.end(); ++it) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    machine->add_requested_language(*it);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This function writes
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   (a) the number of screens,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   (b) the primary display's screen size,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   (c) the screen's color depth, and
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   (d) the size of the screen unavailable to web page content,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       i.e. the Taskbar size on Windows
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// into the |machine|.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddScreenInfoToFingerprint(const WebScreenInfo& screen_info,
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                Fingerprint::MachineCharacteristics* machine) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_screen_count(
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Screen::GetNativeScreen()->GetNumDisplays());
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Size screen_size =
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_screen_size()->set_width(screen_size.width());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_screen_size()->set_height(screen_size.height());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_screen_color_depth(screen_info.depth);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Rect screen_rect(screen_info.rect);
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Rect available_rect(screen_info.availableRect);
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Rect unavailable_rect =
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      gfx::SubtractRects(screen_rect, available_rect);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_unavailable_screen_size()->set_width(
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unavailable_rect.width());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_unavailable_screen_size()->set_height(
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unavailable_rect.height());
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Writes info about the machine's CPU into the |machine|.
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AddCpuInfoToFingerprint(Fingerprint::MachineCharacteristics* machine) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::CPU cpu;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_cpu()->set_vendor_name(cpu.vendor_name());
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->mutable_cpu()->set_brand(cpu.cpu_brand());
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Writes info about the machine's GPU into the |machine|.
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AddGpuInfoToFingerprint(Fingerprint::MachineCharacteristics* machine) {
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gpu::GPUInfo& gpu_info =
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::GpuDataManager::GetInstance()->GetGPUInfo();
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(gpu_info.finalized);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::MachineCharacteristics::Graphics* graphics =
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      machine->mutable_graphics_card();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  graphics->set_vendor_id(gpu_info.gpu.vendor_id);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  graphics->set_device_id(gpu_info.gpu.device_id);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  graphics->set_driver_version(gpu_info.driver_version);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  graphics->set_driver_date(gpu_info.driver_date);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::MachineCharacteristics::Graphics::PerformanceStatistics*
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gpu_performance = graphics->mutable_performance_statistics();
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_performance->set_graphics_score(gpu_info.performance_stats.graphics);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_performance->set_gaming_score(gpu_info.performance_stats.gaming);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_performance->set_overall_score(gpu_info.performance_stats.overall);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Waits for all asynchronous data required for the fingerprint to be loaded,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// then fills out the fingerprint.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FingerprintDataLoader : public content::GpuDataManagerObserver {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FingerprintDataLoader(
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      uint64 obfuscated_gaia_id,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const gfx::Rect& window_bounds,
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const gfx::Rect& content_bounds,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const WebScreenInfo& screen_info,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& version,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& charset,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& accept_languages,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Time& install_time,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DialogType dialog_type,
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& app_locale,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(scoped_ptr<Fingerprint>)>& callback);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~FingerprintDataLoader() {}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::GpuDataManagerObserver:
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGpuInfoUpdate() OVERRIDE;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callbacks for asynchronously loaded data.
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnGotFonts(scoped_ptr<base::ListValue> fonts);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void OnGotGeoposition(const content::Geoposition& geoposition);
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Methods that run on the IO thread to communicate with the
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // GeolocationProvider.
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void LoadGeoposition();
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void OnGotGeopositionOnIOThread(const content::Geoposition& geoposition);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If all of the asynchronous data has been loaded, calls |callback_| with
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the fingerprint data.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MaybeFillFingerprint();
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Calls |callback_| with the fingerprint data.
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FillFingerprint();
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The GPU data provider.
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Weak reference because the GpuDataManager class is a singleton.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::GpuDataManager* const gpu_data_manager_;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The callback used as an "observer" of the GeolocationProvider.  Accessed
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // only on the IO thread.
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::GeolocationProvider::LocationUpdateCallback geolocation_callback_;
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Data that will be passed on to the next loading phase.  See the comment for
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // GetFingerprint() for a description of these variables.
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const uint64 obfuscated_gaia_id_;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect window_bounds_;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect content_bounds_;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const WebScreenInfo screen_info_;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string version_;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string charset_;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string accept_languages_;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::Time install_time_;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DialogType dialog_type_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Data that will be loaded asynchronously.
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::ListValue> fonts_;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<webkit::WebPluginInfo> plugins_;
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool waiting_on_plugins_;
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::Geoposition geoposition_;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The current application locale.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string app_locale_;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The callback that will be called once all the data is available.
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Callback<void(scoped_ptr<Fingerprint>)> callback_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FingerprintDataLoader);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FingerprintDataLoader::FingerprintDataLoader(
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    uint64 obfuscated_gaia_id,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& window_bounds,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& content_bounds,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const WebScreenInfo& screen_info,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& charset,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& accept_languages,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Time& install_time,
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DialogType dialog_type,
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& app_locale,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Callback<void(scoped_ptr<Fingerprint>)>& callback)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : gpu_data_manager_(content::GpuDataManager::GetInstance()),
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      obfuscated_gaia_id_(obfuscated_gaia_id),
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_bounds_(window_bounds),
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content_bounds_(content_bounds),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      screen_info_(screen_info),
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      version_(version),
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      charset_(charset),
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      accept_languages_(accept_languages),
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      install_time_(install_time),
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dialog_type_(dialog_type),
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      waiting_on_plugins_(true),
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback_(callback) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!install_time_.is_null());
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load GPU data if needed.
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!gpu_data_manager_->IsCompleteGpuInfoAvailable()) {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_data_manager_->AddObserver(this);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_data_manager_->RequestCompleteGpuInfoIfNeeded();
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load plugin data.
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::PluginService::GetInstance()->GetPlugins(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FingerprintDataLoader::OnGotPlugins, base::Unretained(this)));
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  waiting_on_plugins_ = false;
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load font data.
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::GetFontListAsync(
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FingerprintDataLoader::OnGotFonts, base::Unretained(this)));
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Load geolocation data.
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::BrowserThread::PostTask(
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&FingerprintDataLoader::LoadGeoposition,
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this)));
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FingerprintDataLoader::OnGpuInfoUpdate() {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!gpu_data_manager_->IsCompleteGpuInfoAvailable())
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_data_manager_->RemoveObserver(this);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaybeFillFingerprint();
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FingerprintDataLoader::OnGotFonts(scoped_ptr<base::ListValue> fonts) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!fonts_);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fonts_.reset(fonts.release());
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaybeFillFingerprint();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FingerprintDataLoader::OnGotPlugins(
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<webkit::WebPluginInfo>& plugins) {
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(waiting_on_plugins_);
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  waiting_on_plugins_ = false;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  plugins_ = plugins;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaybeFillFingerprint();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FingerprintDataLoader::OnGotGeoposition(
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::Geoposition& geoposition) {
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!geoposition_.Validate());
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  geoposition_ = geoposition;
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(geoposition_.Validate() ||
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         geoposition_.error_code != content::Geoposition::ERROR_CODE_NONE);
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MaybeFillFingerprint();
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FingerprintDataLoader::LoadGeoposition() {
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  geolocation_callback_ =
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&FingerprintDataLoader::OnGotGeopositionOnIOThread,
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this));
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      geolocation_callback_, false);
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FingerprintDataLoader::OnGotGeopositionOnIOThread(
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::Geoposition& geoposition) {
35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content::BrowserThread::PostTask(
36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::BrowserThread::UI, FROM_HERE,
36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&FingerprintDataLoader::OnGotGeoposition,
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this), geoposition));
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Unregister as an observer, since this class instance might be destroyed
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // after this callback.  Note: It's important to unregister *after* posting
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the task above.  Unregistering as an observer can have the side-effect of
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // modifying the value of |geoposition|.
36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool removed =
36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback(
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          geolocation_callback_);
37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(removed);
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FingerprintDataLoader::MaybeFillFingerprint() {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If all of the data has been loaded, fill the fingerprint and clean up.
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gpu_data_manager_->IsCompleteGpuInfoAvailable() &&
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fonts_ &&
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      !waiting_on_plugins_ &&
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (geoposition_.Validate() ||
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       geoposition_.error_code != content::Geoposition::ERROR_CODE_NONE)) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillFingerprint();
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FingerprintDataLoader::FillFingerprint() {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Fingerprint> fingerprint(new Fingerprint);
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::MachineCharacteristics* machine =
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fingerprint->mutable_machine_characteristics();
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_operating_system_build(GetOperatingSystemVersion());
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We use the delta between the install time and the Unix epoch, in hours.
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_browser_install_time_hours(
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (install_time_ - base::Time::UnixEpoch()).InHours());
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_utc_offset_ms(GetTimezoneOffset().InMilliseconds());
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  machine->set_browser_language(app_locale_);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_charset(charset_);
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  machine->set_user_agent(content::GetUserAgent(GURL()));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_ram(base::SysInfo::AmountOfPhysicalMemory());
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  machine->set_browser_build(version_);
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  machine->set_browser_feature(DialogTypeToBrowserFeature(dialog_type_));
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddFontsToFingerprint(*fonts_, machine);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddPluginsToFingerprint(plugins_, machine);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddAcceptLanguagesToFingerprint(accept_languages_, machine);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddScreenInfoToFingerprint(screen_info_, machine);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddCpuInfoToFingerprint(machine);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddGpuInfoToFingerprint(machine);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(isherman): Record the user_and_device_name_hash.
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(isherman): Record the partition size of the hard drives?
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::TransientState* transient_state =
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fingerprint->mutable_transient_state();
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::Dimension* inner_window_size =
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      transient_state->mutable_inner_window_size();
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_window_size->set_width(content_bounds_.width());
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_window_size->set_height(content_bounds_.height());
418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::Dimension* outer_window_size =
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      transient_state->mutable_outer_window_size();
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  outer_window_size->set_width(window_bounds_.width());
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  outer_window_size->set_height(window_bounds_.height());
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(isherman): Record network performance data, which is theoretically
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // available to JS.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(isherman): Record more user behavior data.
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (geoposition_.error_code == content::Geoposition::ERROR_CODE_NONE) {
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Fingerprint::UserCharacteristics::Location* location =
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        fingerprint->mutable_user_characteristics()->mutable_location();
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    location->set_altitude(geoposition_.altitude);
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    location->set_latitude(geoposition_.latitude);
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    location->set_longitude(geoposition_.longitude);
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    location->set_accuracy(geoposition_.accuracy);
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    location->set_time_in_ms(
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        (geoposition_.timestamp - base::Time::UnixEpoch()).InMilliseconds());
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Fingerprint::Metadata* metadata = fingerprint->mutable_metadata();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  metadata->set_timestamp_ms(
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  metadata->set_obfuscated_gaia_id(obfuscated_gaia_id_);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  metadata->set_fingerprinter_version(kFingerprinterVersion);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_.Run(fingerprint.Pass());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace internal {
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GetFingerprintInternal(
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint64 obfuscated_gaia_id,
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const gfx::Rect& window_bounds,
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const gfx::Rect& content_bounds,
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const WebKit::WebScreenInfo& screen_info,
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& version,
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& charset,
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& accept_languages,
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::Time& install_time,
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DialogType dialog_type,
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& app_locale,
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::Callback<void(scoped_ptr<Fingerprint>)>& callback) {
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Begin loading all of the data that we need to load asynchronously.
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // This class is responsible for freeing its own memory.
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  new FingerprintDataLoader(obfuscated_gaia_id, window_bounds, content_bounds,
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            screen_info, version, charset, accept_languages,
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            install_time, dialog_type, app_locale, callback);
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace internal
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetFingerprint(
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    uint64 obfuscated_gaia_id,
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Rect& window_bounds,
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::WebContents& web_contents,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& version,
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& charset,
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& accept_languages,
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Time& install_time,
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DialogType dialog_type,
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& app_locale,
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Callback<void(scoped_ptr<Fingerprint>)>& callback) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_contents.GetView()->GetContainerBounds(&content_bounds);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebKit::WebScreenInfo screen_info;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RenderWidgetHostView* host_view =
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents.GetRenderWidgetHostView();
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (host_view)
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_view->GetRenderWidgetHost()->GetWebScreenInfo(&screen_info);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  internal::GetFingerprintInternal(
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      obfuscated_gaia_id, window_bounds, content_bounds, screen_info, version,
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      charset, accept_languages, install_time, dialog_type, app_locale,
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace risk
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace autofill
500