Home | History | Annotate | Download | only in page
      1 /*
      2  * Copyright (C) 2008, 2009 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 // ANDROID
     31 #include "EventListener.h"
     32 // END ANDROID
     33 #include "GeolocationPositionCache.h"
     34 #include "GeolocationService.h"
     35 #include "Geoposition.h"
     36 #include "PositionCallback.h"
     37 #include "PositionError.h"
     38 #include "PositionErrorCallback.h"
     39 #include "PositionOptions.h"
     40 #include "Timer.h"
     41 #include <wtf/HashMap.h>
     42 #include <wtf/HashSet.h>
     43 #include <wtf/OwnPtr.h>
     44 #include <wtf/PassRefPtr.h>
     45 #include <wtf/Platform.h>
     46 #include <wtf/RefCounted.h>
     47 #include <wtf/RefPtr.h>
     48 #include <wtf/Vector.h>
     49 
     50 namespace WebCore {
     51 
     52 class Frame;
     53 
     54 #if ENABLE(CLIENT_BASED_GEOLOCATION)
     55 class GeolocationPosition;
     56 class GeolocationError;
     57 #endif
     58 
     59 // ANDROID
     60 class Geolocation : public EventListener
     61 // END ANDROID
     62 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
     63     , public GeolocationServiceClient
     64 #endif
     65 {
     66 public:
     67     static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
     68 
     69     virtual ~Geolocation();
     70 
     71     void disconnectFrame();
     72 
     73     Geoposition* lastPosition();
     74 
     75     void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
     76     int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
     77     void clearWatch(int watchId);
     78 
     79     void suspend();
     80     void resume();
     81 
     82     void setIsAllowed(bool);
     83     bool isAllowed() const { return m_allowGeolocation == Yes; }
     84     bool isDenied() const { return m_allowGeolocation == No; }
     85 
     86     void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
     87     bool shouldClearCache() const { return m_shouldClearCache; }
     88 
     89 #if ENABLE(CLIENT_BASED_GEOLOCATION)
     90     void setPosition(GeolocationPosition*);
     91     void setError(GeolocationError*);
     92 #endif
     93 
     94 private:
     95     Geolocation(Frame*);
     96 
     97     class GeoNotifier : public RefCounted<GeoNotifier> {
     98     public:
     99         static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
    100 
    101         void setFatalError(PassRefPtr<PositionError>);
    102         bool hasZeroTimeout() const;
    103         void setUseCachedPosition();
    104         void runSuccessCallback(Geoposition*);
    105         void startTimerIfNeeded();
    106         void timerFired(Timer<GeoNotifier>*);
    107 
    108         Geolocation* m_geolocation;
    109         RefPtr<PositionCallback> m_successCallback;
    110         RefPtr<PositionErrorCallback> m_errorCallback;
    111         RefPtr<PositionOptions> m_options;
    112         Timer<GeoNotifier> m_timer;
    113         RefPtr<PositionError> m_fatalError;
    114         bool m_useCachedPosition;
    115 
    116     private:
    117         GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
    118     };
    119 
    120     class Watchers {
    121     public:
    122         void set(int id, PassRefPtr<GeoNotifier>);
    123         void remove(int id);
    124         void remove(GeoNotifier*);
    125         bool contains(GeoNotifier*) const;
    126         void clear();
    127         bool isEmpty() const;
    128         void getNotifiersVector(Vector<RefPtr<GeoNotifier> >&) const;
    129     private:
    130         typedef HashMap<int, RefPtr<GeoNotifier> > IdToNotifierMap;
    131         typedef HashMap<RefPtr<GeoNotifier>, int> NotifierToIdMap;
    132         IdToNotifierMap m_idToNotifierMap;
    133         NotifierToIdMap m_notifierToIdMap;
    134     };
    135 
    136     bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
    137 
    138     void sendError(Vector<RefPtr<GeoNotifier> >&, PositionError*);
    139     void sendPosition(Vector<RefPtr<GeoNotifier> >&, Geoposition*);
    140 
    141     static void stopTimer(Vector<RefPtr<GeoNotifier> >&);
    142     void stopTimersForOneShots();
    143     void stopTimersForWatchers();
    144     void stopTimers();
    145 
    146     void positionChanged(PassRefPtr<Geoposition>);
    147     void makeSuccessCallbacks();
    148     void handleError(PositionError*);
    149 
    150     void requestPermission();
    151 
    152     bool startUpdating(GeoNotifier*);
    153     void stopUpdating();
    154 
    155 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
    156     // GeolocationServiceClient
    157     virtual void geolocationServicePositionChanged(GeolocationService*);
    158     virtual void geolocationServiceErrorOccurred(GeolocationService*);
    159 #endif
    160 
    161     PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
    162 
    163 // ANDROID
    164     // EventListener
    165     virtual bool operator==(const EventListener&);
    166     virtual void handleEvent(ScriptExecutionContext*, Event*);
    167 // END ANDROID
    168 
    169     void fatalErrorOccurred(GeoNotifier*);
    170     void requestTimedOut(GeoNotifier*);
    171     void requestUsesCachedPosition(GeoNotifier*);
    172     bool haveSuitableCachedPosition(PositionOptions*);
    173     void makeCachedPositionCallbacks();
    174 
    175     typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
    176 
    177     GeoNotifierSet m_oneShots;
    178     Watchers m_watchers;
    179     Frame* m_frame;
    180 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
    181     OwnPtr<GeolocationService> m_service;
    182 #else
    183     RefPtr<GeoNotifier> m_startRequestPermissionNotifier;
    184 #endif
    185     RefPtr<Geoposition> m_lastPosition;
    186     RefPtr<Geoposition> m_currentPosition;
    187 
    188     enum {
    189         Unknown,
    190         InProgress,
    191         Yes,
    192         No
    193     } m_allowGeolocation;
    194     bool m_shouldClearCache;
    195 
    196     OwnPtr<GeolocationPositionCache> m_positionCache;
    197     GeoNotifierSet m_requestsAwaitingCachedPosition;
    198 };
    199 
    200 } // namespace WebCore
    201 
    202 #endif // Geolocation_h
    203