• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "modules/geolocation/GeolocationController.h"
28 
29 #include "core/inspector/InspectorInstrumentation.h"
30 #include "modules/geolocation/GeolocationClient.h"
31 #include "modules/geolocation/GeolocationError.h"
32 #include "modules/geolocation/GeolocationPosition.h"
33 
34 namespace WebCore {
35 
GeolocationController(Page * page,GeolocationClient * client)36 GeolocationController::GeolocationController(Page* page, GeolocationClient* client)
37     : PageLifecycleObserver(page)
38     , m_client(client)
39     , m_isClientUpdating(false)
40 {
41 }
42 
startUpdatingIfNeeded()43 void GeolocationController::startUpdatingIfNeeded()
44 {
45     if (m_isClientUpdating)
46         return;
47     m_isClientUpdating = true;
48     m_client->startUpdating();
49 }
50 
stopUpdatingIfNeeded()51 void GeolocationController::stopUpdatingIfNeeded()
52 {
53     if (!m_isClientUpdating)
54         return;
55     m_isClientUpdating = false;
56     m_client->stopUpdating();
57 }
58 
~GeolocationController()59 GeolocationController::~GeolocationController()
60 {
61     ASSERT(m_observers.isEmpty());
62 
63     if (m_client)
64         m_client->geolocationDestroyed();
65 }
66 
create(Page * page,GeolocationClient * client)67 PassOwnPtr<GeolocationController> GeolocationController::create(Page* page, GeolocationClient* client)
68 {
69     return adoptPtr(new GeolocationController(page, client));
70 }
71 
addObserver(Geolocation * observer,bool enableHighAccuracy)72 void GeolocationController::addObserver(Geolocation* observer, bool enableHighAccuracy)
73 {
74     // This may be called multiple times with the same observer, though removeObserver()
75     // is called only once with each.
76     bool wasEmpty = m_observers.isEmpty();
77     m_observers.add(observer);
78     if (enableHighAccuracy)
79         m_highAccuracyObservers.add(observer);
80 
81     if (m_client) {
82         if (enableHighAccuracy)
83             m_client->setEnableHighAccuracy(true);
84         if (wasEmpty && page() && page()->visibilityState() == PageVisibilityStateVisible)
85             startUpdatingIfNeeded();
86     }
87 }
88 
removeObserver(Geolocation * observer)89 void GeolocationController::removeObserver(Geolocation* observer)
90 {
91     if (!m_observers.contains(observer))
92         return;
93 
94     m_observers.remove(observer);
95     m_highAccuracyObservers.remove(observer);
96 
97     if (m_client) {
98         if (m_observers.isEmpty())
99             stopUpdatingIfNeeded();
100         else if (m_highAccuracyObservers.isEmpty())
101             m_client->setEnableHighAccuracy(false);
102     }
103 }
104 
requestPermission(Geolocation * geolocation)105 void GeolocationController::requestPermission(Geolocation* geolocation)
106 {
107     if (m_client)
108         m_client->requestPermission(geolocation);
109 }
110 
cancelPermissionRequest(Geolocation * geolocation)111 void GeolocationController::cancelPermissionRequest(Geolocation* geolocation)
112 {
113     if (m_client)
114         m_client->cancelPermissionRequest(geolocation);
115 }
116 
positionChanged(GeolocationPosition * position)117 void GeolocationController::positionChanged(GeolocationPosition* position)
118 {
119     position = InspectorInstrumentation::overrideGeolocationPosition(page(), position);
120     if (!position) {
121         errorOccurred(GeolocationError::create(GeolocationError::PositionUnavailable, "PositionUnavailable").get());
122         return;
123     }
124     m_lastPosition = position;
125     Vector<RefPtr<Geolocation> > observersVector;
126     copyToVector(m_observers, observersVector);
127     for (size_t i = 0; i < observersVector.size(); ++i)
128         observersVector[i]->positionChanged();
129 }
130 
errorOccurred(GeolocationError * error)131 void GeolocationController::errorOccurred(GeolocationError* error)
132 {
133     Vector<RefPtr<Geolocation> > observersVector;
134     copyToVector(m_observers, observersVector);
135     for (size_t i = 0; i < observersVector.size(); ++i)
136         observersVector[i]->setError(error);
137 }
138 
lastPosition()139 GeolocationPosition* GeolocationController::lastPosition()
140 {
141     if (m_lastPosition.get())
142         return m_lastPosition.get();
143 
144     if (!m_client)
145         return 0;
146 
147     return m_client->lastPosition();
148 }
149 
pageVisibilityChanged()150 void GeolocationController::pageVisibilityChanged()
151 {
152     if (m_observers.isEmpty() || !m_client)
153         return;
154 
155     if (page() && page()->visibilityState() == PageVisibilityStateVisible)
156         startUpdatingIfNeeded();
157     else
158         stopUpdatingIfNeeded();
159 }
160 
supplementName()161 const char* GeolocationController::supplementName()
162 {
163     return "GeolocationController";
164 }
165 
provideGeolocationTo(Page * page,GeolocationClient * client)166 void provideGeolocationTo(Page* page, GeolocationClient* client)
167 {
168     Supplement<Page>::provideTo(page, GeolocationController::supplementName(), GeolocationController::create(page, client));
169 }
170 
171 } // namespace WebCore
172