fingerprint_browsertest.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
1// Copyright 2014 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 "components/autofill/content/browser/risk/fingerprint.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/port.h"
10#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
11#include "content/public/browser/geolocation_provider.h"
12#include "content/public/browser/gpu_data_manager.h"
13#include "content/public/common/geoposition.h"
14#include "content/public/test/content_browser_test.h"
15#include "content/public/test/test_utils.h"
16#include "testing/gmock/include/gmock/gmock.h"
17#include "testing/gtest/include/gtest/gtest.h"
18#include "third_party/WebKit/public/platform/WebRect.h"
19#include "third_party/WebKit/public/platform/WebScreenInfo.h"
20#include "ui/gfx/rect.h"
21
22using testing::ElementsAre;
23
24namespace autofill {
25namespace risk {
26
27namespace internal {
28
29// Defined in the implementation file corresponding to this test.
30void GetFingerprintInternal(
31    uint64 obfuscated_gaia_id,
32    const gfx::Rect& window_bounds,
33    const gfx::Rect& content_bounds,
34    const blink::WebScreenInfo& screen_info,
35    const std::string& version,
36    const std::string& charset,
37    const std::string& accept_languages,
38    const base::Time& install_time,
39    const std::string& app_locale,
40    const std::string& user_agent,
41    const base::TimeDelta& timeout,
42    const base::Callback<void(scoped_ptr<Fingerprint>)>& callback);
43
44}  // namespace internal
45
46// Constants that are passed verbatim to the fingerprinter code and should be
47// serialized into the resulting protocol buffer.
48const uint64 kObfuscatedGaiaId = GG_UINT64_C(16571487432910023183);
49const char kCharset[] = "UTF-8";
50const char kAcceptLanguages[] = "en-US,en";
51const int kScreenColorDepth = 53;
52const char kLocale[] = "en-GB";
53const char kUserAgent[] = "TestUserAgent";
54
55// Geolocation constants that are passed verbatim to the fingerprinter code and
56// should be serialized into the resulting protocol buffer.
57const double kLatitude = -42.0;
58const double kLongitude = 17.3;
59const double kAltitude = 123.4;
60const double kAccuracy = 73.7;
61const int kGeolocationTime = 87;
62
63class AutofillRiskFingerprintTest : public content::ContentBrowserTest {
64 public:
65  AutofillRiskFingerprintTest()
66      : window_bounds_(2, 3, 5, 7),
67        content_bounds_(11, 13, 17, 37),
68        screen_bounds_(0, 0, 101, 71),
69        available_screen_bounds_(0, 11, 101, 60),
70        unavailable_screen_bounds_(0, 0, 101, 11) {}
71
72  void GetFingerprintTestCallback(scoped_ptr<Fingerprint> fingerprint) {
73    // Verify that all fields Chrome can fill have been filled.
74    ASSERT_TRUE(fingerprint->has_machine_characteristics());
75    const Fingerprint::MachineCharacteristics& machine =
76        fingerprint->machine_characteristics();
77    EXPECT_TRUE(machine.has_operating_system_build());
78    EXPECT_TRUE(machine.has_browser_install_time_hours());
79    EXPECT_GT(machine.font_size(), 0);
80    EXPECT_EQ(machine.plugin_size(), 0);  // TODO(isherman): crbug.com/358548.
81    EXPECT_TRUE(machine.has_utc_offset_ms());
82    EXPECT_TRUE(machine.has_browser_language());
83    EXPECT_GT(machine.requested_language_size(), 0);
84    EXPECT_TRUE(machine.has_charset());
85    EXPECT_TRUE(machine.has_screen_count());
86    ASSERT_TRUE(machine.has_screen_size());
87    EXPECT_TRUE(machine.screen_size().has_width());
88    EXPECT_TRUE(machine.screen_size().has_height());
89    EXPECT_TRUE(machine.has_screen_color_depth());
90    ASSERT_TRUE(machine.has_unavailable_screen_size());
91    EXPECT_TRUE(machine.unavailable_screen_size().has_width());
92    EXPECT_TRUE(machine.unavailable_screen_size().has_height());
93    EXPECT_TRUE(machine.has_user_agent());
94    ASSERT_TRUE(machine.has_cpu());
95    EXPECT_TRUE(machine.cpu().has_vendor_name());
96    EXPECT_TRUE(machine.cpu().has_brand());
97    EXPECT_TRUE(machine.has_ram());
98    EXPECT_TRUE(machine.has_browser_build());
99    EXPECT_TRUE(machine.has_browser_feature());
100    if (content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) {
101      ASSERT_TRUE(machine.has_graphics_card());
102      EXPECT_TRUE(machine.graphics_card().has_vendor_id());
103      EXPECT_TRUE(machine.graphics_card().has_device_id());
104    } else {
105      EXPECT_FALSE(machine.has_graphics_card());
106    }
107
108    ASSERT_TRUE(fingerprint->has_transient_state());
109    const Fingerprint::TransientState& transient_state =
110        fingerprint->transient_state();
111    ASSERT_TRUE(transient_state.has_inner_window_size());
112    ASSERT_TRUE(transient_state.has_outer_window_size());
113    EXPECT_TRUE(transient_state.inner_window_size().has_width());
114    EXPECT_TRUE(transient_state.inner_window_size().has_height());
115    EXPECT_TRUE(transient_state.outer_window_size().has_width());
116    EXPECT_TRUE(transient_state.outer_window_size().has_height());
117
118    ASSERT_TRUE(fingerprint->has_user_characteristics());
119    const Fingerprint::UserCharacteristics& user_characteristics =
120        fingerprint->user_characteristics();
121    ASSERT_TRUE(user_characteristics.has_location());
122    const Fingerprint::UserCharacteristics::Location& location =
123        user_characteristics.location();
124    EXPECT_TRUE(location.has_altitude());
125    EXPECT_TRUE(location.has_latitude());
126    EXPECT_TRUE(location.has_longitude());
127    EXPECT_TRUE(location.has_accuracy());
128    EXPECT_TRUE(location.has_time_in_ms());
129
130    ASSERT_TRUE(fingerprint->has_metadata());
131    EXPECT_TRUE(fingerprint->metadata().has_timestamp_ms());
132    EXPECT_TRUE(fingerprint->metadata().has_obfuscated_gaia_id());
133    EXPECT_TRUE(fingerprint->metadata().has_fingerprinter_version());
134
135    // Some values have exact known (mocked out) values:
136    EXPECT_THAT(machine.requested_language(), ElementsAre("en-US", "en"));
137    EXPECT_EQ(kLocale, machine.browser_language());
138    EXPECT_EQ(kUserAgent, machine.user_agent());
139    EXPECT_EQ(kCharset, machine.charset());
140    EXPECT_EQ(kScreenColorDepth, machine.screen_color_depth());
141    EXPECT_EQ(unavailable_screen_bounds_.width(),
142              machine.unavailable_screen_size().width());
143    EXPECT_EQ(unavailable_screen_bounds_.height(),
144              machine.unavailable_screen_size().height());
145    EXPECT_EQ(Fingerprint::MachineCharacteristics::FEATURE_REQUEST_AUTOCOMPLETE,
146              machine.browser_feature());
147    EXPECT_EQ(content_bounds_.width(),
148              transient_state.inner_window_size().width());
149    EXPECT_EQ(content_bounds_.height(),
150              transient_state.inner_window_size().height());
151    EXPECT_EQ(window_bounds_.width(),
152              transient_state.outer_window_size().width());
153    EXPECT_EQ(window_bounds_.height(),
154              transient_state.outer_window_size().height());
155    EXPECT_EQ(kObfuscatedGaiaId, fingerprint->metadata().obfuscated_gaia_id());
156    EXPECT_EQ(kAltitude, location.altitude());
157    EXPECT_EQ(kLatitude, location.latitude());
158    EXPECT_EQ(kLongitude, location.longitude());
159    EXPECT_EQ(kAccuracy, location.accuracy());
160    EXPECT_EQ(kGeolocationTime, location.time_in_ms());
161
162    message_loop_.Quit();
163  }
164
165 protected:
166  // Constants defining bounds in the screen coordinate system that are passed
167  // verbatim to the fingerprinter code and should be serialized into the
168  // resulting protocol buffer.  Declared as class members because gfx::Rect is
169  // not a POD type, so it cannot be statically initialized.
170  const gfx::Rect window_bounds_;
171  const gfx::Rect content_bounds_;
172  const gfx::Rect screen_bounds_;
173  const gfx::Rect available_screen_bounds_;
174  const gfx::Rect unavailable_screen_bounds_;
175
176  // A message loop to block on the asynchronous loading of the fingerprint.
177  base::MessageLoopForUI message_loop_;
178};
179
180// Test that getting a fingerprint works on some basic level.
181IN_PROC_BROWSER_TEST_F(AutofillRiskFingerprintTest, GetFingerprint) {
182  content::Geoposition position;
183  position.latitude = kLatitude;
184  position.longitude = kLongitude;
185  position.altitude = kAltitude;
186  position.accuracy = kAccuracy;
187  position.timestamp =
188      base::Time::UnixEpoch() +
189      base::TimeDelta::FromMilliseconds(kGeolocationTime);
190  scoped_refptr<content::MessageLoopRunner> runner =
191      new content::MessageLoopRunner;
192  content::GeolocationProvider::OverrideLocationForTesting(
193      position, runner->QuitClosure());
194  runner->Run();
195
196  blink::WebScreenInfo screen_info;
197  screen_info.depth = kScreenColorDepth;
198  screen_info.rect = blink::WebRect(screen_bounds_);
199  screen_info.availableRect = blink::WebRect(available_screen_bounds_);
200
201  internal::GetFingerprintInternal(
202      kObfuscatedGaiaId, window_bounds_, content_bounds_, screen_info,
203      "25.0.0.123", kCharset, kAcceptLanguages, base::Time::Now(), kLocale,
204      kUserAgent,
205      base::TimeDelta::FromDays(1),  // Ought to be longer than any test run.
206      base::Bind(&AutofillRiskFingerprintTest::GetFingerprintTestCallback,
207                 base::Unretained(this)));
208
209  // Wait for the callback to be called.
210  message_loop_.Run();
211}
212
213}  // namespace risk
214}  // namespace autofill
215