tizen beta release
[framework/web/webkit-efl.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     void setIsAllowed(bool);
68     Frame* frame() const { return m_frame; }
69
70 #if ENABLE(CLIENT_BASED_GEOLOCATION)
71     void positionChanged();
72     void setError(GeolocationError*);
73 #else
74     GeolocationService* getGeolocationService() const { return m_service.get(); }
75 #endif
76
77 private:
78     Geoposition* lastPosition();
79
80     bool isAllowed() const { return m_allowGeolocation == Yes; }
81     bool isDenied() const { return m_allowGeolocation == No; }
82     
83     Geolocation(Frame*);
84
85     Page* page() const;
86
87     class GeoNotifier : public RefCounted<GeoNotifier> {
88     public:
89         static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
90         
91         void setFatalError(PassRefPtr<PositionError>);
92         bool hasZeroTimeout() const;
93         void setUseCachedPosition();
94         void runSuccessCallback(Geoposition*);
95         void startTimerIfNeeded();
96         void timerFired(Timer<GeoNotifier>*);
97         
98         RefPtr<Geolocation> m_geolocation;
99         RefPtr<PositionCallback> m_successCallback;
100         RefPtr<PositionErrorCallback> m_errorCallback;
101         RefPtr<PositionOptions> m_options;
102         Timer<GeoNotifier> m_timer;
103         RefPtr<PositionError> m_fatalError;
104         bool m_useCachedPosition;
105
106     private:
107         GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
108     };
109
110     typedef Vector<RefPtr<GeoNotifier> > GeoNotifierVector;
111     typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
112
113     class Watchers {
114     public:
115         void set(int id, PassRefPtr<GeoNotifier>);
116         GeoNotifier* find(int id);
117         void remove(int id);
118         void remove(GeoNotifier*);
119         bool contains(GeoNotifier*) const;
120         void clear();
121         bool isEmpty() const;
122         void getNotifiersVector(GeoNotifierVector&) const;
123     private:
124         typedef HashMap<int, RefPtr<GeoNotifier> > IdToNotifierMap;
125         typedef HashMap<RefPtr<GeoNotifier>, int> NotifierToIdMap;
126         IdToNotifierMap m_idToNotifierMap;
127         NotifierToIdMap m_notifierToIdMap;
128     };
129
130     bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
131
132     void sendError(GeoNotifierVector&, PositionError*);
133     void sendPosition(GeoNotifierVector&, Geoposition*);
134
135     static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached);
136     static void copyToSet(const GeoNotifierVector&, GeoNotifierSet&);
137
138     static void stopTimer(GeoNotifierVector&);
139     void stopTimersForOneShots();
140     void stopTimersForWatchers();
141     void stopTimers();
142
143     void cancelRequests(GeoNotifierVector&);
144     void cancelAllRequests();
145
146     void positionChangedInternal();
147     void makeSuccessCallbacks();
148     void handleError(PositionError*);
149
150     void requestPermission();
151
152     bool startUpdating(GeoNotifier*);
153     void stopUpdating();
154
155 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
156     void handlePendingPermissionNotifiers();
157 #endif
158
159 #if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
160     // GeolocationServiceClient
161     virtual void geolocationServicePositionChanged(GeolocationService*);
162     virtual void geolocationServiceErrorOccurred(GeolocationService*);
163 #endif
164
165     PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
166
167     void fatalErrorOccurred(GeoNotifier*);
168     void requestTimedOut(GeoNotifier*);
169     void requestUsesCachedPosition(GeoNotifier*);
170     bool haveSuitableCachedPosition(PositionOptions*);
171     void makeCachedPositionCallbacks();
172
173     GeoNotifierSet m_oneShots;
174     Watchers m_watchers;
175     Frame* m_frame;
176 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
177     OwnPtr<GeolocationService> m_service;
178 #endif
179 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
180     GeoNotifierSet m_pendingForPermissionNotifiers;
181 #endif
182     RefPtr<Geoposition> m_lastPosition;
183
184     enum {
185         Unknown,
186         InProgress,
187         Yes,
188         No
189     } m_allowGeolocation;
190
191 #if ENABLE(GEOLOCATION)
192     RefPtr<Geoposition> m_cachedPosition;
193 #endif
194     GeoNotifierSet m_requestsAwaitingCachedPosition;
195 };
196     
197 } // namespace WebCore
198
199 #endif // Geolocation_h
200