/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 */ |