Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/geolocation/nsGeolocation.h
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
#ifndef nsGeoLocation_h
8
#define nsGeoLocation_h
9
10
// Microsoft's API Name hackery sucks
11
#undef CreateEvent
12
13
#include "mozilla/StaticPtr.h"
14
#include "nsCOMPtr.h"
15
#include "nsTArray.h"
16
#include "nsITimer.h"
17
#include "nsIObserver.h"
18
#include "nsWrapperCache.h"
19
20
#include "nsWeakPtr.h"
21
#include "nsCycleCollectionParticipant.h"
22
23
#include "nsGeoPosition.h"
24
#include "nsIDOMGeoPosition.h"
25
#include "nsIDOMGeoPositionCallback.h"
26
#include "nsIDOMGeoPositionErrorCallback.h"
27
#include "mozilla/dom/BindingDeclarations.h"
28
#include "mozilla/dom/GeolocationBinding.h"
29
#include "mozilla/dom/CallbackObject.h"
30
31
#include "nsIGeolocationProvider.h"
32
#include "nsIContentPermissionPrompt.h"
33
#include "mozilla/Attributes.h"
34
35
class nsGeolocationService;
36
class nsGeolocationRequest;
37
38
namespace mozilla {
39
namespace dom {
40
class Geolocation;
41
typedef CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback> GeoPositionCallback;
42
typedef CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallback> GeoPositionErrorCallback;
43
} // namespace dom
44
} // namespace mozilla
45
46
struct CachedPositionAndAccuracy {
47
  nsCOMPtr<nsIDOMGeoPosition> position;
48
  bool isHighAccuracy;
49
};
50
51
/**
52
 * Singleton that manages the geolocation provider
53
 */
54
class nsGeolocationService final : public nsIGeolocationUpdate,
55
                                   public nsIObserver
