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