| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 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 "content/browser/browser_thread_impl.h" | |
| 6 #include "content/browser/geolocation/gps_location_provider_linux.h" | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 | |
| 11 namespace content { | |
| 12 | |
| 13 class MockLibGps : public LibGps { | |
| 14 public: | |
| 15 MockLibGps(); | |
| 16 virtual ~MockLibGps(); | |
| 17 | |
| 18 virtual bool GetPositionIfFixed(Geoposition* position) OVERRIDE { | |
| 19 CHECK(position); | |
| 20 ++get_position_calls_; | |
| 21 *position = get_position_; | |
| 22 return get_position_ret_; | |
| 23 } | |
| 24 | |
| 25 static int gps_open_stub(const char*, const char*, struct gps_data_t*) { | |
| 26 CHECK(g_instance_); | |
| 27 g_instance_->gps_open_calls_++; | |
| 28 return g_instance_->gps_open_ret_; | |
| 29 } | |
| 30 | |
| 31 static int gps_close_stub(struct gps_data_t*) { | |
| 32 return 0; | |
| 33 } | |
| 34 | |
| 35 static int gps_read_stub(struct gps_data_t*) { | |
| 36 CHECK(g_instance_); | |
| 37 g_instance_->gps_read_calls_++; | |
| 38 return g_instance_->gps_read_ret_; | |
| 39 } | |
| 40 | |
| 41 int get_position_calls_; | |
| 42 bool get_position_ret_; | |
| 43 int gps_open_calls_; | |
| 44 int gps_open_ret_; | |
| 45 int gps_read_calls_; | |
| 46 int gps_read_ret_; | |
| 47 Geoposition get_position_; | |
| 48 static MockLibGps* g_instance_; | |
| 49 }; | |
| 50 | |
| 51 class GeolocationGpsProviderLinuxTests : public testing::Test { | |
| 52 public: | |
| 53 GeolocationGpsProviderLinuxTests(); | |
| 54 virtual ~GeolocationGpsProviderLinuxTests(); | |
| 55 | |
| 56 static LibGps* NewMockLibGps() { | |
| 57 return new MockLibGps(); | |
| 58 } | |
| 59 static LibGps* NoLibGpsFactory() { | |
| 60 return NULL; | |
| 61 } | |
| 62 | |
| 63 protected: | |
| 64 base::MessageLoop message_loop_; | |
| 65 BrowserThreadImpl ui_thread_; | |
| 66 scoped_ptr<LocationProvider> provider_; | |
| 67 }; | |
| 68 | |
| 69 void CheckValidPosition(const Geoposition& expected, | |
| 70 const Geoposition& actual) { | |
| 71 EXPECT_TRUE(actual.Validate()); | |
| 72 EXPECT_DOUBLE_EQ(expected.latitude, actual.latitude); | |
| 73 EXPECT_DOUBLE_EQ(expected.longitude, actual.longitude); | |
| 74 EXPECT_DOUBLE_EQ(expected.accuracy, actual.accuracy); | |
| 75 } | |
| 76 | |
| 77 void QuitMessageLoopAfterUpdate(const LocationProvider* provider, | |
| 78 const Geoposition& position) { | |
| 79 base::MessageLoop::current()->Quit(); | |
| 80 } | |
| 81 | |
| 82 MockLibGps* MockLibGps::g_instance_ = NULL; | |
| 83 | |
| 84 MockLibGps::MockLibGps() | |
| 85 : get_position_calls_(0), | |
| 86 get_position_ret_(true), | |
| 87 gps_open_calls_(0), | |
| 88 gps_open_ret_(0), | |
| 89 gps_read_calls_(0), | |
| 90 gps_read_ret_(0) { | |
| 91 get_position_.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | |
| 92 EXPECT_FALSE(g_instance_); | |
| 93 g_instance_ = this; | |
| 94 #if defined(USE_LIBGPS) | |
| 95 libgps_loader_.gps_open = gps_open_stub; | |
| 96 libgps_loader_.gps_close = gps_close_stub; | |
| 97 libgps_loader_.gps_read = gps_read_stub; | |
| 98 #endif // defined(USE_LIBGPS) | |
| 99 } | |
| 100 | |
| 101 MockLibGps::~MockLibGps() { | |
| 102 EXPECT_EQ(this, g_instance_); | |
| 103 g_instance_ = NULL; | |
| 104 } | |
| 105 | |
| 106 GeolocationGpsProviderLinuxTests::GeolocationGpsProviderLinuxTests() | |
| 107 : ui_thread_(BrowserThread::IO, &message_loop_), | |
| 108 provider_(new GpsLocationProviderLinux(NewMockLibGps)) { | |
| 109 provider_->SetUpdateCallback(base::Bind(&QuitMessageLoopAfterUpdate)); | |
| 110 } | |
| 111 | |
| 112 GeolocationGpsProviderLinuxTests::~GeolocationGpsProviderLinuxTests() { | |
| 113 } | |
| 114 | |
| 115 TEST_F(GeolocationGpsProviderLinuxTests, NoLibGpsInstalled) { | |
| 116 provider_.reset(new GpsLocationProviderLinux(NoLibGpsFactory)); | |
| 117 ASSERT_TRUE(provider_.get()); | |
| 118 const bool ok = provider_->StartProvider(true); | |
| 119 EXPECT_FALSE(ok); | |
| 120 Geoposition position; | |
| 121 provider_->GetPosition(&position); | |
| 122 EXPECT_FALSE(position.Validate()); | |
| 123 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code); | |
| 124 } | |
| 125 | |
| 126 #if defined(OS_CHROMEOS) | |
| 127 | |
| 128 TEST_F(GeolocationGpsProviderLinuxTests, GetPosition) { | |
| 129 ASSERT_TRUE(provider_.get()); | |
| 130 const bool ok = provider_->StartProvider(true); | |
| 131 EXPECT_TRUE(ok); | |
| 132 ASSERT_TRUE(MockLibGps::g_instance_); | |
| 133 EXPECT_EQ(0, MockLibGps::g_instance_->get_position_calls_); | |
| 134 EXPECT_EQ(0, MockLibGps::g_instance_->gps_open_calls_); | |
| 135 EXPECT_EQ(0, MockLibGps::g_instance_->gps_read_calls_); | |
| 136 Geoposition position; | |
| 137 provider_->GetPosition(&position); | |
| 138 EXPECT_FALSE(position.Validate()); | |
| 139 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code); | |
| 140 MockLibGps::g_instance_->get_position_.error_code = | |
| 141 Geoposition::ERROR_CODE_NONE; | |
| 142 MockLibGps::g_instance_->get_position_.latitude = 4.5; | |
| 143 MockLibGps::g_instance_->get_position_.longitude = -34.1; | |
| 144 MockLibGps::g_instance_->get_position_.accuracy = 345; | |
| 145 MockLibGps::g_instance_->get_position_.timestamp = | |
| 146 base::Time::FromDoubleT(200); | |
| 147 EXPECT_TRUE(MockLibGps::g_instance_->get_position_.Validate()); | |
| 148 base::MessageLoop::current()->Run(); | |
| 149 EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_); | |
| 150 EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_); | |
| 151 EXPECT_EQ(1, MockLibGps::g_instance_->gps_read_calls_); | |
| 152 provider_->GetPosition(&position); | |
| 153 CheckValidPosition(MockLibGps::g_instance_->get_position_, position); | |
| 154 | |
| 155 // Movement. This will block for up to half a second. | |
| 156 MockLibGps::g_instance_->get_position_.latitude += 0.01; | |
| 157 base::MessageLoop::current()->Run(); | |
| 158 provider_->GetPosition(&position); | |
| 159 EXPECT_EQ(2, MockLibGps::g_instance_->get_position_calls_); | |
| 160 EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_); | |
| 161 EXPECT_EQ(2, MockLibGps::g_instance_->gps_read_calls_); | |
| 162 CheckValidPosition(MockLibGps::g_instance_->get_position_, position); | |
| 163 } | |
| 164 | |
| 165 void EnableGpsOpenCallback() { | |
| 166 CHECK(MockLibGps::g_instance_); | |
| 167 MockLibGps::g_instance_->gps_open_ret_ = 0; | |
| 168 } | |
| 169 | |
| 170 TEST_F(GeolocationGpsProviderLinuxTests, LibGpsReconnect) { | |
| 171 // Setup gpsd reconnect interval to be 1000ms to speed up test. | |
| 172 GpsLocationProviderLinux* gps_provider = | |
| 173 static_cast<GpsLocationProviderLinux*>(provider_.get()); | |
| 174 gps_provider->SetGpsdReconnectIntervalMillis(1000); | |
| 175 gps_provider->SetPollPeriodMovingMillis(200); | |
| 176 const bool ok = provider_->StartProvider(true); | |
| 177 EXPECT_TRUE(ok); | |
| 178 ASSERT_TRUE(MockLibGps::g_instance_); | |
| 179 // Let gps_open() fails, and so will LibGps::Start(). | |
| 180 // Reconnect will happen in 1000ms. | |
| 181 MockLibGps::g_instance_->gps_open_ret_ = 1; | |
| 182 Geoposition position; | |
| 183 MockLibGps::g_instance_->get_position_.error_code = | |
| 184 Geoposition::ERROR_CODE_NONE; | |
| 185 MockLibGps::g_instance_->get_position_.latitude = 4.5; | |
| 186 MockLibGps::g_instance_->get_position_.longitude = -34.1; | |
| 187 MockLibGps::g_instance_->get_position_.accuracy = 345; | |
| 188 MockLibGps::g_instance_->get_position_.timestamp = | |
| 189 base::Time::FromDoubleT(200); | |
| 190 EXPECT_TRUE(MockLibGps::g_instance_->get_position_.Validate()); | |
| 191 // This task makes gps_open() and LibGps::Start() to succeed after | |
| 192 // 1500ms. | |
| 193 base::MessageLoop::current()->PostDelayedTask( | |
| 194 FROM_HERE, | |
| 195 base::Bind(&EnableGpsOpenCallback), | |
| 196 base::TimeDelta::FromMilliseconds(1500)); | |
| 197 base::MessageLoop::current()->Run(); | |
| 198 provider_->GetPosition(&position); | |
| 199 EXPECT_TRUE(position.Validate()); | |
| 200 // 3 gps_open() calls are expected (2 failures and 1 success) | |
| 201 EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_); | |
| 202 EXPECT_EQ(3, MockLibGps::g_instance_->gps_open_calls_); | |
| 203 EXPECT_EQ(1, MockLibGps::g_instance_->gps_read_calls_); | |
| 204 } | |
| 205 | |
| 206 #endif // #if defined(OS_CHROMEOS) | |
| 207 | |
| 208 } // namespace content | |
| OLD | NEW |