What's new? | Help | Directory | Sign in
Google
             
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// Copyright 2008, Google Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// 3. Neither the name of Google Inc. nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// This file declares GearsGeolocation, the main class of the Gears Geolocation
// API. The GearsGeolocation object provides the API methods to JavaScript. It
// uses a set of location providers to gather position information.
//
// This file also declares the Position structure, which is used to represent a
// position fix.

#ifndef GEARS_GEOLOCATION_GEOLOCATION_H__
#define GEARS_GEOLOCATION_GEOLOCATION_H__

#include <map>
#include <vector>
#include "gears/base/common/base_class.h"
#include "gears/base/common/message_service.h"
#ifdef USING_CCTESTS
#include "gears/geolocation/geolocation_test.h"
#endif
#include "gears/geolocation/location_provider.h"
#include "gears/geolocation/timed_callback.h"
#include "third_party/linked_ptr/linked_ptr.h"

static const double kBadLatLng = 200;
// Lowest point on land is at approximately -400 metres.
static const int kBadAltitude = -1000;
static const int kBadAccuracy = -1; // Accuracy must be non-negative.


// Error codes for returning to JavaScript.
const int kGeolocationLocationAcquisitionErrorCode = 2;
const int kGeolocationLocationNotFoundErrorCode = 3;

// The internal representation of an address.
struct Address {
std::string16 street_number; // street number
std::string16 street; // street address
std::string16 premises; // premises, e.g. building name
std::string16 city; // city name
std::string16 county; // county name
std::string16 region; // region, e.g. a state in the US
std::string16 country; // country
std::string16 country_code; // country code (ISO 3166-1)
std::string16 postal_code; // postal code
};

// The internal representation of a position. Some properties use different
// types when passed to JavaScript.
struct Position {
public:
Position()
: latitude(kBadLatLng),
longitude(kBadLatLng),
altitude(kBadAltitude),
accuracy(kBadAccuracy),
altitude_accuracy(kBadAccuracy),
timestamp(-1),
error_code(kint32min) {}
bool IsGoodFix() const {
// A good fix has a valid latitude, longitude, accuracy and timestamp.
return latitude >= -90.0 && latitude <= 90.0 &&
longitude >= -180.0 && longitude <= 180.0 &&
accuracy >= 0.0 &&
timestamp != -1;
}
bool IsInitialized() const {
return IsGoodFix() || error_code != kint32min;
}

// These properties are returned to JavaScript as a Position object.
double latitude; // In degrees
double longitude; // In degrees
double altitude; // In metres
double accuracy; // In metres
double altitude_accuracy; // In metres
int64 timestamp; // Milliseconds since 1st Jan 1970
// Note that the corresponding JavaScript Position property is 'gearsAddress'.
Address address;

// These properties are returned to JavaScript as a PositionError object.
int error_code;
std::string16 error_message; // Human-readable error message
};

