OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string16.h" | 10 #include "base/string16.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // GeolocationObserver | 55 // GeolocationObserver |
56 virtual void OnLocationUpdate(const Geoposition& position) {} | 56 virtual void OnLocationUpdate(const Geoposition& position) {} |
57 }; | 57 }; |
58 | 58 |
59 class MockGeolocationObserver : public GeolocationObserver { | 59 class MockGeolocationObserver : public GeolocationObserver { |
60 public: | 60 public: |
61 // GeolocationObserver | 61 // GeolocationObserver |
62 MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); | 62 MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); |
63 }; | 63 }; |
64 | 64 |
| 65 class AsyncMockGeolocationObserver : public MockGeolocationObserver { |
| 66 public: |
| 67 // GeolocationObserver |
| 68 virtual void OnLocationUpdate(const Geoposition& position) { |
| 69 MockGeolocationObserver::OnLocationUpdate(position); |
| 70 MessageLoop::current()->Quit(); |
| 71 } |
| 72 }; |
| 73 |
65 class MockGeolocationCallbackWrapper { | 74 class MockGeolocationCallbackWrapper { |
66 public: | 75 public: |
67 MOCK_METHOD1(Callback, void(const Geoposition& position)); | 76 MOCK_METHOD1(Callback, void(const Geoposition& position)); |
68 }; | 77 }; |
69 | 78 |
70 class GeopositionEqMatcher | 79 class GeopositionEqMatcher |
71 : public MatcherInterface<const Geoposition&> { | 80 : public MatcherInterface<const Geoposition&> { |
72 public: | 81 public: |
73 explicit GeopositionEqMatcher(const Geoposition& expected) | 82 explicit GeopositionEqMatcher(const Geoposition& expected) |
74 : expected_(expected) {} | 83 : expected_(expected) {} |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 io_thread_(BrowserThread::IO, &message_loop_), | 121 io_thread_(BrowserThread::IO, &message_loop_), |
113 provider_(new LocationProviderForTestArbitrator) { | 122 provider_(new LocationProviderForTestArbitrator) { |
114 } | 123 } |
115 | 124 |
116 ~GeolocationProviderTest() {} | 125 ~GeolocationProviderTest() {} |
117 | 126 |
118 LocationProviderForTestArbitrator* provider() { return provider_.get(); } | 127 LocationProviderForTestArbitrator* provider() { return provider_.get(); } |
119 | 128 |
120 // Called on test thread. | 129 // Called on test thread. |
121 bool ProvidersStarted(); | 130 bool ProvidersStarted(); |
| 131 void SendMockLocation(const Geoposition& position); |
122 | 132 |
123 private: | 133 private: |
124 // Called on provider thread. | 134 // Called on provider thread. |
125 void GetProvidersStarted(bool* started); | 135 void GetProvidersStarted(bool* started); |
126 | 136 |
127 MessageLoop message_loop_; | 137 MessageLoop message_loop_; |
128 TestBrowserThread io_thread_; | 138 TestBrowserThread io_thread_; |
129 scoped_ptr<LocationProviderForTestArbitrator> provider_; | 139 scoped_ptr<LocationProviderForTestArbitrator> provider_; |
130 }; | 140 }; |
131 | 141 |
(...skipping 10 matching lines...) Expand all Loading... |
142 MessageLoop::QuitClosure()); | 152 MessageLoop::QuitClosure()); |
143 message_loop_.Run(); | 153 message_loop_.Run(); |
144 return started; | 154 return started; |
145 } | 155 } |
146 | 156 |
147 void GeolocationProviderTest::GetProvidersStarted(bool* started) { | 157 void GeolocationProviderTest::GetProvidersStarted(bool* started) { |
148 DCHECK(MessageLoop::current() == provider_->message_loop()); | 158 DCHECK(MessageLoop::current() == provider_->message_loop()); |
149 *started = provider_->mock_arbitrator()->providers_started(); | 159 *started = provider_->mock_arbitrator()->providers_started(); |
150 } | 160 } |
151 | 161 |
| 162 void GeolocationProviderTest::SendMockLocation(const Geoposition& position) { |
| 163 DCHECK(provider_->IsRunning()); |
| 164 DCHECK(MessageLoop::current() == &message_loop_); |
| 165 provider_->message_loop()->PostTask( |
| 166 FROM_HERE, |
| 167 base::Bind(&GeolocationProvider::OnLocationUpdate, |
| 168 base::Unretained(provider_.get()), |
| 169 position)); |
| 170 } |
152 | 171 |
153 // Regression test for http://crbug.com/59377 | 172 // Regression test for http://crbug.com/59377 |
154 TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { | 173 TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { |
155 EXPECT_FALSE(provider()->HasPermissionBeenGranted()); | 174 EXPECT_FALSE(provider()->HasPermissionBeenGranted()); |
156 provider()->OnPermissionGranted(); | 175 provider()->OnPermissionGranted(); |
157 EXPECT_TRUE(provider()->HasPermissionBeenGranted()); | 176 EXPECT_TRUE(provider()->HasPermissionBeenGranted()); |
158 } | 177 } |
159 | 178 |
160 TEST_F(GeolocationProviderTest, StartStop) { | 179 TEST_F(GeolocationProviderTest, StartStop) { |
161 EXPECT_FALSE(provider()->IsRunning()); | 180 EXPECT_FALSE(provider()->IsRunning()); |
162 NullGeolocationObserver null_observer; | 181 NullGeolocationObserver null_observer; |
163 GeolocationObserverOptions options; | 182 GeolocationObserverOptions options; |
164 provider()->AddObserver(&null_observer, options); | 183 provider()->AddObserver(&null_observer, options); |
165 EXPECT_TRUE(provider()->IsRunning()); | 184 EXPECT_TRUE(provider()->IsRunning()); |
166 EXPECT_TRUE(ProvidersStarted()); | 185 EXPECT_TRUE(ProvidersStarted()); |
167 | 186 |
168 provider()->RemoveObserver(&null_observer); | 187 provider()->RemoveObserver(&null_observer); |
169 EXPECT_FALSE(ProvidersStarted()); | 188 EXPECT_FALSE(ProvidersStarted()); |
170 EXPECT_TRUE(provider()->IsRunning()); | 189 EXPECT_TRUE(provider()->IsRunning()); |
171 } | 190 } |
172 | 191 |
| 192 TEST_F(GeolocationProviderTest, StalePositionNotSent) { |
| 193 Geoposition first_position; |
| 194 first_position.latitude = 12; |
| 195 first_position.longitude = 34; |
| 196 first_position.accuracy = 56; |
| 197 first_position.timestamp = base::Time::Now(); |
| 198 |
| 199 AsyncMockGeolocationObserver first_observer; |
| 200 GeolocationObserverOptions options; |
| 201 EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position))); |
| 202 provider()->AddObserver(&first_observer, options); |
| 203 SendMockLocation(first_position); |
| 204 MessageLoop::current()->Run(); |
| 205 |
| 206 provider()->RemoveObserver(&first_observer); |
| 207 |
| 208 Geoposition second_position; |
| 209 second_position.latitude = 13; |
| 210 second_position.longitude = 34; |
| 211 second_position.accuracy = 56; |
| 212 second_position.timestamp = base::Time::Now(); |
| 213 |
| 214 AsyncMockGeolocationObserver second_observer; |
| 215 |
| 216 // After adding a second observer, check that no unexpected position update |
| 217 // is sent. |
| 218 EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0); |
| 219 provider()->AddObserver(&second_observer, options); |
| 220 MessageLoop::current()->RunUntilIdle(); |
| 221 |
| 222 // The second observer should receive the new position now. |
| 223 EXPECT_CALL(second_observer, |
| 224 OnLocationUpdate(GeopositionEq(second_position))); |
| 225 SendMockLocation(second_position); |
| 226 MessageLoop::current()->Run(); |
| 227 |
| 228 provider()->RemoveObserver(&second_observer); |
| 229 EXPECT_FALSE(ProvidersStarted()); |
| 230 } |
| 231 |
173 TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { | 232 TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { |
174 Geoposition position; | 233 Geoposition position; |
175 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | 234 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
176 provider()->OverrideLocationForTesting(position); | 235 provider()->OverrideLocationForTesting(position); |
177 // Adding an observer when the location is overridden should synchronously | 236 // Adding an observer when the location is overridden should synchronously |
178 // update the observer with our overridden position. | 237 // update the observer with our overridden position. |
179 MockGeolocationObserver mock_observer; | 238 MockGeolocationObserver mock_observer; |
180 EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position))); | 239 EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position))); |
181 provider()->AddObserver(&mock_observer, GeolocationObserverOptions()); | 240 provider()->AddObserver(&mock_observer, GeolocationObserverOptions()); |
182 provider()->RemoveObserver(&mock_observer); | 241 provider()->RemoveObserver(&mock_observer); |
(...skipping 11 matching lines...) Expand all Loading... |
194 position.longitude = 34; | 253 position.longitude = 34; |
195 position.accuracy = 56; | 254 position.accuracy = 56; |
196 position.timestamp = base::Time::Now(); | 255 position.timestamp = base::Time::Now(); |
197 EXPECT_CALL(callback_wrapper, Callback(GeopositionEq(position))); | 256 EXPECT_CALL(callback_wrapper, Callback(GeopositionEq(position))); |
198 provider()->OverrideLocationForTesting(position); | 257 provider()->OverrideLocationForTesting(position); |
199 // Wait for the providers to be stopped now that all clients are gone. | 258 // Wait for the providers to be stopped now that all clients are gone. |
200 EXPECT_FALSE(ProvidersStarted()); | 259 EXPECT_FALSE(ProvidersStarted()); |
201 } | 260 } |
202 | 261 |
203 } // namespace content | 262 } // namespace content |
OLD | NEW |