2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved.
3 * Copyright 2010, The Android Open Source Project
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 #include "Geoposition.h"
31 #include "PositionCallback.h"
32 #include "PositionError.h"
33 #include "PositionErrorCallback.h"
34 #include "PositionOptions.h"
37 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
38 #include "GeolocationService.h"
44 #if ENABLE(CLIENT_BASED_GEOLOCATION)
45 class GeolocationPosition;
46 class GeolocationError;
50 class Geolocation : public RefCounted<Geolocation>
51 #if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
52 , public GeolocationServiceClient
56 static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
61 void disconnectFrame();
63 void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
64 int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
65 void clearWatch(int watchId);
67 void setIsAllowed(bool);
68 Frame* frame() const { return m_frame; }
70 #if ENABLE(CLIENT_BASED_GEOLOCATION)
71 void positionChanged();
72 void setError(GeolocationError*);
74 GeolocationService* getGeolocationService() const { return m_service.get(); }
78 Geoposition* lastPosition();
80 bool isAllowed() const { return m_allowGeolocation == Yes; }
81 bool isDenied() const { return m_allowGeolocation == No; }
87 class GeoNotifier : public RefCounted<GeoNotifier> {
89 static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
91 void setFatalError(PassRefPtr<PositionError>);
92 bool hasZeroTimeout() const;
93 void setUseCachedPosition();
94 void runSuccessCallback(Geoposition*);
95 void startTimerIfNeeded();
96 void timerFired(Timer<GeoNotifier>*);
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;
107 GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
110 typedef Vector<RefPtr<GeoNotifier> > GeoNotifierVector;
111 typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
115 void set(int id, PassRefPtr<GeoNotifier>);
116 GeoNotifier* find(int id);
118 void remove(GeoNotifier*);
119 bool contains(GeoNotifier*) const;
121 bool isEmpty() const;
122 void getNotifiersVector(GeoNotifierVector&) const;
124 typedef HashMap<int, RefPtr<GeoNotifier> > IdToNotifierMap;
125 typedef HashMap<RefPtr<GeoNotifier>, int> NotifierToIdMap;
126 IdToNotifierMap m_idToNotifierMap;
127 NotifierToIdMap m_notifierToIdMap;
130 bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
132 void sendError(GeoNotifierVector&, PositionError*);
133 void sendPosition(GeoNotifierVector&, Geoposition*);
135 static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached);
136 static void copyToSet(const GeoNotifierVector&, GeoNotifierSet&);
138 static void stopTimer(GeoNotifierVector&);
139 void stopTimersForOneShots();
140 void stopTimersForWatchers();
143 void cancelRequests(GeoNotifierVector&);
144 void cancelAllRequests();
146 void positionChangedInternal();
147 void makeSuccessCallbacks();
148 void handleError(PositionError*);
150 void requestPermission();
152 bool startUpdating(GeoNotifier*);
155 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
156 void handlePendingPermissionNotifiers();
159 #if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
160 // GeolocationServiceClient
161 virtual void geolocationServicePositionChanged(GeolocationService*);
162 virtual void geolocationServiceErrorOccurred(GeolocationService*);
165 PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
167 void fatalErrorOccurred(GeoNotifier*);
168 void requestTimedOut(GeoNotifier*);
169 void requestUsesCachedPosition(GeoNotifier*);
170 bool haveSuitableCachedPosition(PositionOptions*);
171 void makeCachedPositionCallbacks();
173 GeoNotifierSet m_oneShots;
176 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
177 OwnPtr<GeolocationService> m_service;
179 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
180 GeoNotifierSet m_pendingForPermissionNotifiers;
182 RefPtr<Geoposition> m_lastPosition;
189 } m_allowGeolocation;
191 #if ENABLE(GEOLOCATION)
192 RefPtr<Geoposition> m_cachedPosition;
194 GeoNotifierSet m_requestsAwaitingCachedPosition;
197 } // namespace WebCore
199 #endif // Geolocation_h