// Copyright (c) 2010 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 "chrome/browser/geolocation/geolocation_provider.h" #include "base/singleton.h" #include "chrome/browser/geolocation/arbitrator_dependency_factories_for_test.h" #include "chrome/browser/geolocation/fake_access_token_store.h" #include "chrome/browser/geolocation/location_arbitrator.h" #include "chrome/browser/geolocation/mock_location_provider.h" #include "testing/gtest/include/gtest/gtest.h" namespace { class GeolocationProviderTest : public testing::Test { protected: GeolocationProviderTest() : provider_(new GeolocationProvider), dependency_factory_( new GeolocationArbitratorDependencyFactoryWithLocationProvider( &NewAutoSuccessMockNetworkLocationProvider)) { } ~GeolocationProviderTest() { DefaultSingletonTraits<GeolocationProvider>::Delete(provider_); } // testing::Test virtual void SetUp() { GeolocationArbitrator::SetDependencyFactoryForTest( dependency_factory_.get()); } // testing::Test virtual void TearDown() { provider_->Stop(); GeolocationArbitrator::SetDependencyFactoryForTest(NULL); } // Message loop for main thread, as provider depends on it existing. MessageLoop message_loop_; // Object under tests. Owned, but not a scoped_ptr due to specialized // destruction protocol. GeolocationProvider* provider_; scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory_; }; // Regression test for http://crbug.com/59377 TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { EXPECT_FALSE(provider_->HasPermissionBeenGranted()); provider_->OnPermissionGranted(GURL("http://example.com")); EXPECT_TRUE(provider_->HasPermissionBeenGranted()); } class NullGeolocationObserver : public GeolocationObserver { public: // GeolocationObserver virtual void OnLocationUpdate(const Geoposition& position) {} }; class StartStopMockLocationProvider : public MockLocationProvider { public: explicit StartStopMockLocationProvider(MessageLoop* test_loop) : MockLocationProvider(&instance_), test_loop_(test_loop) { } virtual bool StartProvider(bool high_accuracy) { bool result = MockLocationProvider::StartProvider(high_accuracy); test_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask); return result; } virtual void StopProvider() { MockLocationProvider::StopProvider(); test_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask); } private: MessageLoop* test_loop_; }; class MockDependencyFactory : public GeolocationArbitratorDependencyFactory { public: MockDependencyFactory(MessageLoop* test_loop_, AccessTokenStore* access_token_store) : test_loop_(test_loop_), access_token_store_(access_token_store) { } virtual URLRequestContextGetter* GetContextGetter() { return NULL; } virtual GeolocationArbitrator::GetTimeNow GetTimeFunction() { return base::Time::Now; } virtual AccessTokenStore* NewAccessTokenStore() { return access_token_store_.get(); } virtual LocationProviderBase* NewNetworkLocationProvider( AccessTokenStore* access_token_store, URLRequestContextGetter* context, const GURL& url, const string16& access_token) { return new StartStopMockLocationProvider(test_loop_); } virtual LocationProviderBase* NewSystemLocationProvider() { return NULL; } private: MessageLoop* test_loop_; scoped_refptr<AccessTokenStore> access_token_store_; }; TEST_F(GeolocationProviderTest, StartStop) { scoped_refptr<FakeAccessTokenStore> fake_access_token_store = new FakeAccessTokenStore; scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory = new MockDependencyFactory(&message_loop_, fake_access_token_store.get()); GeolocationArbitrator::SetDependencyFactoryForTest(dependency_factory.get()); EXPECT_FALSE(provider_->IsRunning()); NullGeolocationObserver null_observer; GeolocationObserverOptions options; provider_->AddObserver(&null_observer, options); // The GeolocationArbitrator won't start the providers until it has // finished loading access tokens. fake_access_token_store->NotifyDelegateTokensLoaded(); EXPECT_TRUE(provider_->IsRunning()); message_loop_.Run(); EXPECT_EQ(MockLocationProvider::instance_->state_, MockLocationProvider::LOW_ACCURACY); provider_->RemoveObserver(&null_observer); message_loop_.Run(); EXPECT_EQ(MockLocationProvider::instance_->state_, MockLocationProvider::STOPPED); EXPECT_TRUE(provider_->IsRunning()); GeolocationArbitrator::SetDependencyFactoryForTest(NULL); } } // namespace