Home | History | Annotate | Download | only in geolocation
      1 /*
      2  * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved.
      3  * Copyright 2010, The Android Open Source Project
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef Geolocation_h
     28 #define Geolocation_h
     29 
     30 #include "bindings/core/v8/ScriptWrappable.h"
     31 #include "core/dom/ActiveDOMObject.h"
     32 #include "modules/geolocation/GeoNotifier.h"
     33 #include "modules/geolocation/GeolocationWatchers.h"
     34 #include "modules/geolocation/Geoposition.h"
     35 #include "modules/geolocation/PositionCallback.h"
     36 #include "modules/geolocation/PositionError.h"
     37 #include "modules/geolocation/PositionErrorCallback.h"
     38 #include "modules/geolocation/PositionOptions.h"
     39 #include "platform/Timer.h"
     40 #include "platform/heap/Handle.h"
     41 
     42 namespace blink {
     43 
     44 class Dictionary;
     45 class Document;
     46 class LocalFrame;
     47 class GeolocationController;
     48 class GeolocationError;
     49 class GeolocationPosition;
     50 class ExecutionContext;
     51 
     52 class Geolocation FINAL
     53     : public GarbageCollectedFinalized<Geolocation>
     54     , public ScriptWrappable
     55     , public ActiveDOMObject {
     56     DEFINE_WRAPPERTYPEINFO();
     57 public:
     58     static Geolocation* create(ExecutionContext*);
     59     virtual ~Geolocation();
     60     void trace(Visitor*);
     61 
     62     virtual void stop() OVERRIDE;
     63     Document* document() const;
     64     LocalFrame* frame() const;
     65 
     66     // Creates a oneshot and attempts to obtain a position that meets the
     67     // constraints of the options.
     68     void getCurrentPosition(PositionCallback*, PositionErrorCallback*, const Dictionary&);
     69 
     70     // Creates a watcher that will be notified whenever a new position is
     71     // available that meets the constraints of the options.
     72     int watchPosition(PositionCallback*, PositionErrorCallback*, const Dictionary&);
     73 
     74     // Removes all references to the watcher, it will not be updated again.
     75     void clearWatch(int watchID);
     76 
     77     void setIsAllowed(bool);
     78 
     79     bool isAllowed() const { return m_geolocationPermission == PermissionAllowed; }
     80 
     81     // Notifies this that a new position is available. Must never be called
     82     // before permission is granted by the user.
     83     void positionChanged();
     84 
     85     // Notifies this that an error has occurred, it must be handled immediately.
     86     void setError(GeolocationError*);
     87 
     88     // Discards the notifier because a fatal error occurred for it.
     89     void fatalErrorOccurred(GeoNotifier*);
     90 
     91     // Adds the notifier to the set awaiting a cached position. Runs the success
     92     // callbacks for them if permission has been granted. Requests permission if
     93     // it is unknown.
     94     void requestUsesCachedPosition(GeoNotifier*);
     95 
     96     // Discards the notifier if it is a oneshot because it timed it.
     97     void requestTimedOut(GeoNotifier*);
     98 
     99 private:
    100     // Returns the last known position, if any. May return null.
    101     Geoposition* lastPosition();
    102 
    103     bool isDenied() const { return m_geolocationPermission == PermissionDenied; }
    104 
    105     explicit Geolocation(ExecutionContext*);
    106 
    107     typedef HeapVector<Member<GeoNotifier> > GeoNotifierVector;
    108     typedef HeapHashSet<Member<GeoNotifier> > GeoNotifierSet;
    109 
    110     bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
    111 
    112     void sendError(GeoNotifierVector&, PositionError*);
    113     void sendPosition(GeoNotifierVector&, Geoposition*);
    114 
    115     // Removes notifiers that use a cached position from |notifiers| and
    116     // if |cached| is not null they are added to it.
    117     static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached);
    118 
    119     // Copies notifiers from |src| vector to |dest| set.
    120     static void copyToSet(const GeoNotifierVector& src, GeoNotifierSet& dest);
    121 
    122     static void stopTimer(GeoNotifierVector&);
    123     void stopTimersForOneShots();
    124     void stopTimersForWatchers();
    125     void stopTimers();
    126 
    127     // Sets a fatal error on the given notifiers.
    128     void cancelRequests(GeoNotifierVector&);
    129 
    130     // Sets a fatal error on all notifiers.
    131     void cancelAllRequests();
    132 
    133     // Runs the success callbacks on all notifiers. A position must be available
    134     // and the user must have given permission.
    135     void makeSuccessCallbacks();
    136 
    137     // Sends the given error to all notifiers, unless the error is not fatal and
    138     // the notifier is due to receive a cached position. Clears the oneshots,
    139     // and also  clears the watchers if the error is fatal.
    140     void handleError(PositionError*);
    141 
    142     // Requests permission to share positions with the page.
    143     void requestPermission();
    144 
    145     // Attempts to register this with the controller for receiving updates.
    146     // Returns false if there is no controller to register with.
    147     bool startUpdating(GeoNotifier*);
    148 
    149     void stopUpdating();
    150 
    151     // Processes the notifiers that were waiting for a permission decision. If
    152     // granted and this can be registered with the controller then the
    153     // notifier's timers are started. Otherwise, a fatal error is set on them.
    154     void handlePendingPermissionNotifiers();
    155 
    156     // Attempts to obtain a position for the given notifier, either by using
    157     // the cached position or by requesting one from the controller. Sets a
    158     // fatal error if permission is denied or no position can be obtained.
    159     void startRequest(GeoNotifier*);
    160 
    161     bool haveSuitableCachedPosition(PositionOptions*);
    162 
    163     // Runs the success callbacks for the set of notifiers awaiting a cached
    164     // position, the set is then cleared. The oneshots are removed everywhere.
    165     void makeCachedPositionCallbacks();
    166 
    167     GeoNotifierSet m_oneShots;
    168     GeolocationWatchers m_watchers;
    169     GeoNotifierSet m_pendingForPermissionNotifiers;
    170     Member<Geoposition> m_lastPosition;
    171 
    172     // States of Geolocation permission as granted by the embedder. Unknown
    173     // means that the embedder still has to be asked for the current permission
    174     // level; Requested means that the user has yet to make a decision.
    175     enum Permission {
    176         PermissionUnknown,
    177         PermissionRequested,
    178         PermissionAllowed,
    179         PermissionDenied
    180     };
    181 
    182     Permission m_geolocationPermission;
    183 
    184     GeoNotifierSet m_requestsAwaitingCachedPosition;
    185 };
    186 
    187 } // namespace blink
    188 
    189 #endif // Geolocation_h
    190