[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / content / browser / geolocation / location_arbitrator_impl_unittest.cc
blobb385f868d952b7acf468783b2ddb5b88a0fe18a9
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.
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_impl.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"
15 using ::testing::NiceMock;
17 namespace content {
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());
26 // Delegate
27 virtual void OnLocationUpdate(const Geoposition& position) {
28 last_position_ = position;
31 Geoposition last_position_;
34 double g_fake_time_now_secs = 1;
36 base::Time GetTimeNowForTest() {
37 return base::Time::FromDoubleT(g_fake_time_now_secs);
40 void AdvanceTimeNow(const base::TimeDelta& delta) {
41 g_fake_time_now_secs += delta.InSecondsF();
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);
58 void SetReferencePosition(MockLocationProvider* provider) {
59 SetPositionFix(provider, 51.0, -0.1, 400);
62 namespace {
64 class TestingGeolocationArbitrator : public GeolocationArbitratorImpl {
65 public:
66 TestingGeolocationArbitrator(
67 GeolocationObserver* observer,
68 AccessTokenStore* access_token_store)
69 : GeolocationArbitratorImpl(observer),
70 cell_(NULL),
71 gps_(NULL),
72 access_token_store_(access_token_store) {
75 virtual base::Time GetTimeNow() const OVERRIDE {
76 return GetTimeNowForTest();
79 virtual AccessTokenStore* NewAccessTokenStore() OVERRIDE {
80 return access_token_store_.get();
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_);
91 virtual LocationProviderBase* NewSystemLocationProvider() OVERRIDE {
92 return new MockLocationProvider(&gps_);
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_;
104 } // namespace
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()));
116 // testing::Test
117 virtual void TearDown() {
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);
130 base::TimeDelta SwitchOnFreshnessCliff() {
131 // Add 1, to ensure it meets any greater-than test.
132 return base::TimeDelta::FromMilliseconds(
133 GeolocationArbitratorImpl::kFixStaleTimeoutMilliseconds + 1);
136 MockLocationProvider* cell() {
137 return arbitrator_->cell_;
140 MockLocationProvider* gps() {
141 return arbitrator_->gps_;
144 scoped_refptr<FakeAccessTokenStore> access_token_store_;
145 scoped_ptr<MockLocationObserver> observer_;
146 scoped_ptr<TestingGeolocationArbitrator> arbitrator_;
147 MessageLoop loop_;
150 TEST_F(GeolocationLocationArbitratorTest, CreateDestroy) {
151 EXPECT_TRUE(access_token_store_);
152 EXPECT_TRUE(arbitrator_ != NULL);
153 arbitrator_.reset();
154 SUCCEED();
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());
167 TEST_F(GeolocationLocationArbitratorTest, NormalUsage) {
168 ASSERT_TRUE(access_token_store_);
169 ASSERT_TRUE(arbitrator_ != NULL);
171 EXPECT_FALSE(cell());
172 EXPECT_FALSE(gps());
173 arbitrator_->StartProviders(GeolocationObserverOptions(false));
175 EXPECT_TRUE(access_token_store_->access_token_set_.empty());
176 EXPECT_TRUE(access_token_store_->access_token_set_.empty());
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);
188 SetReferencePosition(cell());
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);
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_);
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_);
218 TEST_F(GeolocationLocationArbitratorTest, Arbitration) {
219 arbitrator_->StartProviders(GeolocationObserverOptions(false));
220 access_token_store_->NotifyDelegateTokensLoaded();
221 ASSERT_TRUE(cell());
222 ASSERT_TRUE(gps());
224 SetPositionFix(cell(), 1, 2, 150);
226 // First position available
227 EXPECT_TRUE(observer_->last_position_.Validate());
228 CheckLastPositionInfo(1, 2, 150);
230 SetPositionFix(gps(), 3, 4, 50);
232 // More accurate fix available
233 CheckLastPositionInfo(3, 4, 50);
235 SetPositionFix(cell(), 5, 6, 150);
237 // New fix is available but it's less accurate, older fix should be kept.
238 CheckLastPositionInfo(3, 4, 50);
240 // Advance time, and notify once again
241 AdvanceTimeNow(SwitchOnFreshnessCliff());
242 cell()->HandlePositionChanged(cell()->position_);
244 // New fix is available, less accurate but fresher
245 CheckLastPositionInfo(5, 6, 150);
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);
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);
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);
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);
268 // 14 minutes later
269 AdvanceTimeNow(base::TimeDelta::FromMinutes(14));
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);
275 AdvanceTimeNow(base::TimeDelta::FromSeconds(7));
276 SetPositionFix(cell(), 3.5689579, 139.691420, 1000);
277 CheckLastPositionInfo(3.5659005, 139.682579, 300);
279 // 1 minute later
280 AdvanceTimeNow(base::TimeDelta::FromMinutes(1));
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);
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);
294 } // namespace content