blob: 8181b6dcfdd300bf5eb8f730553e9bdd9ad5d8f2 [file] [log] [blame]
[email protected]a980b052012-04-20 12:42:491// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]fa7e91b82010-10-20 09:29:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]439eb402012-05-04 13:04:445#include "base/basictypes.h"
6#include "base/bind.h"
7#include "base/bind_helpers.h"
8#include "base/compiler_specific.h"
9#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/message_loop.h"
[email protected]60349d92011-09-06 11:00:4112#include "base/synchronization/waitable_event.h"
[email protected]439eb402012-05-04 13:04:4413#include "base/time.h"
14#include "content/browser/geolocation/arbitrator_dependency_factory.h"
[email protected]87678d992011-02-28 17:33:3015#include "content/browser/geolocation/fake_access_token_store.h"
[email protected]439eb402012-05-04 13:04:4416#include "content/browser/geolocation/geolocation_observer.h"
[email protected]87678d992011-02-28 17:33:3017#include "content/browser/geolocation/geolocation_provider.h"
18#include "content/browser/geolocation/location_arbitrator.h"
19#include "content/browser/geolocation/mock_location_provider.h"
[email protected]439eb402012-05-04 13:04:4420#include "content/public/browser/browser_thread.h"
21#include "content/test/test_browser_thread.h"
[email protected]60349d92011-09-06 11:00:4122#include "testing/gmock/include/gmock/gmock.h"
[email protected]fa7e91b82010-10-20 09:29:2723#include "testing/gtest/include/gtest/gtest.h"
24
[email protected]9fc4dab2012-05-02 20:48:3525using content::Geoposition;
[email protected]60349d92011-09-06 11:00:4126using testing::_;
27using testing::DoAll;
[email protected]60349d92011-09-06 11:00:4128using testing::Invoke;
29using testing::InvokeWithoutArgs;
[email protected]439eb402012-05-04 13:04:4430using testing::MakeMatcher;
31using testing::Matcher;
32using testing::MatcherInterface;
33using testing::MatchResultListener;
[email protected]60349d92011-09-06 11:00:4134
[email protected]fa7e91b82010-10-20 09:29:2735namespace {
[email protected]439eb402012-05-04 13:04:4436class NonSingletonGeolocationProvider : public GeolocationProvider {
37 public:
38 NonSingletonGeolocationProvider() {}
39
40 virtual ~NonSingletonGeolocationProvider() {}
41};
42
43class StartStopMockLocationProvider : public MockLocationProvider {
44 public:
45 explicit StartStopMockLocationProvider() : MockLocationProvider(&instance_) {
46 }
47
48 virtual ~StartStopMockLocationProvider() {
49 Die();
50 }
51
52 MOCK_METHOD0(Die, void());
53};
54
55class TestingDependencyFactory
56 : public DefaultGeolocationArbitratorDependencyFactory {
57 public:
58 TestingDependencyFactory(base::WaitableEvent* event) : event_(event) {
59 }
60
61 virtual content::AccessTokenStore* NewAccessTokenStore() OVERRIDE {
62 content::FakeAccessTokenStore* store = new content::FakeAccessTokenStore();
63 EXPECT_CALL(*store, LoadAccessTokens(_))
64 .WillRepeatedly(DoAll(
65 Invoke(store,
66 &content::FakeAccessTokenStore::DefaultLoadAccessTokens),
67 InvokeWithoutArgs(store,
68 &content::FakeAccessTokenStore::
69 NotifyDelegateTokensLoaded),
70 InvokeWithoutArgs(event_, &base::WaitableEvent::Signal)));
71 return store;
72 }
73
74 virtual LocationProviderBase* NewNetworkLocationProvider(
75 content::AccessTokenStore* access_token_store,
76 net::URLRequestContextGetter* context,
77 const GURL& url,
78 const string16& access_token) OVERRIDE {
79 StartStopMockLocationProvider* provider =
80 new StartStopMockLocationProvider();
81 EXPECT_CALL(*provider, Die())
82 .Times(1)
83 .WillOnce(InvokeWithoutArgs(event_, &base::WaitableEvent::Signal));
84 return provider;
85 }
86
87 virtual LocationProviderBase* NewSystemLocationProvider() OVERRIDE {
88 return NULL;
89 }
90
91 private:
92 base::WaitableEvent* event_;
93};
94
95class NullGeolocationObserver : public GeolocationObserver {
96 public:
97 // GeolocationObserver
98 virtual void OnLocationUpdate(const content::Geoposition& position) {}
99};
100
101class MockGeolocationObserver : public GeolocationObserver {
102 public:
103 // GeolocationObserver
104 MOCK_METHOD1(OnLocationUpdate, void(const content::Geoposition& position));
105};
106
107class MockGeolocationCallbackWrapper {
108 public:
109 MOCK_METHOD1(Callback, void(const content::Geoposition& position));
110};
111
112class GeopositionEqMatcher
113 : public MatcherInterface<const content::Geoposition&> {
114 public:
115 explicit GeopositionEqMatcher(const content::Geoposition& expected)
116 : expected_(expected) {}
117
118 virtual bool MatchAndExplain(const content::Geoposition& actual,
119 MatchResultListener* listener) const OVERRIDE {
120 return actual.latitude == expected_.latitude &&
121 actual.longitude == expected_.longitude &&
122 actual.altitude == expected_.altitude &&
123 actual.accuracy == expected_.accuracy &&
124 actual.altitude_accuracy == expected_.altitude_accuracy &&
125 actual.heading == expected_.heading &&
126 actual.speed == expected_.speed &&
127 actual.timestamp == expected_.timestamp &&
128 actual.error_code == expected_.error_code &&
129 actual.error_message == expected_.error_message;
130 }
131
132 virtual void DescribeTo(::std::ostream* os) const OVERRIDE {
133 *os << "which matches the expected position";
134 }
135
136 virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE{
137 *os << "which does not match the expected position";
138 }
139
140 private:
141 content::Geoposition expected_;
142
143 DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher);
144};
145
146Matcher<const content::Geoposition&> GeopositionEq(
147 const content::Geoposition& expected) {
148 return MakeMatcher(new GeopositionEqMatcher(expected));
149}
[email protected]fa7e91b82010-10-20 09:29:27150
151class GeolocationProviderTest : public testing::Test {
152 protected:
[email protected]fa7e91b82010-10-20 09:29:27153 GeolocationProviderTest()
[email protected]439eb402012-05-04 13:04:44154 : message_loop_(),
155 io_thread_(content::BrowserThread::IO, &message_loop_),
156 event_(false, false),
157 dependency_factory_(new TestingDependencyFactory(&event_)),
158 provider_(new NonSingletonGeolocationProvider) {
[email protected]b7d6acc2011-02-03 11:01:50159 GeolocationArbitrator::SetDependencyFactoryForTest(
160 dependency_factory_.get());
161 }
162
[email protected]439eb402012-05-04 13:04:44163 ~GeolocationProviderTest() {
[email protected]b7d6acc2011-02-03 11:01:50164 GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
165 }
166
[email protected]d4cee672012-05-09 17:36:07167 void WaitAndReset() {
168 event_.Wait();
169 event_.Reset();
170 }
171
[email protected]fa7e91b82010-10-20 09:29:27172 MessageLoop message_loop_;
[email protected]439eb402012-05-04 13:04:44173 content::TestBrowserThread io_thread_;
[email protected]fa7e91b82010-10-20 09:29:27174
[email protected]439eb402012-05-04 13:04:44175 base::WaitableEvent event_;
176 scoped_refptr<TestingDependencyFactory> dependency_factory_;
177 scoped_ptr<NonSingletonGeolocationProvider> provider_;
[email protected]fa7e91b82010-10-20 09:29:27178};
179
180// Regression test for http://crbug.com/59377
181TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
182 EXPECT_FALSE(provider_->HasPermissionBeenGranted());
[email protected]a980b052012-04-20 12:42:49183 provider_->OnPermissionGranted();
[email protected]fa7e91b82010-10-20 09:29:27184 EXPECT_TRUE(provider_->HasPermissionBeenGranted());
185}
186
[email protected]b7d6acc2011-02-03 11:01:50187TEST_F(GeolocationProviderTest, StartStop) {
[email protected]b7d6acc2011-02-03 11:01:50188 EXPECT_FALSE(provider_->IsRunning());
189 NullGeolocationObserver null_observer;
190 GeolocationObserverOptions options;
191 provider_->AddObserver(&null_observer, options);
[email protected]60349d92011-09-06 11:00:41192 EXPECT_TRUE(provider_->IsRunning());
193 // Wait for token load request from the arbitrator to come through.
[email protected]d4cee672012-05-09 17:36:07194 WaitAndReset();
[email protected]439eb402012-05-04 13:04:44195
[email protected]b7d6acc2011-02-03 11:01:50196 EXPECT_EQ(MockLocationProvider::instance_->state_,
197 MockLocationProvider::LOW_ACCURACY);
[email protected]b7d6acc2011-02-03 11:01:50198 provider_->RemoveObserver(&null_observer);
[email protected]d4cee672012-05-09 17:36:07199 // Wait for the providers to be stopped now that all clients are gone.
200 WaitAndReset();
[email protected]b7d6acc2011-02-03 11:01:50201 EXPECT_TRUE(provider_->IsRunning());
[email protected]b7d6acc2011-02-03 11:01:50202}
203
[email protected]02a5fe292012-04-25 21:47:56204TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
[email protected]439eb402012-05-04 13:04:44205 content::Geoposition position;
206 position.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
207 provider_->OverrideLocationForTesting(position);
208 // Adding an observer when the location is overridden should synchronously
209 // update the observer with our overridden position.
[email protected]02a5fe292012-04-25 21:47:56210 MockGeolocationObserver mock_observer;
[email protected]439eb402012-05-04 13:04:44211 EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position)));
[email protected]02a5fe292012-04-25 21:47:56212 provider_->AddObserver(&mock_observer, GeolocationObserverOptions());
[email protected]d4cee672012-05-09 17:36:07213 // Wait for token load request from the arbitrator to come through.
214 WaitAndReset();
215
[email protected]02a5fe292012-04-25 21:47:56216 provider_->RemoveObserver(&mock_observer);
[email protected]d4cee672012-05-09 17:36:07217 // Wait for the providers to be stopped now that all clients are gone.
218 WaitAndReset();
[email protected]439eb402012-05-04 13:04:44219}
[email protected]02a5fe292012-04-25 21:47:56220
[email protected]439eb402012-05-04 13:04:44221TEST_F(GeolocationProviderTest, Callback) {
222 MockGeolocationCallbackWrapper callback_wrapper;
223 provider_->RequestCallback(
224 base::Bind(&MockGeolocationCallbackWrapper::Callback,
225 base::Unretained(&callback_wrapper)));
[email protected]d4cee672012-05-09 17:36:07226 // Wait for token load request from the arbitrator to come through.
227 WaitAndReset();
[email protected]439eb402012-05-04 13:04:44228
229 content::Geoposition position;
230 position.latitude = 12;
231 position.longitude = 34;
232 position.accuracy = 56;
233 position.timestamp = base::Time::Now();
234 EXPECT_CALL(callback_wrapper, Callback(GeopositionEq(position)));
235 provider_->OverrideLocationForTesting(position);
[email protected]d4cee672012-05-09 17:36:07236 // Wait for the providers to be stopped now that all clients are gone.
237 WaitAndReset();
[email protected]02a5fe292012-04-25 21:47:56238}
239
[email protected]fa7e91b82010-10-20 09:29:27240} // namespace