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/logging.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/message_loop/message_loop_proxy.h"
19 MockLocationProvider
* MockLocationProvider::instance_
= NULL
;
21 MockLocationProvider::MockLocationProvider(MockLocationProvider
** self_ref
)
23 is_permission_granted_(false),
25 provider_loop_(base::MessageLoopProxy::current()) {
27 CHECK(*self_ref_
== NULL
);
31 MockLocationProvider::~MockLocationProvider() {
32 CHECK(*self_ref_
== this);
36 void MockLocationProvider::HandlePositionChanged(const Geoposition
& position
) {
37 if (provider_loop_
->BelongsToCurrentThread()) {
38 // The location arbitrator unit tests rely on this method running
41 NotifyCallback(position_
);
43 provider_loop_
->PostTask(
45 base::Bind(&MockLocationProvider::HandlePositionChanged
,
46 base::Unretained(this), position
));
50 bool MockLocationProvider::StartProvider(bool high_accuracy
) {
51 state_
= high_accuracy
? HIGH_ACCURACY
: LOW_ACCURACY
;
55 void MockLocationProvider::StopProvider() {
59 void MockLocationProvider::GetPosition(Geoposition
* position
) {
60 *position
= position_
;
63 void MockLocationProvider::OnPermissionGranted() {
64 is_permission_granted_
= true;
67 // Mock location provider that automatically calls back its client at most
68 // once, when StartProvider or OnPermissionGranted is called. Use
69 // |requires_permission_to_start| to select which event triggers the callback.
70 class AutoMockLocationProvider
: public MockLocationProvider
{
72 AutoMockLocationProvider(bool has_valid_location
,
73 bool requires_permission_to_start
)
74 : MockLocationProvider(&instance_
),
76 requires_permission_to_start_(requires_permission_to_start
),
77 listeners_updated_(false) {
78 if (has_valid_location
) {
79 position_
.accuracy
= 3;
80 position_
.latitude
= 4.3;
81 position_
.longitude
= -7.8;
82 // Webkit compares the timestamp to wall clock time, so we need it to be
84 position_
.timestamp
= base::Time::Now();
86 position_
.error_code
= Geoposition::ERROR_CODE_POSITION_UNAVAILABLE
;
89 bool StartProvider(bool high_accuracy
) override
{
90 MockLocationProvider::StartProvider(high_accuracy
);
91 if (!requires_permission_to_start_
) {
92 UpdateListenersIfNeeded();
97 void OnPermissionGranted() override
{
98 MockLocationProvider::OnPermissionGranted();
99 if (requires_permission_to_start_
) {
100 UpdateListenersIfNeeded();
104 void UpdateListenersIfNeeded() {
105 if (!listeners_updated_
) {
106 listeners_updated_
= true;
107 base::MessageLoop::current()->PostTask(
109 base::Bind(&MockLocationProvider::HandlePositionChanged
,
110 weak_factory_
.GetWeakPtr(),
115 base::WeakPtrFactory
<MockLocationProvider
> weak_factory_
;
116 const bool requires_permission_to_start_
;
117 bool listeners_updated_
;
120 LocationProvider
* NewMockLocationProvider() {
121 return new MockLocationProvider(&MockLocationProvider::instance_
);
124 LocationProvider
* NewAutoSuccessMockLocationProvider() {
125 return new AutoMockLocationProvider(true, false);
128 LocationProvider
* NewAutoFailMockLocationProvider() {
129 return new AutoMockLocationProvider(false, false);
132 LocationProvider
* NewAutoSuccessMockNetworkLocationProvider() {
133 return new AutoMockLocationProvider(true, true);
136 } // namespace content