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