1 // Copyright 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.
5 #include "components/autofill/content/browser/risk/fingerprint.h"
8 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/common/chrome_content_client.h"
12 #include "chrome/test/base/in_process_browser_test.h"
13 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
14 #include "content/public/browser/geolocation_provider.h"
15 #include "content/public/browser/gpu_data_manager.h"
16 #include "content/public/common/geoposition.h"
17 #include "content/public/test/test_utils.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/WebKit/public/platform/WebRect.h"
21 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
22 #include "ui/gfx/rect.h"
24 using testing::ElementsAre;
31 // Defined in the implementation file corresponding to this test.
32 void GetFingerprintInternal(
33 uint64 obfuscated_gaia_id,
34 const gfx::Rect& window_bounds,
35 const gfx::Rect& content_bounds,
36 const blink::WebScreenInfo& screen_info,
37 const std::string& version,
38 const std::string& charset,
39 const std::string& accept_languages,
40 const base::Time& install_time,
41 const std::string& app_locale,
42 const std::string& user_agent,
43 const base::TimeDelta& timeout,
44 const base::Callback<void(scoped_ptr<Fingerprint>)>& callback);
46 } // namespace internal
48 // Constants that are passed verbatim to the fingerprinter code and should be
49 // serialized into the resulting protocol buffer.
50 const uint64 kObfuscatedGaiaId = GG_UINT64_C(16571487432910023183);
51 const char kCharset[] = "UTF-8";
52 const char kAcceptLanguages[] = "en-US,en";
53 const int kScreenColorDepth = 53;
55 // Geolocation constants that are passed verbatim to the fingerprinter code and
56 // should be serialized into the resulting protocol buffer.
57 const double kLatitude = -42.0;
58 const double kLongitude = 17.3;
59 const double kAltitude = 123.4;
60 const double kAccuracy = 73.7;
61 const int kGeolocationTime = 87;
63 class AutofillRiskFingerprintTest : public InProcessBrowserTest {
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) {}
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_GT(machine.plugin_size(), 0);
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());
105 EXPECT_FALSE(machine.has_graphics_card());
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());
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());
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());
135 // Some values have exact known (mocked out) values:
136 EXPECT_THAT(machine.requested_language(), ElementsAre("en-US", "en"));
137 EXPECT_EQ(kCharset, machine.charset());
138 EXPECT_EQ(kScreenColorDepth, machine.screen_color_depth());
139 EXPECT_EQ(unavailable_screen_bounds_.width(),
140 machine.unavailable_screen_size().width());
141 EXPECT_EQ(unavailable_screen_bounds_.height(),
142 machine.unavailable_screen_size().height());
143 EXPECT_EQ(Fingerprint::MachineCharacteristics::FEATURE_REQUEST_AUTOCOMPLETE,
144 machine.browser_feature());
145 EXPECT_EQ(content_bounds_.width(),
146 transient_state.inner_window_size().width());
147 EXPECT_EQ(content_bounds_.height(),
148 transient_state.inner_window_size().height());
149 EXPECT_EQ(window_bounds_.width(),
150 transient_state.outer_window_size().width());
151 EXPECT_EQ(window_bounds_.height(),
152 transient_state.outer_window_size().height());
153 EXPECT_EQ(kObfuscatedGaiaId, fingerprint->metadata().obfuscated_gaia_id());
154 EXPECT_EQ(kAltitude, location.altitude());
155 EXPECT_EQ(kLatitude, location.latitude());
156 EXPECT_EQ(kLongitude, location.longitude());
157 EXPECT_EQ(kAccuracy, location.accuracy());
158 EXPECT_EQ(kGeolocationTime, location.time_in_ms());
160 message_loop_.Quit();
164 // Constants defining bounds in the screen coordinate system that are passed
165 // verbatim to the fingerprinter code and should be serialized into the
166 // resulting protocol buffer. Declared as class members because gfx::Rect is
167 // not a POD type, so it cannot be statically initialized.
168 const gfx::Rect window_bounds_;
169 const gfx::Rect content_bounds_;
170 const gfx::Rect screen_bounds_;
171 const gfx::Rect available_screen_bounds_;
172 const gfx::Rect unavailable_screen_bounds_;
174 // A message loop to block on the asynchronous loading of the fingerprint.
175 base::MessageLoopForUI message_loop_;
178 // Test that getting a fingerprint works on some basic level.
179 IN_PROC_BROWSER_TEST_F(AutofillRiskFingerprintTest, GetFingerprint) {
180 content::Geoposition position;
181 position.latitude = kLatitude;
182 position.longitude = kLongitude;
183 position.altitude = kAltitude;
184 position.accuracy = kAccuracy;
186 base::Time::UnixEpoch() +
187 base::TimeDelta::FromMilliseconds(kGeolocationTime);
188 scoped_refptr<content::MessageLoopRunner> runner =
189 new content::MessageLoopRunner;
190 content::GeolocationProvider::OverrideLocationForTesting(
191 position, runner->QuitClosure());
194 blink::WebScreenInfo screen_info;
195 screen_info.depth = kScreenColorDepth;
196 screen_info.rect = blink::WebRect(screen_bounds_);
197 screen_info.availableRect = blink::WebRect(available_screen_bounds_);
199 internal::GetFingerprintInternal(
200 kObfuscatedGaiaId, window_bounds_, content_bounds_, screen_info,
201 "25.0.0.123", kCharset, kAcceptLanguages, base::Time::Now(),
202 g_browser_process->GetApplicationLocale(), GetUserAgent(),
203 base::TimeDelta::FromDays(1), // Ought to be longer than any test run.
204 base::Bind(&AutofillRiskFingerprintTest::GetFingerprintTestCallback,
205 base::Unretained(this)));
207 // Wait for the callback to be called.
212 } // namespace autofill