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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
// Copyright 2014 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 CONTENT_BROWSER_GEOFENCING_GEOFENCING_MANAGER_H_
#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/geofencing/geofencing_registration_delegate.h"
#include "content/browser/service_worker/service_worker_context_observer.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
#include "content/common/geofencing_types.h"
#include "content/common/service_worker/service_worker_status_code.h"
template <typename T>
struct DefaultSingletonTraits;
class GURL;
namespace blink {
struct WebCircularGeofencingRegion;
};
namespace content {
class GeofencingService;
class MockGeofencingService;
class ServiceWorkerContextWrapper;
class ServiceWorkerRegistration;
// This is the main API to the geofencing subsystem. There is one instance of
// this class per storage partition.
// This class is responsible for keeping track of which geofences are currently
// registered by websites/workers, persisting this list of registrations and
// registering them with the global |GeofencingService|.
// This class is created on the UI thread, but all its methods should only be
// called from the IO thread.
// TODO(mek): Implement some kind of persistence of registrations.
class CONTENT_EXPORT GeofencingManager
: NON_EXPORTED_BASE(public GeofencingRegistrationDelegate),
NON_EXPORTED_BASE(public ServiceWorkerContextObserver),
public base::RefCountedThreadSafe<GeofencingManager> {
public:
typedef base::Callback<void(GeofencingStatus)> StatusCallback;
explicit GeofencingManager(
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context);
// Init and Shutdown are for use on the UI thread when the storagepartition is
// being setup and torn down.
void Init();
void Shutdown();
// Initiates registration of a new geofence. StatusCallback is called when
// registration has completed or failed (which could possibly be before
// RegisterRegion returns.
// Attempting to register a region with the same ID as an already registered
// (or in progress of being registered) region will fail.
// TODO(mek): Behavior when using an already used ID might need to be revised
// depending on what the actual spec ends up saying about this.
void RegisterRegion(int64 service_worker_registration_id,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback);
// Unregister a region that was previously registered by a call to
// RegisterRegion. Any attempt to unregister a region that has not been
// registered, or for which the registration is still in progress
// (RegisterRegion hasn't called its callback yet) will fail.
// TODO(mek): Maybe better behavior would be to allow unregistering still
// in-progress registrations.
void UnregisterRegion(int64 service_worker_registration_id,
const std::string& region_id,
const StatusCallback& callback);
// Returns all currently registered regions. In case of failure (no geofencing
// provider available for example) return an error status, while leaving
// |regions| untouched.
// This only returns regions for which the callback passed to RegisterRegion
// has been called already (so it doesn't include still in progress
// registrations).
GeofencingStatus GetRegisteredRegions(
int64 service_worker_registration_id,
std::map<std::string, blink::WebCircularGeofencingRegion>* result);
// Enables or disables mock geofencing service.
void SetMockProvider(GeofencingMockState mock_state);
// Set the mock geofencing position.
// TODO(mek): Unify this mock position with the devtools exposed geolocation
// mock position (http://crbug.com/440902).
void SetMockPosition(double latitude, double longitude);
void SetServiceForTesting(GeofencingService* service) {
service_ = service;
}
protected:
friend class base::RefCountedThreadSafe<GeofencingManager>;
~GeofencingManager() override;
private:
// Internal bookkeeping associated with each registered geofence.
struct Registration;
void InitOnIO();
void ShutdownOnIO();
// ServiceWorkerContextObserver implementation.
void OnRegistrationDeleted(int64 service_worker_registration_id,
const GURL& pattern) override;
// GeofencingRegistrationDelegate implementation.
void RegistrationFinished(int64 geofencing_registration_id,
GeofencingStatus status) override;
void RegionEntered(int64 geofencing_registration_id) override;
void RegionExited(int64 geofencing_registration_id) override;
// Looks up a particular geofence registration. Returns nullptr if no
// registration with the given IDs exists.
Registration* FindRegistration(int64 service_worker_registration_id,
const std::string& region_id);
// Looks up a particular geofence registration. Returns nullptr if no
// registration with the given ID exists.
Registration* FindRegistrationById(int64 geofencing_registration_id);
// Registers a new registration, returning a reference to the newly inserted
// object. Assumes no registration with the same IDs currently exists.
Registration& AddRegistration(
int64 service_worker_registration_id,
const GURL& service_worker_origin,
const std::string& region_id,
const blink::WebCircularGeofencingRegion& region,
const StatusCallback& callback,
int64 geofencing_registration_id);
// Clears a registration.
void ClearRegistration(Registration* registration);
// Unregisters and clears all registrations associated with a specific
// service worker.
void CleanUpForServiceWorker(int64 service_worker_registration_id);
// Starts dispatching a particular geofencing |event_type| for the geofence
// registration with the given ID. This first looks up the Service Worker
// Registration the geofence is associated with, and then attempts to deliver
// the event to that service worker.
void DispatchGeofencingEvent(blink::WebGeofencingEventType event_type,
int64 geofencing_registration_id);
// Delivers an event to the specified service worker for the given geofence.
// If the geofence registration id is no longer valid, this method does
// nothing. This assumes the |service_worker_registration| is the service
// worker the geofence registration is associated with.
void DeliverGeofencingEvent(blink::WebGeofencingEventType event_type,
int64 geofencing_registration_id,
ServiceWorkerStatusCode service_worker_status,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration);
// Called when delivery of a geofence event to a service worker has finished
// (or failed to finish).
void DeliverGeofencingEventEnd(const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration,
ServiceWorkerStatusCode service_worker_status);
// Map of all registered regions for a particular service worker registration.
typedef std::map<std::string, Registration> RegionIdRegistrationMap;
// Map of service worker registration id to the regions registered by that
// service worker.
typedef std::map<int64, RegionIdRegistrationMap>
ServiceWorkerRegistrationsMap;
ServiceWorkerRegistrationsMap registrations_;
// Map of all registered regions by geofencing_registration_id.
typedef std::map<int64, RegionIdRegistrationMap::iterator>
RegistrationIdRegistrationMap;
RegistrationIdRegistrationMap registrations_by_id_;
GeofencingService* service_;
scoped_ptr<MockGeofencingService> mock_service_;
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
DISALLOW_COPY_AND_ASSIGN(GeofencingManager);
};
} // namespace content
#endif // CONTENT_BROWSER_GEOFENCING_GEOFENCING_MANAGER_H_
|