1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This file implements a mock location provider and the factory functions for
6 // various ways of creating it.
8 #include "content/browser/geolocation/mock_location_provider.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/compiler_specific.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/thread_task_runner_handle.h"
19 MockLocationProvider
* MockLocationProvider::instance_
= NULL
;
21 MockLocationProvider::MockLocationProvider(MockLocationProvider
** self_ref
)
23 is_permission_granted_(false),
25 provider_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
27 CHECK(*self_ref_
== NULL
);
31 MockLocationProvider::~MockLocationProvider() {
32 CHECK(*self_ref_
== this);
36 void MockLocationProvider::HandlePositionChanged(const Geoposition
& position
) {
37 if (provider_task_runner_
->BelongsToCurrentThread()) {
38 // The location arbitrator unit tests rely on this method running
41 NotifyCallback(position_
);
43 provider_task_runner_
->PostTask(
44 FROM_HERE
, base::Bind(&MockLocationProvider::HandlePositionChanged
,
45 base::Unretained(this), position
));
49 bool MockLocationProvider::StartProvider(bool high_accuracy
) {
50 state_
= high_accuracy
? HIGH_ACCURACY
: LOW_ACCURACY
;
54 void MockLocationProvider::StopProvider() {
58 void MockLocationProvider::GetPosition(Geoposition
* position
) {
59 *position
= position_
;
62 void MockLocationProvider::OnPermissionGranted() {
63 is_permission_granted_
= true;
66 // Mock location provider that automatically calls back its client at most
67 // once, when StartProvider or OnPermissionGranted is called. Use
68 // |requires_permission_to_start| to select which event triggers the callback.
69 class AutoMockLocationProvider
: public MockLocationProvider
{
71 AutoMockLocationProvider(bool has_valid_location
,
72 bool requires_permission_to_start
)
73 : MockLocationProvider(&instance_
),
75 requires_permission_to_start_(requires_permission_to_start
),
76 listeners_updated_(false) {
77 if (has_valid_location
) {
78 position_
.accuracy
= 3;
79 position_
.latitude
= 4.3;
80 position_
.longitude
= -7.8;
81 // Webkit compares the timestamp to wall clock time, so we need it to be
83 position_
.timestamp
= base::Time::Now();
85 position_
.error_code
= Geoposition::ERROR_CODE_POSITION_UNAVAILABLE
;
88 bool StartProvider(bool high_accuracy
) override
{
89 MockLocationProvider::StartProvider(high_accuracy
);
90 if (!requires_permission_to_start_
) {
91 UpdateListenersIfNeeded();
96 void OnPermissionGranted() override
{
97 MockLocationProvider::OnPermissionGranted();
98 if (requires_permission_to_start_
) {
99 UpdateListenersIfNeeded();
103 void UpdateListenersIfNeeded() {
104 if (!listeners_updated_
) {
105 listeners_updated_
= true;
106 base::ThreadTaskRunnerHandle::Get()->PostTask(
107 FROM_HERE
, base::Bind(&MockLocationProvider::HandlePositionChanged
,
108 weak_factory_
.GetWeakPtr(), position_
));
112 base::WeakPtrFactory
<MockLocationProvider
> weak_factory_
;
113 const bool requires_permission_to_start_
;
114 bool listeners_updated_
;
117 LocationProvider
* NewMockLocationProvider() {
118 return new MockLocationProvider(&MockLocationProvider::instance_
);
121 LocationProvider
* NewAutoSuccessMockLocationProvider() {
122 return new AutoMockLocationProvider(true, false);
125 LocationProvider
* NewAutoFailMockLocationProvider() {
126 return new AutoMockLocationProvider(false, false);
129 LocationProvider
* NewAutoSuccessMockNetworkLocationProvider() {
130 return new AutoMockLocationProvider(true, true);
133 } // namespace content