16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/browser/geolocation/geolocation_provider_impl.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/geolocation/mock_location_arbitrator.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/access_token_store.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::MakeMatcher; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Matcher; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::MatcherInterface; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::MatchResultListener; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class LocationProviderForTestArbitrator : public GeolocationProviderImpl { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LocationProviderForTestArbitrator() : mock_arbitrator_(NULL) {} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~LocationProviderForTestArbitrator() {} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only valid for use on the geolocation thread. 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MockLocationArbitrator* mock_arbitrator() const { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mock_arbitrator_; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // GeolocationProviderImpl implementation: 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual LocationArbitrator* CreateArbitrator() OVERRIDE; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MockLocationArbitrator* mock_arbitrator_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)LocationArbitrator* LocationProviderForTestArbitrator::CreateArbitrator() { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(mock_arbitrator_ == NULL); 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) mock_arbitrator_ = new MockLocationArbitrator; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mock_arbitrator_; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class GeolocationObserver { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual ~GeolocationObserver() {} 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual void OnLocationUpdate(const Geoposition& position) = 0; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGeolocationObserver : public GeolocationObserver { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnLocationUpdate, void(const Geoposition& position)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AsyncMockGeolocationObserver : public MockGeolocationObserver { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnLocationUpdate(const Geoposition& position) OVERRIDE { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockGeolocationObserver::OnLocationUpdate(position); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Quit(); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGeolocationCallbackWrapper { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(Callback, void(const Geoposition& position)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeopositionEqMatcher 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public MatcherInterface<const Geoposition&> { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit GeopositionEqMatcher(const Geoposition& expected) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : expected_(expected) {} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool MatchAndExplain(const Geoposition& actual, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchResultListener* listener) const OVERRIDE { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return actual.latitude == expected_.latitude && 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.longitude == expected_.longitude && 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.altitude == expected_.altitude && 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.accuracy == expected_.accuracy && 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.altitude_accuracy == expected_.altitude_accuracy && 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.heading == expected_.heading && 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.speed == expected_.speed && 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.timestamp == expected_.timestamp && 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.error_code == expected_.error_code && 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual.error_message == expected_.error_message; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DescribeTo(::std::ostream* os) const OVERRIDE { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "which matches the expected position"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *os << "which does not match the expected position"; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Geoposition expected_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GeopositionEqMatcher); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Matcher<const Geoposition&> GeopositionEq(const Geoposition& expected) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MakeMatcher(new GeopositionEqMatcher(expected)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeolocationProviderTest : public testing::Test { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GeolocationProviderTest() 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : message_loop_(), 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui_thread_(BrowserThread::UI, &message_loop_), 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_(new LocationProviderForTestArbitrator) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~GeolocationProviderTest() {} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LocationProviderForTestArbitrator* provider() { return provider_.get(); } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called on test thread. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ProvidersStarted(); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SendMockLocation(const Geoposition& position); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called on provider thread. 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetProvidersStarted(bool* started); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop message_loop_; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestBrowserThread ui_thread_; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LocationProviderForTestArbitrator> provider_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GeolocationProviderTest::ProvidersStarted() { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(provider_->IsRunning()); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(base::MessageLoop::current() == &message_loop_); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool started; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_->message_loop_proxy()->PostTaskAndReply( 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GeolocationProviderTest::GetProvidersStarted, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &started), 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::QuitClosure()); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return started; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GeolocationProviderTest::GetProvidersStarted(bool* started) { 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(base::MessageLoop::current() == provider_->message_loop()); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *started = provider_->mock_arbitrator()->providers_started(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GeolocationProviderTest::SendMockLocation(const Geoposition& position) { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(provider_->IsRunning()); 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(base::MessageLoop::current() == &message_loop_); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) provider_->message_loop() 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ->PostTask(FROM_HERE, 163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&GeolocationProviderImpl::OnLocationUpdate, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(provider_.get()), 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position)); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Regression test for http://crbug.com/59377 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) { 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(provider()->user_did_opt_into_location_services_for_testing()); 171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) provider()->UserDidOptIntoLocationServices(); 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(provider()->user_did_opt_into_location_services_for_testing()); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DummyFunction(const Geoposition& position) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GeolocationProviderTest, StartStop) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(provider()->IsRunning()); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GeolocationProviderImpl::LocationUpdateCallback callback = 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&DummyFunction); 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<content::GeolocationProvider::Subscription> subscription = 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider()->AddLocationUpdateCallback(callback, false); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(provider()->IsRunning()); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(ProvidersStarted()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) subscription.reset(); 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(ProvidersStarted()); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(provider()->IsRunning()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(GeolocationProviderTest, StalePositionNotSent) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Geoposition first_position; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_position.latitude = 12; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_position.longitude = 34; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_position.accuracy = 56; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_position.timestamp = base::Time::Now(); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsyncMockGeolocationObserver first_observer; 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GeolocationProviderImpl::LocationUpdateCallback first_callback = base::Bind( 202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) &MockGeolocationObserver::OnLocationUpdate, 203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(&first_observer)); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position))); 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<content::GeolocationProvider::Subscription> subscription = 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider()->AddLocationUpdateCallback(first_callback, false); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendMockLocation(first_position); 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) subscription.reset(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Geoposition second_position; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) second_position.latitude = 13; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) second_position.longitude = 34; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) second_position.accuracy = 56; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) second_position.timestamp = base::Time::Now(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsyncMockGeolocationObserver second_observer; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // After adding a second observer, check that no unexpected position update 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is sent. 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0); 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GeolocationProviderImpl::LocationUpdateCallback second_callback = base::Bind( 224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) &MockGeolocationObserver::OnLocationUpdate, 225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(&second_observer)); 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<content::GeolocationProvider::Subscription> subscription2 = 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider()->AddLocationUpdateCallback(second_callback, false); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The second observer should receive the new position now. 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(second_observer, 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnLocationUpdate(GeopositionEq(second_position))); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendMockLocation(second_position); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) subscription2.reset(); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(ProvidersStarted()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GeolocationProviderTest, OverrideLocationForTesting) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Geoposition position; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider()->OverrideLocationForTesting(position); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adding an observer when the location is overridden should synchronously 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update the observer with our overridden position. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockGeolocationObserver mock_observer; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(mock_observer, OnLocationUpdate(GeopositionEq(position))); 248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GeolocationProviderImpl::LocationUpdateCallback callback = base::Bind( 249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) &MockGeolocationObserver::OnLocationUpdate, 250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(&mock_observer)); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<content::GeolocationProvider::Subscription> subscription = 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider()->AddLocationUpdateCallback(callback, false); 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) subscription.reset(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the providers to be stopped now that all clients are gone. 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(ProvidersStarted()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 259