diff options
author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-25 21:47:56 +0000 |
---|---|---|
committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-25 21:47:56 +0000 |
commit | 02a5fe29729b8230764a17651ac646f96d680b74 (patch) | |
tree | 039157bd1ce8d9a1e51e33edb37ab399f591a4ff /content/browser/geolocation | |
parent | b9f22d1e6fb76de05b9bb8a361bae8c7a58ed656 (diff) | |
download | chromium_src-02a5fe29729b8230764a17651ac646f96d680b74.zip chromium_src-02a5fe29729b8230764a17651ac646f96d680b74.tar.gz chromium_src-02a5fe29729b8230764a17651ac646f96d680b74.tar.bz2 |
Geolocation support for chromedriver, browser-side only.
BUG=chromedriver:14
TEST=none
Review URL: http://codereview.chromium.org/10070012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133988 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/geolocation')
4 files changed, 104 insertions, 0 deletions
diff --git a/content/browser/geolocation/geolocation.cc b/content/browser/geolocation/geolocation.cc new file mode 100644 index 0000000..789d9a3 --- /dev/null +++ b/content/browser/geolocation/geolocation.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/geolocation.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop_proxy.h" +#include "content/browser/geolocation/geolocation_provider.h" +#include "content/common/geoposition.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +namespace { + +void OverrideLocationForTestingOnIOThread( + double latitude, + double longitude, + double altitude, + const base::Closure& completion_callback, + scoped_refptr<base::MessageLoopProxy> callback_loop) { + Geoposition position; + position.latitude = latitude; + position.longitude = longitude; + position.altitude = altitude; + position.accuracy = 0; + position.timestamp = base::Time::Now(); + GeolocationProvider::GetInstance()->OverrideLocationForTesting(position); + callback_loop->PostTask(FROM_HERE, completion_callback); +} + +} // namespace + +void OverrideLocationForTesting( + double latitude, + double longitude, + double altitude, + const base::Closure& completion_callback) { + base::Closure closure = base::Bind( + &OverrideLocationForTestingOnIOThread, + latitude, longitude, altitude, completion_callback, + base::MessageLoopProxy::current()); + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, closure); + } else { + closure.Run(); + } +} + +} // namespace content diff --git a/content/browser/geolocation/geolocation_provider.cc b/content/browser/geolocation/geolocation_provider.cc index e090ac9..b491826 100644 --- a/content/browser/geolocation/geolocation_provider.cc +++ b/content/browser/geolocation/geolocation_provider.cc @@ -18,6 +18,7 @@ GeolocationProvider::GeolocationProvider() : base::Thread("Geolocation"), client_loop_(base::MessageLoopProxy::current()), is_permission_granted_(false), + ignore_location_updates_(false), arbitrator_(NULL) { } @@ -127,12 +128,23 @@ void GeolocationProvider::CleanUp() { void GeolocationProvider::OnLocationUpdate(const Geoposition& position) { DCHECK(OnGeolocationThread()); + // Will be true only in testing. + if (ignore_location_updates_) + return; client_loop_->PostTask( FROM_HERE, base::Bind(&GeolocationProvider::NotifyObservers, base::Unretained(this), position)); } +void GeolocationProvider::OverrideLocationForTesting( + const Geoposition& position) { + DCHECK(OnClientThread()); + position_ = position; + ignore_location_updates_ = true; + NotifyObservers(position); +} + bool GeolocationProvider::HasPermissionBeenGranted() const { DCHECK(OnClientThread()); return is_permission_granted_; diff --git a/content/browser/geolocation/geolocation_provider.h b/content/browser/geolocation/geolocation_provider.h index a45a365..f816880 100644 --- a/content/browser/geolocation/geolocation_provider.h +++ b/content/browser/geolocation/geolocation_provider.h @@ -48,6 +48,11 @@ class CONTENT_EXPORT GeolocationProvider // GeolocationObserver virtual void OnLocationUpdate(const Geoposition& position) OVERRIDE; + // Overrides the location for automation/testing. Updates any current + // observers with the overriden position. Any further updates from location + // providers will be ignored. + void OverrideLocationForTesting(const Geoposition& override_position); + // Gets a pointer to the singleton instance of the location relayer, which // is in turn bound to the browser's global context objects. Ownership is NOT // returned. @@ -91,6 +96,8 @@ class CONTENT_EXPORT GeolocationProvider ObserverMap observers_; bool is_permission_granted_; Geoposition position_; + // True only in testing, where we want to use a custom position. + bool ignore_location_updates_; // Only to be used on the geolocation thread. GeolocationArbitrator* arbitrator_; diff --git a/content/browser/geolocation/geolocation_provider_unittest.cc b/content/browser/geolocation/geolocation_provider_unittest.cc index 1b131e9..b99de63 100644 --- a/content/browser/geolocation/geolocation_provider_unittest.cc +++ b/content/browser/geolocation/geolocation_provider_unittest.cc @@ -71,6 +71,12 @@ class NullGeolocationObserver : public GeolocationObserver { virtual void OnLocationUpdate(const Geoposition& position) {} }; +class MockGeolocationObserver : public GeolocationObserver { + public: + // GeolocationObserver + MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); +}; + class StartStopMockLocationProvider : public MockLocationProvider { public: explicit StartStopMockLocationProvider(MessageLoop* test_loop) @@ -179,4 +185,29 @@ TEST_F(GeolocationProviderTest, StartStop) { GeolocationArbitrator::SetDependencyFactoryForTest(NULL); } +TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { + scoped_refptr<FakeAccessTokenStore> fake_access_token_store = + new FakeAccessTokenStore; + scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory = + new MockDependencyFactory(&message_loop_, fake_access_token_store.get()); + MockGeolocationObserver mock_observer; + EXPECT_CALL(*(fake_access_token_store.get()), LoadAccessTokens(_)); + + GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get()); + + Geoposition override_position; + override_position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + provider_->OverrideLocationForTesting(override_position); + // Adding an observer when the location is overriden should synchronously + // update the observer with our overriden position. + EXPECT_CALL(mock_observer, OnLocationUpdate( + testing::Field( + &Geoposition::error_code, + testing::Eq(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE)))); + provider_->AddObserver(&mock_observer, GeolocationObserverOptions()); + provider_->RemoveObserver(&mock_observer); + + GeolocationArbitrator::SetDependencyFactoryForTest(NULL); +} + } // namespace |