Commit baaf1843 authored by jknotten@chromium.org's avatar jknotten@chromium.org

Do not stale cached position in GeolocationProvider::AddObserver.

WebKit is expecting a fresh geolocation positions from the
GeolocationClient, so we should try to send a fresh geolocation
position.

TEST=
BUG=157244


Review URL: https://chromiumcodereview.appspot.com/11312210

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170806 0039d316-1c4b-4281-b951-d872f2087c98
parent 7707b21c
...@@ -103,6 +103,9 @@ void GeolocationProvider::OnClientsChanged() { ...@@ -103,6 +103,9 @@ void GeolocationProvider::OnClientsChanged() {
base::Closure task; base::Closure task;
if (observers_.empty() && callbacks_.empty()) { if (observers_.empty() && callbacks_.empty()) {
DCHECK(IsRunning()); DCHECK(IsRunning());
// We have no more observers, so we clear the cached geoposition so that
// when the next observer is added we will not provide a stale position.
position_ = Geoposition();
task = base::Bind(&GeolocationProvider::StopProviders, task = base::Bind(&GeolocationProvider::StopProviders,
base::Unretained(this)); base::Unretained(this));
} else { } else {
......
...@@ -62,6 +62,15 @@ class MockGeolocationObserver : public GeolocationObserver { ...@@ -62,6 +62,15 @@ class MockGeolocationObserver : public GeolocationObserver {
MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position));
}; };
class AsyncMockGeolocationObserver : public MockGeolocationObserver {
public:
// GeolocationObserver
virtual void OnLocationUpdate(const Geoposition& position) {
MockGeolocationObserver::OnLocationUpdate(position);
MessageLoop::current()->Quit();
}
};
class MockGeolocationCallbackWrapper { class MockGeolocationCallbackWrapper {
public: public:
MOCK_METHOD1(Callback, void(const Geoposition& position)); MOCK_METHOD1(Callback, void(const Geoposition& position));
...@@ -119,6 +128,7 @@ class GeolocationProviderTest : public testing::Test { ...@@ -119,6 +128,7 @@ class GeolocationProviderTest : public testing::Test {
// Called on test thread. // Called on test thread.
bool ProvidersStarted(); bool ProvidersStarted();
void SendMockLocation(const Geoposition& position);
private: private:
// Called on provider thread. // Called on provider thread.
...@@ -149,6 +159,15 @@ void GeolocationProviderTest::GetProvidersStarted(bool* started) { ...@@ -149,6 +159,15 @@ void GeolocationProviderTest::GetProvidersStarted(bool* started) {
*started = provider_->mock_arbitrator()->providers_started(); *started = provider_->mock_arbitrator()->providers_started();
} }
void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
DCHECK(provider_->IsRunning());
DCHECK(MessageLoop::current() == &message_loop_);
provider_->message_loop()->PostTask(
FROM_HERE,
base::Bind(&GeolocationProvider::OnLocationUpdate,
base::Unretained(provider_.get()),
position));
}
// Regression test for http://crbug.com/59377 // Regression test for http://crbug.com/59377
TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
...@@ -170,6 +189,46 @@ TEST_F(GeolocationProviderTest, StartStop) { ...@@ -170,6 +189,46 @@ TEST_F(GeolocationProviderTest, StartStop) {
EXPECT_TRUE(provider()->IsRunning()); EXPECT_TRUE(provider()->IsRunning());
} }
TEST_F(GeolocationProviderTest, StalePositionNotSent) {
Geoposition first_position;
first_position.latitude = 12;
first_position.longitude = 34;
first_position.accuracy = 56;
first_position.timestamp = base::Time::Now();
AsyncMockGeolocationObserver first_observer;
GeolocationObserverOptions options;
EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
provider()->AddObserver(&first_observer, options);
SendMockLocation(first_position);
MessageLoop::current()->Run();
provider()->RemoveObserver(&first_observer);
Geoposition second_position;
second_position.latitude = 13;
second_position.longitude = 34;
second_position.accuracy = 56;
second_position.timestamp = base::Time::Now();
AsyncMockGeolocationObserver second_observer;
// After adding a second observer, check that no unexpected position update
// is sent.
EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0);
provider()->AddObserver(&second_observer, options);
MessageLoop::current()->RunUntilIdle();
// The second observer should receive the new position now.
EXPECT_CALL(second_observer,
OnLocationUpdate(GeopositionEq(second_position)));
SendMockLocation(second_position);
MessageLoop::current()->Run();
provider()->RemoveObserver(&second_observer);
EXPECT_FALSE(ProvidersStarted());
}
TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
Geoposition position; Geoposition position;
position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment