Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/geolocation/nsGeoPosition.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsGeoPosition.h"
8
9
#include "mozilla/FloatingPoint.h"
10
#include "mozilla/dom/PositionBinding.h"
11
#include "mozilla/dom/CoordinatesBinding.h"
12
13
using mozilla::IsNaN;
14
15
// NaN() is a more convenient function name.
16
inline
17
double NaN()
18
0
{
19
0
  return mozilla::UnspecifiedNaN<double>();
20
0
}
21
22
#ifdef DEBUG
23
static
24
bool EqualOrNaN(double a, double b)
25
{
26
  return (a == b) || (IsNaN(a) && IsNaN(b));
27
}
28
#endif
29
30
////////////////////////////////////////////////////
31
// nsGeoPositionCoords
32
////////////////////////////////////////////////////
33
nsGeoPositionCoords::nsGeoPositionCoords(double aLat, double aLong,
34
                                         double aAlt, double aHError,
35
                                         double aVError, double aHeading,
36
                                         double aSpeed)
37
  : mLat(aLat)
38
  , mLong(aLong)
39
  , mAlt(aAlt)
40
  , mHError((aHError >= 0) ? aHError : 0)
41
    // altitudeAccuracy without an altitude doesn't make any sense.
42
  , mVError((aVError >= 0 && !IsNaN(aAlt)) ? aVError : NaN())
43
    // If the hosting device is stationary (i.e. the value of the speed attribute
44
    // is 0), then the value of the heading attribute must be NaN (or null).
45
  , mHeading((aHeading >= 0 && aHeading < 360 && aSpeed > 0)
46
             ? aHeading : NaN())
47
  , mSpeed(aSpeed >= 0 ? aSpeed : NaN())
48
0
{
49
0
  // Sanity check the location provider's results in debug builds. If the
50
0
  // location provider is returning bogus results, we'd like to know, but
51
0
  // we prefer to return some position data to JavaScript over a
52
0
  // POSITION_UNAVAILABLE error.
53
0
  MOZ_ASSERT(aLat >= -90 && aLat <= 90);
54
0
  MOZ_ASSERT(aLong >= -180 && aLong <= 180);
55
0
  MOZ_ASSERT(!(aLat == 0 && aLong == 0)); // valid but probably a bug
56
0
57
0
  MOZ_ASSERT(EqualOrNaN(mAlt, aAlt));
58
0
  MOZ_ASSERT(mHError == aHError);
59
0
  MOZ_ASSERT(EqualOrNaN(mVError, aVError));
60
0
  MOZ_ASSERT(EqualOrNaN(mHeading, aHeading));
61
0
  MOZ_ASSERT(EqualOrNaN(mSpeed, aSpeed));
62
0
}
63
64
nsGeoPositionCoords::~nsGeoPositionCoords()
65
0
{
66
0
}
67
68
0
NS_INTERFACE_MAP_BEGIN(nsGeoPositionCoords)
69
0
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPositionCoords)
70
0
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCoords)
71
0
NS_INTERFACE_MAP_END
72
73
NS_IMPL_ADDREF(nsGeoPositionCoords)
74
NS_IMPL_RELEASE(nsGeoPositionCoords)
75
76
NS_IMETHODIMP
77
nsGeoPositionCoords::GetLatitude(double *aLatitude)
78
0
{
79
0
  *aLatitude = mLat;
80
0
  return NS_OK;
81
0
}
82
83
NS_IMETHODIMP
84
nsGeoPositionCoords::GetLongitude(double *aLongitude)
85
0
{
86
0
  *aLongitude = mLong;
87
0
  return NS_OK;
88
0
}
89
90
NS_IMETHODIMP
91
nsGeoPositionCoords::GetAltitude(double *aAltitude)
92
0
{
93
0
  *aAltitude = mAlt;
94
0
  return NS_OK;
95
0
}
96
97
NS_IMETHODIMP
98
nsGeoPositionCoords::GetAccuracy(double *aAccuracy)
99
0
{
100
0
  *aAccuracy = mHError;
101
0
  return NS_OK;
102
0
}
103
104
NS_IMETHODIMP
105
nsGeoPositionCoords::GetAltitudeAccuracy(double *aAltitudeAccuracy)
106
0
{
107
0
  *aAltitudeAccuracy = mVError;
108
0
  return NS_OK;
109
0
}
110
111
NS_IMETHODIMP
112
nsGeoPositionCoords::GetHeading(double *aHeading)
113
0
{
114
0
  *aHeading = mHeading;
115
0
  return NS_OK;
116
0
}
117
118
NS_IMETHODIMP
119
nsGeoPositionCoords::GetSpeed(double *aSpeed)
120
0
{
121
0
  *aSpeed = mSpeed;
122
0
  return NS_OK;
123
0
}
124
125
////////////////////////////////////////////////////
126
// nsGeoPosition
127
////////////////////////////////////////////////////
128
129
nsGeoPosition::nsGeoPosition(double aLat, double aLong,
130
                             double aAlt, double aHError,
131
                             double aVError, double aHeading,
132
                             double aSpeed, DOMTimeStamp aTimestamp) :
133
    mTimestamp(aTimestamp)
134
0
{
135
0
    mCoords = new nsGeoPositionCoords(aLat, aLong,
136
0
                                      aAlt, aHError,
137
0
                                      aVError, aHeading,
138
0
                                      aSpeed);
139
0
}
140
141
nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
142
                             DOMTimeStamp aTimestamp) :
143
  mTimestamp(aTimestamp),
144
  mCoords(aCoords)
