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

Side by Side Diff: device/geolocation/geolocation_provider_impl_unittest.cc

Issue 2192683003: Revert of Reland: Geolocation: move from content/browser to device/ (patchset #2 id:20001 of https:… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2810
Patch Set: Created 4 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "device/geolocation/geolocation_provider_impl.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/location.h"
12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string16.h"
18 #include "base/time/time.h"
19 #include "device/geolocation/access_token_store.h"
20 #include "device/geolocation/mock_location_arbitrator.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using testing::MakeMatcher;
25 using testing::Matcher;
26 using testing::MatcherInterface;
27 using testing::MatchResultListener;
28
29 namespace device {
30
31 class LocationProviderForTestArbitrator : public GeolocationProviderImpl {
32 public:
33 LocationProviderForTestArbitrator() : mock_arbitrator_(NULL) {}
34 ~LocationProviderForTestArbitrator() override {}
35
36 // Only valid for use on the geolocation thread.
37 MockLocationArbitrator* mock_arbitrator() const {
38 return mock_arbitrator_;
39 }
40
41 protected:
42 // GeolocationProviderImpl implementation:
43 std::unique_ptr<LocationArbitrator> CreateArbitrator() override;
44
45 private:
46 // An alias to the arbitrator stored in the super class, where it is owned.
47 MockLocationArbitrator* mock_arbitrator_;
48 };
49
50 std::unique_ptr<LocationArbitrator>
51 LocationProviderForTestArbitrator::CreateArbitrator() {
52 DCHECK(mock_arbitrator_ == NULL);
53 mock_arbitrator_ = new MockLocationArbitrator;
54 return base::WrapUnique(mock_arbitrator_);
55 }
56
57 class GeolocationObserver {
58 public:
59 virtual ~GeolocationObserver() {}
60 virtual void OnLocationUpdate(const Geoposition& position) = 0;
61 };
62
63 class MockGeolocationObserver : public GeolocationObserver {
64 public:
65 MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position));
66 };
67
68 class AsyncMockGeolocationObserver : public MockGeolocationObserver {
69 public:
70 void OnLocationUpdate(const Geoposition& position) override {
71 MockGeolocationObserver::OnLocationUpdate(position);
72 base::MessageLoop::current()->QuitWhenIdle();
73 }
74 };
75
76 class MockGeolocationCallbackWrapper {
77 public:
78 MOCK_METHOD1(Callback, void(const Geoposition& position));
79 };
80
81 class GeopositionEqMatcher
82 : public MatcherInterface<const Geoposition&> {
83 public:
84 explicit GeopositionEqMatcher(const Geoposition& expected)
85 : expected_(expected) {}
86
87 bool MatchAndExplain(const Geoposition& actual,
88 MatchResultListener* listener) const override {
89 return actual.latitude == expected_.latitude &&
90 actual.longitude == expected_.longitude &&
91 actual.altitude == expected_.altitude &&
92 actual.accuracy == expected_.accuracy &&
93 actual.altitude_accuracy == expected_.altitude_accuracy &&
94 actual.heading == expected_.heading &&
95 actual.speed == expected_.speed &&
96 actual.timestamp == expected_.timestamp &&
97 actual.error_code == expected_.error_code &&
98 actual.error_message == expected_.error_message;
99 }
100
101 void DescribeTo(::std::ostream* os) const override {
102 *os << "which matches the expected position";
103 }
104
105 void DescribeNegationTo(::std::ostream* os) const override {
106 *os << "which does not match the expected position";
107 }
108
109 private:
110 Geoposition expected_;
111
112 DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher);
113 };
114
115 Matcher<const Geoposition&> GeopositionEq(const Geoposition& expected) {
116 return MakeMatcher(new GeopositionEqMatcher(expected));
117 }
118
119 class GeolocationProviderTest : public testing::Test {
120 protected:
121 GeolocationProviderTest()
122 : message_loop_(),
123 provider_(new LocationProviderForTestArbitrator) {
124 }
125
126 ~GeolocationProviderTest() override {}
127
128 LocationProviderForTestArbitrator* provider() { return provider_.get(); }
129
130 // Called on test thread.
131 bool ProvidersStarted();
132 void SendMockLocation(const Geoposition& position);
133
134 private:
135 // Called on provider thread.
136 void GetProvidersStarted(bool* started);
137
138 base::MessageLoopForUI message_loop_;
139 std::unique_ptr<LocationProviderForTestArbitrator> provider_;
140 };
141
142
143 bool GeolocationProviderTest::ProvidersStarted() {
144 DCHECK(provider_->IsRunning());
145 DCHECK(base::MessageLoop::current() == &message_loop_);
146 bool started;
147 provider_->task_runner()->PostTaskAndReply(
148 FROM_HERE, base::Bind(&GeolocationProviderTest::GetProvidersStarted,
149 base::Unretained(this), &started),
150 base::MessageLoop::QuitWhenIdleClosure());
151 base::RunLoop().Run();
152 return started;
153 }
154
155 void GeolocationProviderTest::GetProvidersStarted(bool* started) {
156 DCHECK(provider_->task_runner()->BelongsToCurrentThread());
157 *started = provider_->mock_arbitrator()->providers_started();
158 }
159
160 void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
161 DCHECK(provider_->IsRunning());
162 DCHECK(base::MessageLoop::current() == &message_loop_);
163 provider_->task_runner()->PostTask(
164 FROM_HERE, base::Bind(&GeolocationProviderImpl::OnLocationUpdate,
165 base::Unretained(provider_.get()), position));
166 }
167
168 // Regression test for http://crbug.com/59377
169 TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
170 EXPECT_FALSE(provider()->user_did_opt_into_location_services_for_testing());
171 provider()->UserDidOptIntoLocationServices();
172 EXPECT_TRUE(provider()->user_did_opt_into_location_services_for_testing());
173 }
174
175 void DummyFunction(const Geoposition& position) {
176 }
177
178 TEST_F(GeolocationProviderTest, StartStop) {
179 EXPECT_FALSE(provider()->IsRunning());
180 GeolocationProviderImpl::LocationUpdateCallback callback =
181 base::Bind(&DummyFunction);
182 std::unique_ptr<GeolocationProvider::Subscription> subscription =
183 provider()->AddLocationUpdateCallback(callback, false);
184 EXPECT_TRUE(provider()->IsRunning());
185 EXPECT_TRUE(ProvidersStarted());
186
187 subscription.reset();
188
189 EXPECT_FALSE(ProvidersStarted());
190 EXPECT_TRUE(provider()->IsRunning());
191 }
192
193 TEST_F(GeolocationProviderTest, StalePositionNotSent) {
194 Geoposition first_position;
195 first_position.latitude = 12;
196 first_position.longitude = 34;
197 first_position.accuracy = 56;
198 first_position.timestamp = base::Time::Now();
199
200 AsyncMockGeolocationObserver first_observer;
201 GeolocationProviderImpl::LocationUpdateCallback first_callback = base::Bind(
202 &MockGeolocationObserver::OnLocationUpdate,
203 base::Unretained(&first_observer));
204 EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
205 std::unique_ptr<GeolocationProvider::Subscription> subscription =
206 provider()->AddLocationUpdateCallback(first_callback, false);
207 SendMockLocation(first_position);
208 base::RunLoop().Run();
209
210 subscription.reset();
211
212 Geoposition second_position;
213 second_position.latitude = 13;
214 second_position.longitude = 34;
215 second_position.accuracy = 56;
216 second_position.timestamp = base::Time::Now();
217
218 AsyncMockGeolocationObserver second_observer;
219
220 // After adding a second observer, check that no unexpected position update
221 // is sent.
222 EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0);
223 GeolocationProviderImpl::LocationUpdateCallback second_callback = base::Bind(
224 &MockGeolocationObserver::OnLocationUpdate,
225 base::Unretained(&second_observer));
226 std::unique_ptr<GeolocationProvider::Subscription> subscription2 =
227 provider()->AddLocationUpdateCallback(second_callback, false);
228 base::RunLoop().RunUntilIdle();
229
230 // The second observer should receive the new position now.
231 EXPECT_CALL(second_observer,
232 OnLocationUpdate(GeopositionEq(second_position)));
233 SendMockLocation(second_position);
234 base::RunLoop().Run();
235
236 subscription2.reset();
237 EXPECT_FALSE(ProvidersStarted());
238 }
239
240 TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
241 Geoposition position;
242 position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
243 provider()->OverrideLocationForTesting(position);
244 // Adding an observer when the location is overridden should synchronously
245 // update the observer with our overridden position.
246 MockGeolocationObserver mock_observer;
247 EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position)));
248 GeolocationProviderImpl::LocationUpdateCallback callback = base::Bind(
249 &MockGeolocationObserver::OnLocationUpdate,
250 base::Unretained(&mock_observer));
251 std::unique_ptr<GeolocationProvider::Subscription> subscription =
252 provider()->AddLocationUpdateCallback(callback, false);
253 subscription.reset();
254 // Wait for the providers to be stopped now that all clients are gone.
255 EXPECT_FALSE(ProvidersStarted());
256 }
257
258 } // namespace device
OLDNEW
« no previous file with comments | « device/geolocation/geolocation_provider_impl.cc ('k') | device/geolocation/geolocation_service_context.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698