Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / geolocation / 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 "bindings/v8/ScriptWrappable.h"
31 #include "core/dom/ActiveDOMObject.h"
32 #include "modules/geolocation/Geoposition.h"
33 #include "modules/geolocation/PositionCallback.h"
34 #include "modules/geolocation/PositionError.h"
35 #include "modules/geolocation/PositionErrorCallback.h"
36 #include "modules/geolocation/PositionOptions.h"
37 #include "platform/Timer.h"
38 #include "platform/heap/Handle.h"
39
40 namespace WebCore {
41
42 class Document;
43 class LocalFrame;
44 class GeolocationController;
45 class GeolocationError;
46 class GeolocationPosition;
47 class Page;
48 class ExecutionContext;
49
50 class Geolocation FINAL : public RefCountedWillBeGarbageCollectedFinalized<Geolocation>, public ScriptWrappable, public ActiveDOMObject
51 {
52 public:
53     static PassRefPtrWillBeRawPtr<Geolocation> create(ExecutionContext*);
54     virtual ~Geolocation();
55     void trace(Visitor*);
56
57     virtual void stop() OVERRIDE;
58     Document* document() const;
59     LocalFrame* frame() const;
60
61     // Creates a oneshot and attempts to obtain a position that meets the
62     // constraints of the options.
63     void getCurrentPosition(PassOwnPtr<PositionCallback>, PassOwnPtr<PositionErrorCallback>, PassRefPtrWillBeRawPtr<PositionOptions>);
64
65     // Creates a watcher that will be notified whenever a new position is
66     // available that meets the constraints of the options.
67     int watchPosition(PassOwnPtr<PositionCallback>, PassOwnPtr<PositionErrorCallback>, PassRefPtrWillBeRawPtr<PositionOptions>);
68
69     // Removes all references to the watcher, it will not be updated again.
70     void clearWatch(int watchID);
71
72     void setIsAllowed(bool);
73
74     bool isAllowed() const { return m_allowGeolocation == Yes; }
75
76     // Notifies this that a new position is available. Must never be called
77     // before permission is granted by the user.
78     void positionChanged();
79
80     // Notifies this that an error has occurred, it must be handled immediately.
81     void setError(GeolocationError*);
82
83 private:
84     // Returns the last known position, if any. May return null.
85     Geoposition* lastPosition();
86
87     bool isDenied() const { return m_allowGeolocation == No; }
88
89     explicit Geolocation(ExecutionContext*);
90
91     Page* page() const;
92
93     // Holds the success and error callbacks and the options that were provided
94     // when a oneshot or watcher were created. Also, if specified in the
95     // options, manages a timer to limit the time to wait for the system to
96     // obtain a position.
97     class GeoNotifier : public RefCountedWillBeGarbageCollectedFinalized<GeoNotifier> {
98     public:
99         static PassRefPtrWillBeRawPtr<GeoNotifier> create(Geolocation* geolocation, PassOwnPtr<PositionCallback> positionCallback, PassOwnPtr<PositionErrorCallback> positionErrorCallback, PassRefPtrWillBeRawPtr<PositionOptions> options)
100         {
101             return adoptRefWillBeNoop(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options));
102         }
103         void trace(Visitor*);
104
105         PositionOptions* options() const { return m_options.get(); };
106
107         // Sets the given error as the fatal error if there isn't one yet.
108         // Starts the timer with an interval of 0.
109         void setFatalError(PassRefPtrWillBeRawPtr<PositionError>);
110
111         bool useCachedPosition() const { return m_useCachedPosition; }
112
113         // Tells the notifier to use a cached position and starts its timer with
114         // an interval of 0.
115         void setUseCachedPosition();
116
117         void runSuccessCallback(Geoposition*);
118         void runErrorCallback(PositionError*);
119
120         // Starts the timer if a timeout was specified on the options.
121         void startTimerIfNeeded();
122
123         void stopTimer();
124
125         // Runs the error callback if there is a fatal error. Otherwise, if a
126         // cached position must be used, registers itself for receiving one.
127         // Otherwise, the notifier has expired, and its error callback is run.
128         void timerFired(Timer<GeoNotifier>*);
129
130         bool hasZeroTimeout() const;
131
132     private:
133         GeoNotifier(Geolocation*, PassOwnPtr<PositionCallback>, PassOwnPtr<PositionErrorCallback>, PassRefPtrWillBeRawPtr<PositionOptions>);
134
135         RefPtrWillBeMember<Geolocation> m_geolocation;
136         OwnPtr<PositionCallback> m_successCallback;
137         OwnPtr<PositionErrorCallback> m_errorCallback;
138         RefPtrWillBeMember<PositionOptions> m_options;
139         Timer<GeoNotifier> m_timer;
140         RefPtrWillBeMember<PositionError> m_fatalError;
141         bool m_useCachedPosition;
142     };
143
144     typedef WillBeHeapVector<RefPtrWillBeMember<GeoNotifier> > GeoNotifierVector;
145     typedef WillBeHeapHashSet<RefPtrWillBeMember<GeoNotifier> > GeoNotifierSet;
146
147     class Watchers {
148         DISALLOW_ALLOCATION();
149     public:
150         void trace(Visitor*);
151         bool add(int id, PassRefPtrWillBeRawPtr<GeoNotifier>);
152         GeoNotifier* find(int id);
153         void remove(int id);
154         void remove(GeoNotifier*);
155         bool contains(GeoNotifier*) const;
156         void clear();
157         bool isEmpty() const;
158         void getNotifiersVector(GeoNotifierVector&) const;
159     private:
160         typedef WillBeHeapHashMap<int, RefPtrWillBeMember<GeoNotifier> > IdToNotifierMap;
161         typedef WillBeHeapHashMap<RefPtrWillBeMember<GeoNotifier>, int> NotifierToIdMap;
162         IdToNotifierMap m_idToNotifierMap;
163         NotifierToIdMap m_notifierToIdMap;
164     };
165
166     bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
167
168     void sendError(GeoNotifierVector&, PositionError*);
169     void sendPosition(GeoNotifierVector&, Geoposition*);
170
171     // Removes notifiers that use a cached position from |notifiers| and
172     // if |cached| is not null they are added to it.
173     static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached);
174
175     // Copies notifiers from |src| vector to |dest| set.
176     static void copyToSet(const GeoNotifierVector& src, GeoNotifierSet& dest);
177
178     static void stopTimer(GeoNotifierVector&);
179     void stopTimersForOneShots();
180     void stopTimersForWatchers();
181     void stopTimers();
182
183     // Sets a fatal error on the given notifiers.
184     void cancelRequests(GeoNotifierVector&);
185
186     // Sets a fatal error on all notifiers.
187     void cancelAllRequests();
188
189     // Runs the success callbacks on all notifiers. A position must be available
190     // and the user must have given permission.
191     void makeSuccessCallbacks();
192
193     // Sends the given error to all notifiers, unless the error is not fatal and
194     // the notifier is due to receive a cached position. Clears the oneshots,
195     // and also  clears the watchers if the error is fatal.
196     void handleError(PositionError*);
197
198     // Requests permission to share positions with the page.
199     void requestPermission();
200
201     // Attempts to register this with the controller for receiving updates.
202     // Returns false if there is no controller to register with.
203     bool startUpdating(GeoNotifier*);
204
205     void stopUpdating();
206
207     // Processes the notifiers that were waiting for a permission decision. If
208     // granted and this can be registered with the controller then the
209     // notifier's timers are started. Otherwise, a fatal error is set on them.
210     void handlePendingPermissionNotifiers();
211
212     // Attempts to obtain a position for the given notifier, either by using
213     // the cached position or by requesting one from the controller. Sets a
214     // fatal error if permission is denied or no position can be obtained.
215     void startRequest(GeoNotifier*);
216
217     // Discards the notifier because a fatal error occurred for it.
218     void fatalErrorOccurred(GeoNotifier*);
219
220     // Discards the notifier if it is a oneshot because it timed it.
221     void requestTimedOut(GeoNotifier*);
222
223     // Adds the notifier to the set awaiting a cached position. Runs the success
224     // callbacks for them if permission has been granted. Requests permission if
225     // it is unknown.
226     void requestUsesCachedPosition(GeoNotifier*);
227
228     bool haveSuitableCachedPosition(PositionOptions*);
229
230     // Runs the success callbacks for the set of notifiers awaiting a cached
231     // position, the set is then cleared. The oneshots are removed everywhere.
232     void makeCachedPositionCallbacks();
233
234     GeoNotifierSet m_oneShots;
235     Watchers m_watchers;
236     GeoNotifierSet m_pendingForPermissionNotifiers;
237     RefPtrWillBeMember<Geoposition> m_lastPosition;
238
239     enum {
240         Unknown,
241         InProgress,
242         Yes,
243         No
244     } m_allowGeolocation;
245
246     GeoNotifierSet m_requestsAwaitingCachedPosition;
247 };
248
249 } // namespace WebCore
250
251 #endif // Geolocation_h