145
0
{
146
0
}
147
148
nsGeoPosition::~nsGeoPosition()
149
0
{
150
0
}
151
152
0
NS_INTERFACE_MAP_BEGIN(nsGeoPosition)
153
0
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPosition)
154
0
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPosition)
155
0
NS_INTERFACE_MAP_END
156
157
NS_IMPL_ADDREF(nsGeoPosition)
158
NS_IMPL_RELEASE(nsGeoPosition)
159
160
NS_IMETHODIMP
161
nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp)
162
0
{
163
0
  *aTimestamp = mTimestamp;
164
0
  return NS_OK;
165
0
}
166
167
NS_IMETHODIMP
168
nsGeoPosition::GetCoords(nsIDOMGeoPositionCoords * *aCoords)
169
0
{
170
0
  NS_IF_ADDREF(*aCoords = mCoords);
171
0
  return NS_OK;
172
0
}
173
174
namespace mozilla {
175
namespace dom {
176
177
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Position, mParent, mCoordinates)
178
NS_IMPL_CYCLE_COLLECTING_ADDREF(Position)
179
NS_IMPL_CYCLE_COLLECTING_RELEASE(Position)
180
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Position)
181
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
182
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
183
0
NS_INTERFACE_MAP_END
184
185
Position::Position(nsISupports* aParent, nsIDOMGeoPosition* aGeoPosition)
186
  : mParent(aParent)
187
  , mGeoPosition(aGeoPosition)
188
0
{
189
0
}
190
191
Position::~Position()
192
0
{
193
0
}
194
195
nsISupports*
196
Position::GetParentObject() const
197
0
{
198
0
  return mParent;
199
0
}
200
201
JSObject*
202
Position::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
203
0
{
204
0
  return Position_Binding::Wrap(aCx, this, aGivenProto);
205
0
}
206
207
Coordinates*
208
Position::Coords()
209
0
{
210
0
  if (!mCoordinates) {
211
0
    nsCOMPtr<nsIDOMGeoPositionCoords> coords;
212
0
    mGeoPosition->GetCoords(getter_AddRefs(coords));
213
0
    MOZ_ASSERT(coords, "coords should not be null");
214
0
215
0
    mCoordinates = new Coordinates(this, coords);
216
0
  }
217
0
218
0
  return mCoordinates;
219
0
}
220
221
uint64_t
222
Position::Timestamp() const
223
0
{
224
0
  uint64_t rv;
225
0
226
0
  mGeoPosition->GetTimestamp(&rv);
227
0
  return rv;
228
0
}
229
230
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Coordinates, mPosition)
231
NS_IMPL_CYCLE_COLLECTING_ADDREF(Coordinates)
232
NS_IMPL_CYCLE_COLLECTING_RELEASE(Coordinates)
233
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Coordinates)
234
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
235
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
236
0
NS_INTERFACE_MAP_END
237
238
Coordinates::Coordinates(Position* aPosition, nsIDOMGeoPositionCoords* aCoords)
239
  : mPosition(aPosition)
240
  , mCoords(aCoords)
241
0
{
242
0
}
243
244
Coordinates::~Coordinates()
245
0
{
246
0
}
247
248
Position*
249
Coordinates::GetParentObject() const
250
0
{
251
0
  return mPosition;
252
0
}
253
254
JSObject*
255
Coordinates::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
256
0
{
257
0
  return Coordinates_Binding::Wrap(aCx, this, aGivenProto);
258
0
}
259
260
#define GENERATE_COORDS_WRAPPED_GETTER(name) \
261
double                                       \
262
0
Coordinates::name() const                    \
263
0
{                                            \
264
0
  double rv;                                 \
265
0
  mCoords->Get##name(&rv);                   \
266
0
  return rv;                                 \
267
0
}
Unexecuted instantiation: mozilla::dom::Coordinates::Latitude() const
Unexecuted instantiation: mozilla::dom::Coordinates::Longitude() const
Unexecuted instantiation: mozilla::dom::Coordinates::Accuracy() const
268
269
#define GENERATE_COORDS_WRAPPED_GETTER_NULLABLE(name) \
270
Nullable<double>                                      \
271
0
Coordinates::Get##name() const                        \
272
0
{                                                     \
273
0
  double value;                                       \
274
0
  mCoords->Get##name(&value);                         \
275
0
  Nullable<double> rv;                                \
276
0
  if (!IsNaN(value)) {                                \
277
0
    rv.SetValue(value);                               \
278
0
  }                                                   \
279
0
  return rv;                                          \
280
0
}
Unexecuted instantiation: mozilla::dom::Coordinates::GetAltitude() const
Unexecuted instantiation: mozilla::dom::Coordinates::GetAltitudeAccuracy() const
Unexecuted instantiation: mozilla::dom::Coordinates::GetHeading() const
Unexecuted instantiation: mozilla::dom::Coordinates::GetSpeed() const
281
282
GENERATE_COORDS_WRAPPED_GETTER(Latitude)
283
GENERATE_COORDS_WRAPPED_GETTER(Longitude)
284
GENERATE_COORDS_WRAPPED_GETTER_NULLABLE(Altitude)
285
GENERATE_COORDS_WRAPPED_GETTER(Accuracy)
286
GENERATE_COORDS_WRAPPED_GETTER_NULLABLE(AltitudeAccuracy)
287
GENERATE_COORDS_WRAPPED_GETTER_NULLABLE(Heading)
288
GENERATE_COORDS_WRAPPED_GETTER_NULLABLE(Speed)
289
290
#undef GENERATE_COORDS_WRAPPED_GETTER
291
#undef GENERATE_COORDS_WRAPPED_GETTER_NULLABLE
292
293
} // namespace dom
294
} // namespace mozilla