15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)// This file implements a mock location provider and the factory functions for 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// various ways of creating it. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/geolocation/mock_location_provider.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockLocationProvider* MockLocationProvider::instance_ = NULL; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockLocationProvider::MockLocationProvider(MockLocationProvider** self_ref) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : state_(STOPPED), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_permission_granted_(false), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self_ref_(self_ref), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider_loop_(base::MessageLoopProxy::current()) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(self_ref_); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(*self_ref_ == NULL); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *self_ref_ = this; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockLocationProvider::~MockLocationProvider() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(*self_ref_ == this); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *self_ref_ = NULL; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockLocationProvider::HandlePositionChanged(const Geoposition& position) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_loop_->BelongsToCurrentThread()) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The location arbitrator unit tests rely on this method running 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ = position; 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NotifyCallback(position_); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider_loop_->PostTask( 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MockLocationProvider::HandlePositionChanged, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), position)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockLocationProvider::StartProvider(bool high_accuracy) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = high_accuracy ? HIGH_ACCURACY : LOW_ACCURACY; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockLocationProvider::StopProvider() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = STOPPED; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockLocationProvider::GetPosition(Geoposition* position) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *position = position_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockLocationProvider::OnPermissionGranted() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_permission_granted_ = true; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mock location provider that automatically calls back its client at most 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once, when StartProvider or OnPermissionGranted is called. Use 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |requires_permission_to_start| to select which event triggers the callback. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutoMockLocationProvider : public MockLocationProvider { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoMockLocationProvider(bool has_valid_location, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool requires_permission_to_start) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MockLocationProvider(&instance_), 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requires_permission_to_start_(requires_permission_to_start), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_updated_(false) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_valid_location) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_.accuracy = 3; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_.latitude = 4.3; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_.longitude = -7.8; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Webkit compares the timestamp to wall clock time, so we need it to be 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contemporary. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_.timestamp = base::Time::Now(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool StartProvider(bool high_accuracy) OVERRIDE { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockLocationProvider::StartProvider(high_accuracy); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!requires_permission_to_start_) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateListenersIfNeeded(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnPermissionGranted() OVERRIDE { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockLocationProvider::OnPermissionGranted(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (requires_permission_to_start_) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateListenersIfNeeded(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateListenersIfNeeded() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners_updated_) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_updated_ = true; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MockLocationProvider::HandlePositionChanged, 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_.GetWeakPtr(), 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position_)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<MockLocationProvider> weak_factory_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool requires_permission_to_start_; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool listeners_updated_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)LocationProvider* NewMockLocationProvider() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new MockLocationProvider(&MockLocationProvider::instance_); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)LocationProvider* NewAutoSuccessMockLocationProvider() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new AutoMockLocationProvider(true, false); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)LocationProvider* NewAutoFailMockLocationProvider() { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new AutoMockLocationProvider(false, false); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)LocationProvider* NewAutoSuccessMockNetworkLocationProvider() { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new AutoMockLocationProvider(true, true); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 137