// The principal class of the Geolocation API.
class GearsGeolocation
: public ModuleImplBaseClass,
public LocationProviderBase::ListenerInterface,
public MessageObserverInterface,
public TimedCallback::ListenerInterface,
public JsEventHandlerInterface {
public:
#ifdef USING_CCTESTS
// Uses ParseArguments for testing.
friend void TestParseGeolocationOptions(JsCallContext *context,
JsRunnerInterface *js_runner);
// Uses CreateJavaScriptPositionObject and CreateJavaScriptPositionErrorObject
// for testing.
friend void TestGeolocationGetLocationFromResponse(
JsCallContext *context,
JsRunnerInterface *js_runner);
#endif

GearsGeolocation();
virtual ~GearsGeolocation();

// API methods. See the Geolocation API design document at
// http://code.google.com/p/google-gears/wiki/LocationAPI for a more complete
// description of these methods.

// Gets the last, cached, position fix. This method does not cause Gears to
// actively seek a position update.
// IN: nothing
// OUT: object position
void GetLastPosition(JsCallContext *context);

// Instructs Gears to get a new position fix. The supplied callback function
// is called with a valid position as soon as it is available, or with NULL on
// failure.
// IN: function successCallback, optional function errorCallback,
// optional object options
// OUT: nothing
void GetCurrentPosition(JsCallContext *context);

// Instructs Gears to get a new position fix. The supplied callback function
// is called repeatedly with position updates as they become available. The
// return value is a unique ID for this watch which can be used to cancel it.
// IN: function successCallback, optional function errorCallback,
// optional object options
// OUT: int watch_id
void WatchPosition(JsCallContext *context);

// Cancels the position watch specified by the supplied ID.
// IN: int watchId
// OUT: nothing
void ClearWatch(JsCallContext *context);

// Triggers the geolocation-specific permissions dialog.
// IN: string siteName, string imageUrl, string extraMessage
// OUT: boolean permission
void GetPermission(JsCallContext *context);

// Maintains all the data for a position fix.
typedef std::vector<LocationProviderBase*> ProviderVector;
struct FixRequestInfo {
FixRequestInfo() : last_success_callback_time(0) {}
ProviderVector providers;
bool enable_high_accuracy;
bool request_address;
std::string16 address_language;
bool repeats;
// Linked_ptr so we can use FixRequestInfo in STL containers.
linked_ptr<JsRootedCallback> success_callback;
linked_ptr<JsRootedCallback> error_callback;
// The last position sent back to JavaScript. Used by repeating requests
// only.
Position last_position;
// The time at which we last made a success callback to JavaScript, in ms
// since the epoch.
int64 last_success_callback_time;
// The timer used for a pending future success callback in a watch.
linked_ptr<TimedCallback> success_callback_timer;
// The position that will be used used for a pending future success callback
// in a watch.
Position pending_position;
};

private:
// LocationProviderBase::ListenerInterface implementation.
virtual bool LocationUpdateAvailable(LocationProviderBase *provider);

// MessageObserverInterface implementation.
virtual void OnNotify(MessageService *service,
const char16 *topic,
const NotificationData *data);

// TimedCallback::ListenerInterface implementation.
virtual void OnTimeout(TimedCallback *caller, void *user_data);

// JsEventHandlerInterface implementation used to handle the 'JSEVENT_UNLOAD'
// event.
void HandleEvent(JsEventType event_type);

// Internal method used by OnNotify.
void LocationUpdateAvailableImpl(LocationProviderBase *provider);

// Internal method used by GetCurrentPosition and WatchPosition to get a
// position fix.
void GetPositionFix(JsCallContext *context, bool repeats);

// Cancels an ongoing watch.
bool CancelWatch(const int &watch_id);

// In the two following methods, we use an ID to identify the fix request,
// rather than a raw pointer. However, both methods require that the ID is
// valid. See the implementation of LocationUpdateAvailableImpl.

// Internal method used by LocationUpdateAvailable to handle an update for a
// repeating fix request.
void HandleRepeatingRequestUpdate(int id,
const Position &position);

// Internal method used by LocationUpdateAvailable to handle an update for a
// non-repeating fix request.
void HandleSingleRequestUpdate(LocationProviderBase *provider,
int id,
const Position &position);

// Internal method to make the callback to JavaScript once we have a postion
// fix.
bool MakeSuccessCallback(FixRequestInfo *fix_info, const Position &position);
bool MakeErrorCallback(FixRequestInfo *fix_info, const Position &position);

// Parses the JavaScript arguments passed to the GetCurrentPosition and
// WatchPosition methods.
static bool ParseArguments(JsCallContext *context,
bool repeats,
std::vector<std::string16> *urls,
GearsGeolocation::FixRequestInfo *info);
// Parses a JsObject representing the options parameter. The output is a
// vector of URLs and the fix request info. Return value indicates success.
static bool ParseOptions(JsCallContext *context,
const JsObject &options,
std::vector<std::string16> *urls,
GearsGeolocation::FixRequestInfo *info);
// Parses a JsScopedToken representing the gearsLocationProviderUrls field.
// The output is a vector of URLs. Return value indicates success.
static bool ParseLocationProviderUrls(JsCallContext *context,
const JsArray &js_array,
std::vector<std::string16> *urls);

// Converts a Gears position object to a JavaScript object. static for use in
// unit tests.
static bool CreateJavaScriptPositionObject(const Position &position,
bool use_address,
JsRunnerInterface *js_runner,
JsObject *js_object);
static bool CreateJavaScriptPositionErrorObject(const Position &position,
JsObject *js_object);

// Gets the fix request for a given ID. The supplied ID must be valid.
FixRequestInfo *GetFixRequest(int id);

// Takes a pointer to a new fix request and records it in our map. Returns
// false if the maximum number of fix requests has been reached. Otherwise
// return true.
bool RecordNewFixRequest(FixRequestInfo *fix_request);

// Removes a fix request. Cancels any pending requests to the location
// providers it uses. Note that this does not delete the FixRequestInfo
// object.
void RemoveFixRequest(int id);

// Deletes a fix request and decrements our ref count.
void DeleteFixRequest(FixRequestInfo *fix_request);

// Removes a location provider from a fix request.
void RemoveProvider(LocationProviderBase *provider, int id);

// Causes a callback to JavaScript to be made at the specified number of
// milliseconds in the future.
void MakeFutureSuccessCallback(int timeout_milliseconds,
FixRequestInfo *fix_info,
const Position &position);

// TODO(steveblock): Refactor the logic used to maintain the fix request maps
// into a separate class.

// A map from providers to fix request IDs. We use this map when looking up
// the single fix requests in which a provider is involved and to make sure
// that the provider from which a location update is received is still valid
// once the callback has been marshalled. See the comment in the
// implementation of LocationUpdateAvailableImpl for a discussion of how and
// why request IDs are used.
typedef std::vector<int> IdList;
typedef std::map<LocationProviderBase*, IdList> ProviderMap;
ProviderMap providers_;

// Map from fix request ID to fix request.
typedef std::map<int, FixRequestInfo*> FixRequestInfoMap;
FixRequestInfoMap fix_requests_;
int next_single_request_id_; // Always negative
int next_watch_id_; // Always positive

// The current best estimate for our position. This is the position returned
// by GetLastPosition and is shared by all watches.
Position last_position_;

ThreadId java_script_thread_id_;

scoped_ptr<JsEventMonitor> unload_monitor_;

DECL_SINGLE_THREAD
DISALLOW_EVIL_CONSTRUCTORS(GearsGeolocation);
};

#endif // GEARS_GEOLOCATION_GEOLOCATION_H__
Show details Hide details

Change log

r2820 by gears.daemon on Sep 09, 2008   Diff
[Author: nigeltao]

Push JsToken-manipulating functions to be
member methods of JsArray,
JsObject, and JsCallContext.

Also, unify the three JsRootedToken
implementations.

PRESUBMIT=passed
R=mpcomplete
CC=gears-eng@googlegroups.com
...
Go to: 
Project members, sign in to write a code review

Older revisions

r2799 by gears.daemon on Sep 04, 2008   Diff
[Author: steveblock]

Bug fix in Geolocation arbitrator.
Protects against the case where a
provider is deleted but still has
...
r2784 by gears.daemon on Sep 02, 2008   Diff
[Author: steveblock]

Updates Position altitude, accuracy
and altitude_accuracy fields to use
double rather than int internally.
...
r2610 by gears.daemon on Aug 06, 2008   Diff
[Author: steveblock]

Fixes name of Position.gearsAddress
property.

...
All revisions of this file

File info

Size: 13530 bytes, 320 lines