1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// 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.
#ifndef CHROME_BROWSER_GEOLOCATION_LOCATION_ARBITRATOR_H_
#define CHROME_BROWSER_GEOLOCATION_LOCATION_ARBITRATOR_H_
#include "base/string16.h"
#include "base/time.h"
#include "base/ref_counted.h"
class AccessTokenStore;
class GURL;
class LocationProviderBase;
class URLRequestContextGetter;
struct Geoposition;
// This is the main API to the geolocaiton subsystem. Typically the application
// will hold a single instance of this class, and can register multiple
// observers which will be notified of location updates. Underlying location
// provider(s) will only be enabled whilst there is at least one observer
// registered.
// This class is responsible for handling updates from multiple underlying
// providers and resolving them to a single 'best' location fix at any given
// moment.
class GeolocationArbitrator : public base::RefCounted<GeolocationArbitrator> {
public:
// Number of milliseconds newer a location provider has to be that it's worth
// switching to this location provider on the basis of it being fresher
// (regardles of relative accuracy). Public for tests.
static const int64 kFixStaleTimeoutMilliseconds;
// Defines a function that returns the current time.
typedef base::Time (*GetTimeNow)();
// Allows injection of factory methods for creating the location providers.
// RefCounted for simplicity of writing tests.
class ProviderFactory : public base::RefCounted<ProviderFactory> {
public:
virtual LocationProviderBase* NewNetworkLocationProvider(
AccessTokenStore* access_token_store,
URLRequestContextGetter* context,
const GURL& url,
const string16& access_token) = 0;
virtual LocationProviderBase* NewGpsLocationProvider() = 0;
protected:
friend class base::RefCounted<ProviderFactory>;
virtual ~ProviderFactory();
};
// Creates and returns a new instance of the location arbitrator. Allows
// injection of dependencies, for testing.
static GeolocationArbitrator* Create(
AccessTokenStore* access_token_store,
URLRequestContextGetter* context_getter,
GetTimeNow get_time_now,
ProviderFactory* provider_factory);
// Gets a pointer to the singleton instance of the location arbitrator, which
// is in turn bound to the browser's global context objects. Ownership is NOT
// returned.
static GeolocationArbitrator* GetInstance();
class Delegate {
public:
// This will be called whenever the 'best available' location is updated,
// or when an error is encountered meaning no location data will be
// available in the forseeable future.
virtual void OnLocationUpdate(const Geoposition& position) = 0;
protected:
Delegate() {}
virtual ~Delegate() {}
private:
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
struct UpdateOptions {
UpdateOptions() : use_high_accuracy(false) {}
explicit UpdateOptions(bool high_accuracy)
: use_high_accuracy(high_accuracy) {}
// Given a map<ANYTHING, UpdateOptions> this function will iterate the map
// and collapse all the options found to a single instance that satisfies
// them all.
template <typename MAP>
static UpdateOptions Collapse(const MAP& options_map) {
for (typename MAP::const_iterator it = options_map.begin();
it != options_map.end(); ++it) {
if (it->second.use_high_accuracy)
return UpdateOptions(true);
}
return UpdateOptions(false);
}
bool use_high_accuracy;
};
// Must be called from the same thread as the arbitrator was created on.
// The update options passed are used as a 'hint' for the provider preferences
// for this particular observer, however the delegate could receive callbacks
// for best available locations from any active provider whilst it is
// registered.
// If an existing delegate is added a second time it's options are updated
// but only a single call to RemoveObserver() is required to remove it.
virtual void AddObserver(Delegate* delegate,
const UpdateOptions& update_options) = 0;
// Remove a previously registered observer. No-op if not previously registered
// via AddObserver(). Returns true if the observer was removed.
virtual bool RemoveObserver(Delegate* delegate) = 0;
// Returns the current position estimate, or an uninitialized position
// if none is yet available. Once initialized, this will always match
// the most recent observer notification (via Delegate::OnLocationUpdate()).
virtual Geoposition GetCurrentPosition() = 0;
// Called everytime permission is granted to a page for using geolocation.
// This may either be through explicit user action (e.g. responding to the
// infobar prompt) or inferred from a persisted site permission.
// The arbitrator will inform all providers of this, which may in turn use
// this information to modify their internal policy.
virtual void OnPermissionGranted(const GURL& requesting_frame) = 0;
// Returns true if this arbitrator has received at least one call to
// OnPermissionGranted().
virtual bool HasPermissionBeenGranted() const = 0;
// For testing, a factory function can be set which will be used to create
// a specified test provider. Pass NULL to reset to the default behavior.
// For finer grained control, use class ProviderFactory instead.
// TODO(joth): Move all tests to use ProviderFactory and remove this.
typedef LocationProviderBase* (*LocationProviderFactoryFunction)(void);
static void SetProviderFactoryForTest(
LocationProviderFactoryFunction factory_function);
protected:
friend class base::RefCounted<GeolocationArbitrator>;
GeolocationArbitrator();
// RefCounted object; no not delete directly.
virtual ~GeolocationArbitrator();
private:
DISALLOW_COPY_AND_ASSIGN(GeolocationArbitrator);
};
#endif // CHROME_BROWSER_GEOLOCATION_LOCATION_ARBITRATOR_H_
|