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