tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Geolocation.h (9353B)


      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 mozilla_dom_Geolocation_h
      8 #define mozilla_dom_Geolocation_h
      9 
     10 // Microsoft's API Name hackery sucks
     11 #undef CreateEvent
     12 
     13 #include "GeolocationCoordinates.h"
     14 #include "GeolocationPosition.h"
     15 #include "GeolocationSystem.h"
     16 #include "mozilla/Attributes.h"
     17 #include "mozilla/dom/BindingDeclarations.h"
     18 #include "mozilla/dom/CallbackObject.h"
     19 #include "mozilla/dom/GeolocationBinding.h"
     20 #include "nsCOMPtr.h"
     21 #include "nsCycleCollectionParticipant.h"
     22 #include "nsIDOMGeoPosition.h"
     23 #include "nsIDOMGeoPositionCallback.h"
     24 #include "nsIDOMGeoPositionErrorCallback.h"
     25 #include "nsIGeolocationProvider.h"
     26 #include "nsIObserver.h"
     27 #include "nsITimer.h"
     28 #include "nsIWeakReferenceUtils.h"
     29 #include "nsTArray.h"
     30 #include "nsWrapperCache.h"
     31 
     32 class nsGeolocationService;
     33 class nsGeolocationRequest;
     34 
     35 namespace mozilla::dom {
     36 class Geolocation;
     37 using GeoPositionCallback =
     38    CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback>;
     39 using GeoPositionErrorCallback =
     40    CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallback>;
     41 namespace geolocation {
     42 enum class LocationOSPermission;
     43 }
     44 }  // namespace mozilla::dom
     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 public:
     57  static already_AddRefed<nsGeolocationService> GetGeolocationService(
     58      mozilla::dom::BrowsingContext* browsingContext = nullptr);
     59  static mozilla::StaticRefPtr<nsGeolocationService> sService;
     60 
     61  NS_DECL_THREADSAFE_ISUPPORTS
     62  NS_DECL_NSIGEOLOCATIONUPDATE
     63  NS_DECL_NSIOBSERVER
     64 
     65  nsGeolocationService() = default;
     66 
     67  nsresult Init();
     68 
     69  // Management of the Geolocation objects
     70  void AddLocator(mozilla::dom::Geolocation* aLocator);
     71  void RemoveLocator(mozilla::dom::Geolocation* aLocator);
     72 
     73  // Move locators from service override to the original service.
     74  void MoveLocators(nsGeolocationService* aService);
     75 
     76  void SetCachedPosition(nsIDOMGeoPosition* aPosition);
     77  CachedPositionAndAccuracy GetCachedPosition();
     78 
     79  // Find and startup a geolocation device (gps, nmea, etc.)
     80  MOZ_CAN_RUN_SCRIPT nsresult StartDevice();
     81 
     82  // Stop the started geolocation device (gps, nmea, etc.)
     83  void StopDevice();
     84 
     85  // create, or reinitialize 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  ~nsGeolocationService();
     94 
     95  // Disconnect timer.  When this timer expires, it clears all pending callbacks
     96  // and closes down the provider, unless we are watching a point, and in that
     97  // case, we disable the disconnect timer.
     98  nsCOMPtr<nsITimer> mDisconnectTimer;
     99 
    100  // The object providing geo location information to us.
    101  nsCOMPtr<nsIGeolocationProvider> mProvider;
    102 
    103  // mGeolocators are not owned here.  Their constructor
    104  // adds them to this list, and their destructor removes
    105  // them from this list.
    106  nsTArray<mozilla::dom::Geolocation*> mGeolocators;
    107 
    108  // This is the last geo position that we have seen.
    109  CachedPositionAndAccuracy mLastPosition;
    110 
    111  // Current state of requests for higher accuracy
    112  bool mHigherAccuracy = false;
    113 
    114  // Whether the geolocation device is starting.
    115  // Nothing() if not being started, or a boolean reflecting the requested
    116  // accuracy.
    117  mozilla::Maybe<bool> mStarting;
    118 };
    119 
    120 namespace mozilla::dom {
    121 
    122 /**
    123 * Can return a geolocation info
    124 */
    125 class Geolocation final : public nsIGeolocationUpdate, public nsWrapperCache {
    126 public:
    127  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    128  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_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,
    138                               JS::Handle<JSObject*> aGivenProto) override;
    139 
    140  MOZ_CAN_RUN_SCRIPT
    141  int32_t WatchPosition(PositionCallback& aCallback,
    142                        PositionErrorCallback* aErrorCallback,
    143                        const PositionOptions& aOptions, CallerType aCallerType,
    144                        ErrorResult& aRv);
    145 
    146  MOZ_CAN_RUN_SCRIPT
    147  void GetCurrentPosition(PositionCallback& aCallback,
    148                          PositionErrorCallback* aErrorCallback,
    149                          const PositionOptions& aOptions,
    150                          CallerType aCallerType, ErrorResult& aRv);
    151  void ClearWatch(int32_t aWatchId);
    152 
    153  // A WatchPosition for C++ use. Returns 0 if we failed to actually watch.
    154  MOZ_CAN_RUN_SCRIPT
    155  int32_t WatchPosition(nsIDOMGeoPositionCallback* aCallback,
    156                        nsIDOMGeoPositionErrorCallback* aErrorCallback,
    157                        UniquePtr<PositionOptions>&& aOptions);
    158 
    159  // Returns true if any of the callbacks are repeating
    160  bool HasActiveCallbacks();
    161 
    162  // Register an allowed request
    163  void NotifyAllowedRequest(nsGeolocationRequest* aRequest);
    164 
    165  // Remove request from all callbacks arrays
    166  void RemoveRequest(nsGeolocationRequest* request);
    167 
    168  // Check if there is already ClearWatch called for current
    169  // request & clear if yes
    170  bool ClearPendingRequest(nsGeolocationRequest* aRequest);
    171 
    172  // Shutting down.
    173  void Shutdown();
    174 
    175  // Getter for the browsing context that this Geolocation was loaded for
    176  mozilla::dom::BrowsingContext* GetBrowsingContext() {
    177    return mBrowsingContext;
    178  }
    179 
    180  // Getter for the principal that this Geolocation was loaded from
    181  nsIPrincipal* GetPrincipal() { return mPrincipal; }
    182 
    183  // Getter for the window that this Geolocation is owned by
    184  nsIWeakReference* GetOwner() { return mOwner; }
    185 
    186  // Check to see if the window still exists
    187  bool WindowOwnerStillExists();
    188 
    189  // Check to see if any active request requires high accuracy
    190  bool HighAccuracyRequested();
    191 
    192  // Get the singleton non-window Geolocation instance.  This never returns
    193  // null.
    194  static already_AddRefed<Geolocation> NonWindowSingleton();
    195 
    196  static geolocation::SystemGeolocationPermissionBehavior
    197  GetLocationOSPermission();
    198 
    199  static MOZ_CAN_RUN_SCRIPT void ReallowWithSystemPermissionOrCancel(
    200      BrowsingContext* aBrowsingContext,
    201      geolocation::ParentRequestResolver&& aResolver);
    202 
    203 private:
    204  ~Geolocation();
    205 
    206  MOZ_CAN_RUN_SCRIPT
    207  nsresult GetCurrentPosition(GeoPositionCallback aCallback,
    208                              GeoPositionErrorCallback aErrorCallback,
    209                              UniquePtr<PositionOptions>&& aOptions,
    210                              CallerType aCallerType);
    211 
    212  MOZ_CAN_RUN_SCRIPT
    213  int32_t WatchPosition(GeoPositionCallback aCallback,
    214                        GeoPositionErrorCallback aErrorCallback,
    215                        UniquePtr<PositionOptions>&& aOptions,
    216                        CallerType aCallerType, ErrorResult& aRv);
    217 
    218  static bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
    219 
    220  // Check if clearWatch is already called
    221  bool IsAlreadyCleared(nsGeolocationRequest* aRequest);
    222 
    223  // Returns whether the Geolocation object should block requests
    224  // within a context that is not secure.
    225  bool ShouldBlockInsecureRequests() const;
    226 
    227  // Checks if the request is in a content window that is fully active, or the
    228  // request is coming from a chrome window.
    229  bool IsFullyActiveOrChrome();
    230 
    231  // Initates the asynchronous process of filling the request.
    232  static void RequestIfPermitted(nsGeolocationRequest* request);
    233 
    234  // Two callback arrays.  The first |mPendingCallbacks| holds objects for only
    235  // one callback and then they are released/removed from the array.  The second
    236  // |mWatchingCallbacks| holds objects until the object is explicitly removed
    237  // or there is a page change. All requests held by either array are active,
    238  // that is, they have been allowed and expect to be fulfilled.
    239 
    240  nsTArray<RefPtr<nsGeolocationRequest> > mPendingCallbacks;
    241  nsTArray<RefPtr<nsGeolocationRequest> > mWatchingCallbacks;
    242 
    243  // window that this was created for.  Weak reference.
    244  nsWeakPtr mOwner;
    245 
    246  // where the content was loaded from
    247  nsCOMPtr<nsIPrincipal> mPrincipal;
    248  RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
    249 
    250  // the protocols we want to measure
    251  enum class ProtocolType : uint8_t { OTHER, HTTP, HTTPS };
    252 
    253  // the protocol used to load the content
    254  ProtocolType mProtocolType;
    255 
    256  // owning back pointer.
    257  RefPtr<nsGeolocationService> mService;
    258  // owning back pointer for service override.
    259  RefPtr<nsGeolocationService> mServiceOverride;
    260 
    261  // Watch ID
    262  uint32_t mLastWatchId;
    263 
    264  // Pending requests are used when the service is not ready
    265  nsTArray<RefPtr<nsGeolocationRequest> > mPendingRequests;
    266 
    267  // Array containing already cleared watch IDs
    268  nsTArray<int32_t> mClearedWatchIDs;
    269 
    270  // Our cached non-window singleton.
    271  static mozilla::StaticRefPtr<Geolocation> sNonWindowSingleton;
    272 };
    273 
    274 }  // namespace mozilla::dom
    275 
    276 #endif /* mozilla_dom_Geolocation_h */