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

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

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

Powered by Google App Engine
This is Rietveld 408576698