2 * Copyright (C) 2008, 2009 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 "GeolocationPositionCache.h"
31 #include "Geoposition.h"
32 #include "PositionCallback.h"
33 #include "PositionError.h"
34 #include "PositionErrorCallback.h"
35 #include "PositionOptions.h"
38 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
39 #include "GeolocationService.h"
46 #if ENABLE(CLIENT_BASED_GEOLOCATION)
47 class GeolocationPosition;
48 class GeolocationError;
51 class Geolocation : public RefCounted<Geolocation>
52 #if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
53 , public GeolocationServiceClient
57 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 // These methods are used by Android.
71 void setIsAllowed(bool);
72 Frame* frame() const { return m_frame; }
74 #if ENABLE(CLIENT_BASED_GEOLOCATION)
75 void positionChanged();
76 void setError(GeolocationError*);
78 GeolocationService* getGeolocationService() const { return m_service.get(); }
82 Geoposition* lastPosition();
84 bool isAllowed() const { return m_allowGeolocation == Yes; }
85 bool isDenied() const { return m_allowGeolocation == No; }
89 class GeoNotifier : public RefCounted<GeoNotifier> {
91 static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
93 void setFatalError(PassRefPtr<PositionError>);
94 bool hasZeroTimeout() const;
95 void setUseCachedPosition();
96 void runSuccessCallback(Geoposition*);
97 void startTimerIfNeeded();
98 void timerFired(Timer<GeoNotifier>*);
100 Geolocation* m_geolocation;
101 RefPtr<PositionCallback> m_successCallback;
102 RefPtr<PositionErrorCallback> m_errorCallback;
103 RefPtr<PositionOptions> m_options;
104 Timer<GeoNotifier> m_timer;
105 RefPtr<PositionError> m_fatalError;
106 bool m_useCachedPosition;
109 GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
112 typedef Vector<RefPtr<GeoNotifier> > GeoNotifierVector;
113 typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
117 void set(int id, PassRefPtr<GeoNotifier>);
119 void remove(GeoNotifier*);
120 bool contains(GeoNotifier*) const;
122 bool isEmpty() const;
123 void getNotifiersVector(GeoNotifierVector&) const;
125 typedef HashMap<int, RefPtr<GeoNotifier> > IdToNotifierMap;
126 typedef HashMap<RefPtr<GeoNotifier>, int> NotifierToIdMap;
127 IdToNotifierMap m_idToNotifierMap;
128 NotifierToIdMap m_notifierToIdMap;
131 bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
133 void sendError(GeoNotifierVector&, PositionError*);
134 void sendPosition(GeoNotifierVector&, Geoposition*);
136 static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached);
137 static void copyToSet(const GeoNotifierVector&, GeoNotifierSet&);
139 static void stopTimer(GeoNotifierVector&);
140 void stopTimersForOneShots();
141 void stopTimersForWatchers();
144 void cancelRequests(GeoNotifierVector&);
145 void cancelAllRequests();
147 void positionChangedInternal();
148 void makeSuccessCallbacks();
149 void handleError(PositionError*);
151 void requestPermission();
153 bool startUpdating(GeoNotifier*);
156 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
157 void handlePendingPermissionNotifiers();
160 #if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
161 // GeolocationServiceClient
162 virtual void geolocationServicePositionChanged(GeolocationService*);
163 virtual void geolocationServiceErrorOccurred(GeolocationService*);
166 PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
168 void fatalErrorOccurred(GeoNotifier*);
169 void requestTimedOut(GeoNotifier*);
170 void requestUsesCachedPosition(GeoNotifier*);
171 bool haveSuitableCachedPosition(PositionOptions*);
172 void makeCachedPositionCallbacks();
174 GeoNotifierSet m_oneShots;
177 #if !ENABLE(CLIENT_BASED_GEOLOCATION)
178 OwnPtr<GeolocationService> m_service;
180 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
181 GeoNotifierSet m_pendingForPermissionNotifiers;
183 RefPtr<Geoposition> m_lastPosition;
190 } m_allowGeolocation;
192 #if ENABLE(GEOLOCATION)
193 OwnPtr<GeolocationPositionCache> m_positionCache;
195 GeoNotifierSet m_requestsAwaitingCachedPosition;
198 } // namespace WebCore
200 #endif // Geolocation_h