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 |