1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Apple Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "config.h"
33#include "GeolocationClientMock.h"
34
35#if ENABLE(GEOLOCATION)
36
37#include "GeolocationController.h"
38#include "GeolocationError.h"
39#include "GeolocationPosition.h"
40
41namespace WebCore {
42
43GeolocationClientMock::GeolocationClientMock()
44 : m_controller(0)
45 , m_hasError(false)
46 , m_controllerTimer(*this, &GeolocationClientMock::controllerTimerFired)
47 , m_permissionTimer(*this, &GeolocationClientMock::permissionTimerFired)
48 , m_isActive(false)
49 , m_permissionState(PermissionStateUnset)
50{
51}
52
53GeolocationClientMock::~GeolocationClientMock()
54{
55 ASSERT(!m_isActive);
56}
57
58void GeolocationClientMock::setController(GeolocationController *controller)
59{
60 ASSERT(controller && !m_controller);
61 m_controller = controller;
62}
63
64void GeolocationClientMock::setPosition(GeolocationPosition&& position)
65{
66 m_lastPosition = WTFMove(position);
67 clearError();
68 asyncUpdateController();
69}
70
71void GeolocationClientMock::setPositionUnavailableError(const String& errorMessage)
72{
73 m_hasError = true;
74 m_errorMessage = errorMessage;
75 m_lastPosition = WTF::nullopt;
76 asyncUpdateController();
77}
78
79void GeolocationClientMock::setPermission(bool allowed)
80{
81 m_permissionState = allowed ? PermissionStateAllowed : PermissionStateDenied;
82 asyncUpdatePermission();
83}
84
85int GeolocationClientMock::numberOfPendingPermissionRequests() const
86{
87 return m_pendingPermission.size();
88}
89
90void GeolocationClientMock::requestPermission(Geolocation& geolocation)
91{
92 m_pendingPermission.add(&geolocation);
93 if (m_permissionState != PermissionStateUnset)
94 asyncUpdatePermission();
95}
96
97void GeolocationClientMock::cancelPermissionRequest(Geolocation& geolocation)
98{
99 // Called from Geolocation::disconnectFrame() in response to Frame destruction.
100 m_pendingPermission.remove(&geolocation);
101 if (m_pendingPermission.isEmpty() && m_permissionTimer.isActive())
102 m_permissionTimer.stop();
103}
104
105void GeolocationClientMock::asyncUpdatePermission()
106{
107 ASSERT(m_permissionState != PermissionStateUnset);
108 if (!m_permissionTimer.isActive())
109 m_permissionTimer.startOneShot(0_s);
110}
111
112void GeolocationClientMock::permissionTimerFired()
113{
114 ASSERT(m_permissionState != PermissionStateUnset);
115 bool allowed = m_permissionState == PermissionStateAllowed;
116 GeolocationSet::iterator end = m_pendingPermission.end();
117
118 // Once permission has been set (or denied) on a Geolocation object, there can be
119 // no further requests for permission to the mock. Consequently the callbacks
120 // which fire synchronously from Geolocation::setIsAllowed() cannot reentrantly modify
121 // m_pendingPermission.
122 for (GeolocationSet::iterator it = m_pendingPermission.begin(); it != end; ++it)
123 (*it)->setIsAllowed(allowed);
124 m_pendingPermission.clear();
125}
126
127void GeolocationClientMock::reset()
128{
129 m_lastPosition = WTF::nullopt;
130 clearError();
131 m_permissionState = PermissionStateUnset;
132}
133
134void GeolocationClientMock::geolocationDestroyed()
135{
136 ASSERT(!m_isActive);
137}
138
139void GeolocationClientMock::startUpdating()
140{
141 ASSERT(!m_isActive);
142 m_isActive = true;
143 asyncUpdateController();
144}
145
146void GeolocationClientMock::stopUpdating()
147{
148 ASSERT(m_isActive);
149 m_isActive = false;
150 m_controllerTimer.stop();
151}
152
153void GeolocationClientMock::setEnableHighAccuracy(bool)
154{
155 // FIXME: We need to add some tests regarding "high accuracy" mode.
156 // See https://bugs.webkit.org/show_bug.cgi?id=49438
157}
158
159Optional<GeolocationPosition> GeolocationClientMock::lastPosition()
160{
161 return m_lastPosition;
162}
163
164void GeolocationClientMock::asyncUpdateController()
165{
166 ASSERT(m_controller);
167 if (m_isActive && !m_controllerTimer.isActive())
168 m_controllerTimer.startOneShot(0_s);
169}
170
171void GeolocationClientMock::controllerTimerFired()
172{
173 ASSERT(m_controller);
174
175 if (m_lastPosition) {
176 ASSERT(!m_hasError);
177 m_controller->positionChanged(*m_lastPosition);
178 } else if (m_hasError) {
179 auto geolocatioError = GeolocationError::create(GeolocationError::PositionUnavailable, m_errorMessage);
180 m_controller->errorOccurred(geolocatioError.get());
181 }
182}
183
184void GeolocationClientMock::clearError()
185{
186 m_hasError = false;
187 m_errorMessage = String();
188}
189
190} // WebCore
191
192#endif // ENABLE(GEOLOCATION)
193