Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: content/browser/geolocation/location_arbitrator_unittest.cc

Issue 11412194: Cleanup: MockGeolocationArbitrator for GeolocationProvider tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make suggested changes. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "base/memory/scoped_ptr.h"
6 #include "content/browser/geolocation/fake_access_token_store.h"
7 #include "content/browser/geolocation/geolocation_observer.h"
8 #include "content/browser/geolocation/location_arbitrator.h"
9 #include "content/browser/geolocation/location_provider.h"
10 #include "content/browser/geolocation/mock_location_provider.h"
11 #include "content/public/common/geoposition.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using ::testing::NiceMock;
16
17 namespace content {
18
19 class MockLocationObserver : public GeolocationObserver {
20 public:
21 void InvalidateLastPosition() {
22 last_position_.latitude = 100;
23 last_position_.error_code = Geoposition::ERROR_CODE_NONE;
24 ASSERT_FALSE(last_position_.Validate());
25 }
26 // Delegate
27 virtual void OnLocationUpdate(const Geoposition& position) {
28 last_position_ = position;
29 }
30
31 Geoposition last_position_;
32 };
33
34 double g_fake_time_now_secs = 1;
35
36 base::Time GetTimeNowForTest() {
37 return base::Time::FromDoubleT(g_fake_time_now_secs);
38 }
39
40 void AdvanceTimeNow(const base::TimeDelta& delta) {
41 g_fake_time_now_secs += delta.InSecondsF();
42 }
43
44 void SetPositionFix(MockLocationProvider* provider,
45 double latitude,
46 double longitude,
47 double accuracy) {
48 Geoposition position;
49 position.error_code = Geoposition::ERROR_CODE_NONE;
50 position.latitude = latitude;
51 position.longitude = longitude;
52 position.accuracy = accuracy;
53 position.timestamp = GetTimeNowForTest();
54 ASSERT_TRUE(position.Validate());
55 provider->HandlePositionChanged(position);
56 }
57
58 void SetReferencePosition(MockLocationProvider* provider) {
59 SetPositionFix(provider, 51.0, -0.1, 400);
60 }
61
62 namespace {
63
64 class TestingGeolocationArbitrator : public GeolocationArbitrator {
65 public:
66 TestingGeolocationArbitrator(
67 GeolocationObserver* observer,
68 AccessTokenStore* access_token_store)
69 : GeolocationArbitrator(observer),
70 cell_(NULL),
71 gps_(NULL),
72 access_token_store_(access_token_store) {
73 }
74
75 virtual base::Time GetTimeNow() const OVERRIDE {
76 return GetTimeNowForTest();
77 }
78
79 virtual AccessTokenStore* NewAccessTokenStore() OVERRIDE {
80 return access_token_store_.get();
81 }
82
83 virtual LocationProviderBase* NewNetworkLocationProvider(
84 AccessTokenStore* access_token_store,
85 net::URLRequestContextGetter* context,
86 const GURL& url,
87 const string16& access_token) OVERRIDE {
88 return new MockLocationProvider(&cell_);
89 }
90
91 virtual LocationProviderBase* NewSystemLocationProvider() OVERRIDE {
92 return new MockLocationProvider(&gps_);
93 }
94
95 // Two location providers, with nice short names to make the tests more
96 // readable. Note |gps_| will only be set when there is a high accuracy
97 // observer registered (and |cell_| when there's at least one observer of any
98 // type).
99 MockLocationProvider* cell_;
100 MockLocationProvider* gps_;
101 scoped_refptr<AccessTokenStore> access_token_store_;
102 };
103
104 } // namespace
105
106 class GeolocationLocationArbitratorTest : public testing::Test {
107 protected:
108 // testing::Test
109 virtual void SetUp() {
110 access_token_store_ = new NiceMock<FakeAccessTokenStore>;
111 observer_.reset(new MockLocationObserver);
112 arbitrator_.reset(new TestingGeolocationArbitrator(
113 observer_.get(), access_token_store_.get()));
114 }
115
116 // testing::Test
117 virtual void TearDown() {
118 }
119
120 void CheckLastPositionInfo(double latitude,
121 double longitude,
122 double accuracy) {
123 Geoposition geoposition = observer_->last_position_;
124 EXPECT_TRUE(geoposition.Validate());
125 EXPECT_DOUBLE_EQ(latitude, geoposition.latitude);
126 EXPECT_DOUBLE_EQ(longitude, geoposition.longitude);
127 EXPECT_DOUBLE_EQ(accuracy, geoposition.accuracy);
128 }
129
130 base::TimeDelta SwitchOnFreshnessCliff() {
131 // Add 1, to ensure it meets any greater-than test.
132 return base::TimeDelta::FromMilliseconds(
133 GeolocationArbitrator::kFixStaleTimeoutMilliseconds + 1);
134 }
135
136 MockLocationProvider* cell() {
137 return arbitrator_->cell_;
138 }
139
140 MockLocationProvider* gps() {
141 return arbitrator_->gps_;
142 }
143
144 scoped_refptr<FakeAccessTokenStore> access_token_store_;
145 scoped_ptr<MockLocationObserver> observer_;
146 scoped_ptr<TestingGeolocationArbitrator> arbitrator_;
147 MessageLoop loop_;
148 };
149
150 TEST_F(GeolocationLocationArbitratorTest, CreateDestroy) {
151 EXPECT_TRUE(access_token_store_);
152 EXPECT_TRUE(arbitrator_ != NULL);
153 arbitrator_.reset();
154 SUCCEED();
155 }
156
157 TEST_F(GeolocationLocationArbitratorTest, OnPermissionGranted) {
158 EXPECT_FALSE(arbitrator_->HasPermissionBeenGranted());
159 arbitrator_->OnPermissionGranted();
160 EXPECT_TRUE(arbitrator_->HasPermissionBeenGranted());
161 // Can't check the provider has been notified without going through the
162 // motions to create the provider (see next test).
163 EXPECT_FALSE(cell());
164 EXPECT_FALSE(gps());
165 }
166
167 TEST_F(GeolocationLocationArbitratorTest, NormalUsage) {
168 ASSERT_TRUE(access_token_store_);
169 ASSERT_TRUE(arbitrator_ != NULL);
170
171 EXPECT_FALSE(cell());
172 EXPECT_FALSE(gps());
173 arbitrator_->StartProviders(GeolocationObserverOptions(false));
174
175 EXPECT_TRUE(access_token_store_->access_token_set_.empty());
176 EXPECT_TRUE(access_token_store_->access_token_set_.empty());
177
178 access_token_store_->NotifyDelegateTokensLoaded();
179 ASSERT_TRUE(cell());
180 EXPECT_TRUE(gps());
181 EXPECT_TRUE(cell()->has_listeners());
182 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, cell()->state_);
183 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, gps()->state_);
184 EXPECT_FALSE(observer_->last_position_.Validate());
185 EXPECT_EQ(Geoposition::ERROR_CODE_NONE,
186 observer_->last_position_.error_code);
187
188 SetReferencePosition(cell());
189
190 EXPECT_TRUE(observer_->last_position_.Validate() ||
191 observer_->last_position_.error_code !=
192 Geoposition::ERROR_CODE_NONE);
193 EXPECT_EQ(cell()->position_.latitude,
194 observer_->last_position_.latitude);
195
196 EXPECT_FALSE(cell()->is_permission_granted_);
197 EXPECT_FALSE(arbitrator_->HasPermissionBeenGranted());
198 arbitrator_->OnPermissionGranted();
199 EXPECT_TRUE(arbitrator_->HasPermissionBeenGranted());
200 EXPECT_TRUE(cell()->is_permission_granted_);
201 }
202
203 TEST_F(GeolocationLocationArbitratorTest, SetObserverOptions) {
204 arbitrator_->StartProviders(GeolocationObserverOptions(false));
205 access_token_store_->NotifyDelegateTokensLoaded();
206 ASSERT_TRUE(cell());
207 ASSERT_TRUE(gps());
208 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, cell()->state_);
209 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, gps()->state_);
210 SetReferencePosition(cell());
211 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, cell()->state_);
212 EXPECT_EQ(MockLocationProvider::LOW_ACCURACY, gps()->state_);
213 arbitrator_->StartProviders(GeolocationObserverOptions(true));
214 EXPECT_EQ(MockLocationProvider::HIGH_ACCURACY, cell()->state_);
215 EXPECT_EQ(MockLocationProvider::HIGH_ACCURACY, gps()->state_);
216 }
217
218 TEST_F(GeolocationLocationArbitratorTest, Arbitration) {
219 arbitrator_->StartProviders(GeolocationObserverOptions(false));
220 access_token_store_->NotifyDelegateTokensLoaded();
221 ASSERT_TRUE(cell());
222 ASSERT_TRUE(gps());
223
224 SetPositionFix(cell(), 1, 2, 150);
225
226 // First position available
227 EXPECT_TRUE(observer_->last_position_.Validate());
228 CheckLastPositionInfo(1, 2, 150);
229
230 SetPositionFix(gps(), 3, 4, 50);
231
232 // More accurate fix available
233 CheckLastPositionInfo(3, 4, 50);
234
235 SetPositionFix(cell(), 5, 6, 150);
236
237 // New fix is available but it's less accurate, older fix should be kept.
238 CheckLastPositionInfo(3, 4, 50);
239
240 // Advance time, and notify once again
241 AdvanceTimeNow(SwitchOnFreshnessCliff());
242 cell()->HandlePositionChanged(cell()->position_);
243
244 // New fix is available, less accurate but fresher
245 CheckLastPositionInfo(5, 6, 150);
246
247 // Advance time, and set a low accuracy position
248 AdvanceTimeNow(SwitchOnFreshnessCliff());
249 SetPositionFix(cell(), 5.676731, 139.629385, 1000);
250 CheckLastPositionInfo(5.676731, 139.629385, 1000);
251
252 // 15 secs later, step outside. Switches to gps signal.
253 AdvanceTimeNow(base::TimeDelta::FromSeconds(15));
254 SetPositionFix(gps(), 3.5676457, 139.629198, 50);
255 CheckLastPositionInfo(3.5676457, 139.629198, 50);
256
257 // 5 mins later switch cells while walking. Stay on gps.
258 AdvanceTimeNow(base::TimeDelta::FromMinutes(5));
259 SetPositionFix(cell(), 3.567832, 139.634648, 300);
260 SetPositionFix(gps(), 3.5677675, 139.632314, 50);
261 CheckLastPositionInfo(3.5677675, 139.632314, 50);
262
263 // Ride train and gps signal degrades slightly. Stay on fresher gps
264 AdvanceTimeNow(base::TimeDelta::FromMinutes(5));
265 SetPositionFix(gps(), 3.5679026, 139.634777, 300);
266 CheckLastPositionInfo(3.5679026, 139.634777, 300);
267
268 // 14 minutes later
269 AdvanceTimeNow(base::TimeDelta::FromMinutes(14));
270
271 // GPS reading misses a beat, but don't switch to cell yet to avoid
272 // oscillating.
273 SetPositionFix(gps(), 3.5659005, 139.682579, 300);
274
275 AdvanceTimeNow(base::TimeDelta::FromSeconds(7));
276 SetPositionFix(cell(), 3.5689579, 139.691420, 1000);
277 CheckLastPositionInfo(3.5659005, 139.682579, 300);
278
279 // 1 minute later
280 AdvanceTimeNow(base::TimeDelta::FromMinutes(1));
281
282 // Enter tunnel. Stay on fresher gps for a moment.
283 SetPositionFix(cell(), 3.5657078, 139.68922, 300);
284 SetPositionFix(gps(), 3.5657104, 139.690341, 300);
285 CheckLastPositionInfo(3.5657104, 139.690341, 300);
286
287 // 2 minutes later
288 AdvanceTimeNow(base::TimeDelta::FromMinutes(2));
289 // Arrive in station. Cell moves but GPS is stale. Switch to fresher cell.
290 SetPositionFix(cell(), 3.5658700, 139.069979, 1000);
291 CheckLastPositionInfo(3.5658700, 139.069979, 1000);
292 }
293
294 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698