• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
create(Frame * frame)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);
isAllowed()83     bool isAllowed() const { return m_allowGeolocation == Yes; }
isDenied()84     bool isDenied() const { return m_allowGeolocation == No; }
85 
setShouldClearCache(bool shouldClearCache)86     void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = 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:
create(Geolocation * geolocation,PassRefPtr<PositionCallback> positionCallback,PassRefPtr<PositionErrorCallback> positionErrorCallback,PassRefPtr<PositionOptions> options)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 
hasListeners()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