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