summaryrefslogtreecommitdiffstats
path: root/dom/geolocation/Geolocation.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/geolocation/Geolocation.h')
-rw-r--r--dom/geolocation/Geolocation.h249
1 files changed, 249 insertions, 0 deletions
diff --git a/dom/geolocation/Geolocation.h b/dom/geolocation/Geolocation.h
new file mode 100644
index 0000000000..7e1af00d05
--- /dev/null
+++ b/dom/geolocation/Geolocation.h
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_Geolocation_h
+#define mozilla_dom_Geolocation_h
+
+// Microsoft's API Name hackery sucks
+#undef CreateEvent
+
+#include "mozilla/StaticPtr.h"
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+#include "nsITimer.h"
+#include "nsIObserver.h"
+#include "nsIWeakReferenceUtils.h"
+#include "nsWrapperCache.h"
+
+#include "nsCycleCollectionParticipant.h"
+
+#include "GeolocationPosition.h"
+#include "GeolocationCoordinates.h"
+#include "nsIDOMGeoPosition.h"
+#include "nsIDOMGeoPositionCallback.h"
+#include "nsIDOMGeoPositionErrorCallback.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/GeolocationBinding.h"
+#include "mozilla/dom/CallbackObject.h"
+
+#include "nsIGeolocationProvider.h"
+#include "mozilla/Attributes.h"
+
+class nsGeolocationService;
+class nsGeolocationRequest;
+
+namespace mozilla::dom {
+class Geolocation;
+using GeoPositionCallback =
+ CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback>;
+using GeoPositionErrorCallback =
+ CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallback>;
+} // namespace mozilla::dom
+
+struct CachedPositionAndAccuracy {
+ nsCOMPtr<nsIDOMGeoPosition> position;
+ bool isHighAccuracy;
+};
+
+/**
+ * Singleton that manages the geolocation provider
+ */
+class nsGeolocationService final : public nsIGeolocationUpdate,
+ public nsIObserver {
+ public:
+ static already_AddRefed<nsGeolocationService> GetGeolocationService();
+ static mozilla::StaticRefPtr<nsGeolocationService> sService;
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIGEOLOCATIONUPDATE
+ NS_DECL_NSIOBSERVER
+
+ nsGeolocationService() = default;
+
+ nsresult Init();
+
+ // Management of the Geolocation objects
+ void AddLocator(mozilla::dom::Geolocation* locator);
+ void RemoveLocator(mozilla::dom::Geolocation* locator);
+
+ void SetCachedPosition(nsIDOMGeoPosition* aPosition);
+ CachedPositionAndAccuracy GetCachedPosition();
+
+ // Find and startup a geolocation device (gps, nmea, etc.)
+ MOZ_CAN_RUN_SCRIPT nsresult StartDevice();
+
+ // Stop the started geolocation device (gps, nmea, etc.)
+ void StopDevice();
+
+ // create, or reinitialize the callback timer
+ void SetDisconnectTimer();
+
+ // Update the accuracy and notify the provider if changed
+ void UpdateAccuracy(bool aForceHigh = false);
+ bool HighAccuracyRequested();
+
+ private:
+ ~nsGeolocationService();
+
+ // Disconnect timer. When this timer expires, it clears all pending callbacks
+ // and closes down the provider, unless we are watching a point, and in that
+ // case, we disable the disconnect timer.
+ nsCOMPtr<nsITimer> mDisconnectTimer;
+
+ // The object providing geo location information to us.
+ nsCOMPtr<nsIGeolocationProvider> mProvider;
+
+ // mGeolocators are not owned here. Their constructor
+ // adds them to this list, and their destructor removes
+ // them from this list.
+ nsTArray<mozilla::dom::Geolocation*> mGeolocators;
+
+ // This is the last geo position that we have seen.
+ CachedPositionAndAccuracy mLastPosition;
+
+ // Current state of requests for higher accuracy
+ bool mHigherAccuracy = false;
+};
+
+namespace mozilla::dom {
+
+/**
+ * Can return a geolocation info
+ */
+class Geolocation final : public nsIGeolocationUpdate, public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Geolocation)
+
+ NS_DECL_NSIGEOLOCATIONUPDATE
+
+ Geolocation();
+
+ nsresult Init(nsPIDOMWindowInner* aContentDom = nullptr);
+
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCtx,
+ JS::Handle<JSObject*> aGivenProto) override;
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t WatchPosition(PositionCallback& aCallback,
+ PositionErrorCallback* aErrorCallback,
+ const PositionOptions& aOptions, CallerType aCallerType,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT
+ void GetCurrentPosition(PositionCallback& aCallback,
+ PositionErrorCallback* aErrorCallback,
+ const PositionOptions& aOptions,
+ CallerType aCallerType, ErrorResult& aRv);
+ void ClearWatch(int32_t aWatchId);
+
+ // A WatchPosition for C++ use. Returns 0 if we failed to actually watch.
+ MOZ_CAN_RUN_SCRIPT
+ int32_t WatchPosition(nsIDOMGeoPositionCallback* aCallback,
+ nsIDOMGeoPositionErrorCallback* aErrorCallback,
+ UniquePtr<PositionOptions>&& aOptions);
+
+ // Returns true if any of the callbacks are repeating
+ bool HasActiveCallbacks();
+
+ // Register an allowed request
+ void NotifyAllowedRequest(nsGeolocationRequest* aRequest);
+
+ // Remove request from all callbacks arrays
+ void RemoveRequest(nsGeolocationRequest* request);
+
+ // Check if there is already ClearWatch called for current
+ // request & clear if yes
+ bool ClearPendingRequest(nsGeolocationRequest* aRequest);
+
+ // Shutting down.
+ void Shutdown();
+
+ // Getter for the principal that this Geolocation was loaded from
+ nsIPrincipal* GetPrincipal() { return mPrincipal; }
+
+ // Getter for the window that this Geolocation is owned by
+ nsIWeakReference* GetOwner() { return mOwner; }
+
+ // Check to see if the window still exists
+ bool WindowOwnerStillExists();
+
+ // Check to see if any active request requires high accuracy
+ bool HighAccuracyRequested();
+
+ // Get the singleton non-window Geolocation instance. This never returns
+ // null.
+ static already_AddRefed<Geolocation> NonWindowSingleton();
+
+ private:
+ ~Geolocation();
+
+ MOZ_CAN_RUN_SCRIPT
+ nsresult GetCurrentPosition(GeoPositionCallback aCallback,
+ GeoPositionErrorCallback aErrorCallback,
+ UniquePtr<PositionOptions>&& aOptions,
+ CallerType aCallerType);
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t WatchPosition(GeoPositionCallback aCallback,
+ GeoPositionErrorCallback aErrorCallback,
+ UniquePtr<PositionOptions>&& aOptions,
+ CallerType aCallerType, ErrorResult& aRv);
+
+ bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
+
+ // Check if clearWatch is already called
+ bool IsAlreadyCleared(nsGeolocationRequest* aRequest);
+
+ // Returns whether the Geolocation object should block requests
+ // within a context that is not secure.
+ bool ShouldBlockInsecureRequests() const;
+
+ // Checks if the request is in a content window that is fully active, or the
+ // request is coming from a chrome window.
+ bool IsFullyActiveOrChrome();
+
+ // Two callback arrays. The first |mPendingCallbacks| holds objects for only
+ // one callback and then they are released/removed from the array. The second
+ // |mWatchingCallbacks| holds objects until the object is explictly removed or
+ // there is a page change. All requests held by either array are active, that
+ // is, they have been allowed and expect to be fulfilled.
+
+ nsTArray<RefPtr<nsGeolocationRequest> > mPendingCallbacks;
+ nsTArray<RefPtr<nsGeolocationRequest> > mWatchingCallbacks;
+
+ // window that this was created for. Weak reference.
+ nsWeakPtr mOwner;
+
+ // where the content was loaded from
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+
+ // the protocols we want to measure
+ enum class ProtocolType : uint8_t { OTHER, HTTP, HTTPS };
+
+ // the protocol used to load the content
+ ProtocolType mProtocolType;
+
+ // owning back pointer.
+ RefPtr<nsGeolocationService> mService;
+
+ // Watch ID
+ uint32_t mLastWatchId;
+
+ // Pending requests are used when the service is not ready
+ nsTArray<RefPtr<nsGeolocationRequest> > mPendingRequests;
+
+ // Array containing already cleared watch IDs
+ nsTArray<int32_t> mClearedWatchIDs;
+
+ // Our cached non-window singleton.
+ static mozilla::StaticRefPtr<Geolocation> sNonWindowSingleton;
+};
+
+} // namespace mozilla::dom
+
+#endif /* mozilla_dom_Geolocation_h */