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

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

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

Powered by Google App Engine
This is Rietveld 408576698