56
{
57
public:
58
59
  static already_AddRefed<nsGeolocationService> GetGeolocationService();
60
  static mozilla::StaticRefPtr<nsGeolocationService> sService;
61
62
  NS_DECL_THREADSAFE_ISUPPORTS
63
  NS_DECL_NSIGEOLOCATIONUPDATE
64
  NS_DECL_NSIOBSERVER
65
66
0
  nsGeolocationService() {
67
0
      mHigherAccuracy = false;
68
0
  }
69
70
  nsresult Init();
71
72
  // Management of the Geolocation objects
73
  void AddLocator(mozilla::dom::Geolocation* locator);
74
  void RemoveLocator(mozilla::dom::Geolocation* locator);
75
76
  void SetCachedPosition(nsIDOMGeoPosition* aPosition);
77
  CachedPositionAndAccuracy GetCachedPosition();
78
79
  // Find and startup a geolocation device (gps, nmea, etc.)
80
  nsresult StartDevice(nsIPrincipal* aPrincipal);
81
82
  // Stop the started geolocation device (gps, nmea, etc.)
83
  void     StopDevice();
84
85
  // create, or reinitalize the callback timer
86
  void     SetDisconnectTimer();
87
88
  // Update the accuracy and notify the provider if changed
89
  void     UpdateAccuracy(bool aForceHigh = false);
90
  bool     HighAccuracyRequested();
91
92
private:
93
94
  ~nsGeolocationService();
95
96
  // Disconnect timer.  When this timer expires, it clears all pending callbacks
97
  // and closes down the provider, unless we are watching a point, and in that
98
  // case, we disable the disconnect timer.
99
  nsCOMPtr<nsITimer> mDisconnectTimer;
100
101
  // The object providing geo location information to us.
102
  nsCOMPtr<nsIGeolocationProvider> mProvider;
103
104
  // mGeolocators are not owned here.  Their constructor
105
  // adds them to this list, and their destructor removes
106
  // them from this list.
107
  nsTArray<mozilla::dom::Geolocation*> mGeolocators;
108
109
  // This is the last geo position that we have seen.
110
  CachedPositionAndAccuracy mLastPosition;
111
112
  // Current state of requests for higher accuracy
113
  bool mHigherAccuracy;
114
};
115
116
namespace mozilla {
117
namespace dom {
118
119
/**
120
 * Can return a geolocation info
121
 */
122
class Geolocation final : public nsIGeolocationUpdate,
123
                          public nsWrapperCache
124
{
125
public:
126
127
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
128
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Geolocation)
129
130
  NS_DECL_NSIGEOLOCATIONUPDATE
131
132
  Geolocation();
133
134
  nsresult Init(nsPIDOMWindowInner* aContentDom = nullptr);
135
136
  nsPIDOMWindowInner* GetParentObject() const;
137
  virtual JSObject* WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto) override;
138
139
  int32_t WatchPosition(PositionCallback& aCallback,
140
                        PositionErrorCallback* aErrorCallback,
141
                        const PositionOptions& aOptions,
142
                        CallerType aCallerType,
143
                        ErrorResult& aRv);
144
  void GetCurrentPosition(PositionCallback& aCallback,
145
                          PositionErrorCallback* aErrorCallback,
146
                          const PositionOptions& aOptions,
147
                          CallerType aCallerType,
148
                          ErrorResult& aRv);
149
  void ClearWatch(int32_t aWatchId);
150
151
  // A WatchPosition for C++ use.  Returns -1 if we failed to actually watch.
152
  int32_t WatchPosition(nsIDOMGeoPositionCallback* aCallback,
153
                        nsIDOMGeoPositionErrorCallback* aErrorCallback,
154
                        UniquePtr<PositionOptions>&& aOptions);
155
156
  // Returns true if any of the callbacks are repeating
157
  bool HasActiveCallbacks();
158
159
  // Register an allowed request
160
  void NotifyAllowedRequest(nsGeolocationRequest* aRequest);
161
162
  // Remove request from all callbacks arrays
163
  void RemoveRequest(nsGeolocationRequest* request);
164
165
  // Check if there is already ClearWatch called for current
166
  // request & clear if yes
167
  bool ClearPendingRequest(nsGeolocationRequest* aRequest);
168
169
  // Shutting down.
170
  void Shutdown();
171
172
  // Getter for the principal that this Geolocation was loaded from
173
0
  nsIPrincipal* GetPrincipal() { return mPrincipal; }
174
175
  // Getter for the window that this Geolocation is owned by
176
0
  nsIWeakReference* GetOwner() { return mOwner; }
177
178
  // Check to see if the window still exists
179
  bool WindowOwnerStillExists();
180
181
  // Check to see if any active request requires high accuracy
182
  bool HighAccuracyRequested();
183
184
  // Get the singleton non-window Geolocation instance.  This never returns null.
185
  static already_AddRefed<Geolocation> NonWindowSingleton();
186
187
private:
188
189
  ~Geolocation();
190
191
  nsresult GetCurrentPosition(GeoPositionCallback aCallback,
192
                              GeoPositionErrorCallback aErrorCallback,
193
                              UniquePtr<PositionOptions>&& aOptions,
194
                              CallerType aCallerType);
195
  int32_t WatchPosition(GeoPositionCallback aCallback,
196
                        GeoPositionErrorCallback aErrorCallback,
197
                        UniquePtr<PositionOptions>&& aOptions,
198
                        CallerType aCallerType,
199
                        ErrorResult& aRv);
200
201
  bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
202
203
  // Check if clearWatch is already called
204
  bool IsAlreadyCleared(nsGeolocationRequest* aRequest);
205
206
  // Returns whether the Geolocation object should block requests
207
  // within a context that is not secure.
208
  bool ShouldBlockInsecureRequests() const;
209
210
  // Two callback arrays.  The first |mPendingCallbacks| holds objects for only
211
  // one callback and then they are released/removed from the array.  The second
212
  // |mWatchingCallbacks| holds objects until the object is explictly removed or
213
  // there is a page change. All requests held by either array are active, that
214
  // is, they have been allowed and expect to be fulfilled.
215
216
  nsTArray<RefPtr<nsGeolocationRequest> > mPendingCallbacks;
217
  nsTArray<RefPtr<nsGeolocationRequest> > mWatchingCallbacks;
218
219
  // window that this was created for.  Weak reference.
220
  nsWeakPtr mOwner;
221
222
  // where the content was loaded from
223
  nsCOMPtr<nsIPrincipal> mPrincipal;
224
225
  // the protocols we want to measure
226
  enum class ProtocolType: uint8_t { OTHER, HTTP, HTTPS };
227
228
  // the protocol used to load the content
229
  ProtocolType mProtocolType;
230
231
  // owning back pointer.
232
  RefPtr<nsGeolocationService> mService;
233
234
  // Watch ID
235
  uint32_t mLastWatchId;
236
237
  // Pending requests are used when the service is not ready
238
  nsTArray<RefPtr<nsGeolocationRequest> > mPendingRequests;
239
240
  // Array containing already cleared watch IDs
241
  nsTArray<int32_t> mClearedWatchIDs;
242
243
  // Our cached non-window singleton.
244
  static mozilla::StaticRefPtr<Geolocation> sNonWindowSingleton;
245
};
246
247
} // namespace dom
248
} // namespace mozilla
249
250
#endif /* nsGeoLocation_h */