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/. */
7 #ifndef mozilla_dom_Geolocation_h
8 #define mozilla_dom_Geolocation_h
10 // Microsoft's API Name hackery sucks
13 #include "mozilla/StaticPtr.h"
17 #include "nsIObserver.h"
18 #include "nsIWeakReferenceUtils.h"
19 #include "nsWrapperCache.h"
21 #include "nsCycleCollectionParticipant.h"
23 #include "GeolocationPosition.h"
24 #include "GeolocationCoordinates.h"
25 #include "nsIDOMGeoPosition.h"
26 #include "nsIDOMGeoPositionCallback.h"
27 #include "nsIDOMGeoPositionErrorCallback.h"
28 #include "mozilla/dom/BindingDeclarations.h"
29 #include "mozilla/dom/GeolocationBinding.h"
30 #include "mozilla/dom/CallbackObject.h"
32 #include "nsIGeolocationProvider.h"
33 #include "mozilla/Attributes.h"
35 class nsGeolocationService
;
36 class nsGeolocationRequest
;
38 namespace mozilla::dom
{
40 using GeoPositionCallback
=
41 CallbackObjectHolder
<PositionCallback
, nsIDOMGeoPositionCallback
>;
42 using GeoPositionErrorCallback
=
43 CallbackObjectHolder
<PositionErrorCallback
, nsIDOMGeoPositionErrorCallback
>;
44 } // namespace mozilla::dom
46 struct CachedPositionAndAccuracy
{
47 nsCOMPtr
<nsIDOMGeoPosition
> position
;
52 * Singleton that manages the geolocation provider
54 class nsGeolocationService final
: public nsIGeolocationUpdate
,
57 static already_AddRefed
<nsGeolocationService
> GetGeolocationService();
58 static mozilla::StaticRefPtr
<nsGeolocationService
> sService
;
60 NS_DECL_THREADSAFE_ISUPPORTS
61 NS_DECL_NSIGEOLOCATIONUPDATE
64 nsGeolocationService() = default;
68 // Management of the Geolocation objects
69 void AddLocator(mozilla::dom::Geolocation
* locator
);
70 void RemoveLocator(mozilla::dom::Geolocation
* locator
);
72 void SetCachedPosition(nsIDOMGeoPosition
* aPosition
);
73 CachedPositionAndAccuracy
GetCachedPosition();
75 // Find and startup a geolocation device (gps, nmea, etc.)
76 MOZ_CAN_RUN_SCRIPT nsresult
StartDevice();
78 // Stop the started geolocation device (gps, nmea, etc.)
81 // create, or reinitialize the callback timer
82 void SetDisconnectTimer();
84 // Update the accuracy and notify the provider if changed
85 void UpdateAccuracy(bool aForceHigh
= false);
86 bool HighAccuracyRequested();
89 ~nsGeolocationService();
91 // Disconnect timer. When this timer expires, it clears all pending callbacks
92 // and closes down the provider, unless we are watching a point, and in that
93 // case, we disable the disconnect timer.
94 nsCOMPtr
<nsITimer
> mDisconnectTimer
;
96 // The object providing geo location information to us.
97 nsCOMPtr
<nsIGeolocationProvider
> mProvider
;
99 // mGeolocators are not owned here. Their constructor
100 // adds them to this list, and their destructor removes
101 // them from this list.
102 nsTArray
<mozilla::dom::Geolocation
*> mGeolocators
;
104 // This is the last geo position that we have seen.
105 CachedPositionAndAccuracy mLastPosition
;
107 // Current state of requests for higher accuracy
108 bool mHigherAccuracy
= false;
111 namespace mozilla::dom
{
114 * Can return a geolocation info
116 class Geolocation final
: public nsIGeolocationUpdate
, public nsWrapperCache
{
118 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
119 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Geolocation
)
121 NS_DECL_NSIGEOLOCATIONUPDATE
125 nsresult
Init(nsPIDOMWindowInner
* aContentDom
= nullptr);
127 nsPIDOMWindowInner
* GetParentObject() const;
128 virtual JSObject
* WrapObject(JSContext
* aCtx
,
129 JS::Handle
<JSObject
*> aGivenProto
) override
;
132 int32_t WatchPosition(PositionCallback
& aCallback
,
133 PositionErrorCallback
* aErrorCallback
,
134 const PositionOptions
& aOptions
, CallerType aCallerType
,
138 void GetCurrentPosition(PositionCallback
& aCallback
,
139 PositionErrorCallback
* aErrorCallback
,
140 const PositionOptions
& aOptions
,
141 CallerType aCallerType
, ErrorResult
& aRv
);
142 void ClearWatch(int32_t aWatchId
);
144 // A WatchPosition for C++ use. Returns 0 if we failed to actually watch.
146 int32_t WatchPosition(nsIDOMGeoPositionCallback
* aCallback
,
147 nsIDOMGeoPositionErrorCallback
* aErrorCallback
,
148 UniquePtr
<PositionOptions
>&& aOptions
);
150 // Returns true if any of the callbacks are repeating
151 bool HasActiveCallbacks();
153 // Register an allowed request
154 void NotifyAllowedRequest(nsGeolocationRequest
* aRequest
);
156 // Remove request from all callbacks arrays
157 void RemoveRequest(nsGeolocationRequest
* request
);
159 // Check if there is already ClearWatch called for current
160 // request & clear if yes
161 bool ClearPendingRequest(nsGeolocationRequest
* aRequest
);
166 // Getter for the principal that this Geolocation was loaded from
167 nsIPrincipal
* GetPrincipal() { return mPrincipal
; }
169 // Getter for the window that this Geolocation is owned by
170 nsIWeakReference
* GetOwner() { return mOwner
; }
172 // Check to see if the window still exists
173 bool WindowOwnerStillExists();
175 // Check to see if any active request requires high accuracy
176 bool HighAccuracyRequested();
178 // Get the singleton non-window Geolocation instance. This never returns
180 static already_AddRefed
<Geolocation
> NonWindowSingleton();
186 nsresult
GetCurrentPosition(GeoPositionCallback aCallback
,
187 GeoPositionErrorCallback aErrorCallback
,
188 UniquePtr
<PositionOptions
>&& aOptions
,
189 CallerType aCallerType
);
192 int32_t WatchPosition(GeoPositionCallback aCallback
,
193 GeoPositionErrorCallback aErrorCallback
,
194 UniquePtr
<PositionOptions
>&& aOptions
,
195 CallerType aCallerType
, ErrorResult
& aRv
);
197 bool RegisterRequestWithPrompt(nsGeolocationRequest
* request
);
199 // Check if clearWatch is already called
200 bool IsAlreadyCleared(nsGeolocationRequest
* aRequest
);
202 // Returns whether the Geolocation object should block requests
203 // within a context that is not secure.
204 bool ShouldBlockInsecureRequests() const;
206 // Checks if the request is in a content window that is fully active, or the
207 // request is coming from a chrome window.
208 bool IsFullyActiveOrChrome();
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.
216 nsTArray
<RefPtr
<nsGeolocationRequest
> > mPendingCallbacks
;
217 nsTArray
<RefPtr
<nsGeolocationRequest
> > mWatchingCallbacks
;
219 // window that this was created for. Weak reference.
222 // where the content was loaded from
223 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
225 // the protocols we want to measure
226 enum class ProtocolType
: uint8_t { OTHER
, HTTP
, HTTPS
};
228 // the protocol used to load the content
229 ProtocolType mProtocolType
;
231 // owning back pointer.
232 RefPtr
<nsGeolocationService
> mService
;
235 uint32_t mLastWatchId
;
237 // Pending requests are used when the service is not ready
238 nsTArray
<RefPtr
<nsGeolocationRequest
> > mPendingRequests
;
240 // Array containing already cleared watch IDs
241 nsTArray
<int32_t> mClearedWatchIDs
;
243 // Our cached non-window singleton.
244 static mozilla::StaticRefPtr
<Geolocation
> sNonWindowSingleton
;
247 } // namespace mozilla::dom
249 #endif /* mozilla_dom_Geolocation_h */