| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Apple Inc. All Rights Reserved. | 3 * Copyright (C) 2012 Apple Inc. All Rights Reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 #include "config.h" | 32 #include "config.h" |
| 33 #include "GeolocationClientMock.h" | 33 #include "GeolocationClientMock.h" |
| 34 | 34 |
| 35 #include "core/dom/Document.h" |
| 35 #include "modules/geolocation/GeolocationController.h" | 36 #include "modules/geolocation/GeolocationController.h" |
| 36 #include "modules/geolocation/GeolocationError.h" | 37 #include "modules/geolocation/GeolocationError.h" |
| 37 #include "modules/geolocation/GeolocationPosition.h" | 38 #include "modules/geolocation/GeolocationPosition.h" |
| 38 | 39 |
| 39 namespace blink { | 40 namespace blink { |
| 40 | 41 |
| 41 GeolocationClientMock::GeolocationClientMock() | 42 GeolocationClientMock* GeolocationClientMock::from(Document* document) |
| 42 : m_hasError(false) | |
| 43 , m_controllerTimer(this, &GeolocationClientMock::controllerTimerFired) | |
| 44 , m_permissionTimer(this, &GeolocationClientMock::permissionTimerFired) | |
| 45 , m_isActive(false) | |
| 46 , m_permissionState(PermissionStateUnset) | |
| 47 { | 43 { |
| 44 GeolocationClientMock* supplement = static_cast<GeolocationClientMock*>(Will
BeHeapSupplement<Document>::from(*document, supplementName())); |
| 45 if (!supplement) { |
| 46 supplement = new GeolocationClientMock(document); |
| 47 WillBeHeapSupplement<Document>::provideTo(*document, supplementName(), a
doptPtrWillBeNoop(supplement)); |
| 48 document->setServiceProvider(supplement); |
| 49 } |
| 50 return supplement; |
| 51 } |
| 52 |
| 53 GeolocationClientMock::GeolocationClientMock(Document* document) |
| 54 : m_document(document) |
| 55 , m_permissionState(content::PERMISSION_STATUS_ASK) |
| 56 , m_geolocationBinding(this) |
| 57 , m_permissionBinding(this) |
| 58 { |
| 59 m_document->setServiceProvider(this); |
| 48 } | 60 } |
| 49 | 61 |
| 50 GeolocationClientMock::~GeolocationClientMock() | 62 GeolocationClientMock::~GeolocationClientMock() |
| 51 { | 63 { |
| 52 ASSERT(!m_isActive); | 64 if (m_document->serviceProvider() == this) |
| 65 m_document->setServiceProvider(nullptr); |
| 53 } | 66 } |
| 54 | 67 |
| 55 void GeolocationClientMock::setPosition(GeolocationPosition* position) | 68 void GeolocationClientMock::setPosition(GeolocationPosition* position) |
| 56 { | 69 { |
| 57 m_lastPosition = position; | 70 m_lastPosition = content::MojoGeoposition::New(); |
| 58 clearError(); | 71 m_lastPosition->latitude = position->latitude(); |
| 59 asyncUpdateController(); | 72 m_lastPosition->longitude = position->longitude(); |
| 73 m_lastPosition->altitude = position->canProvideAltitude() ? position->altitu
de() : -10000.; |
| 74 m_lastPosition->accuracy = position->accuracy(); |
| 75 m_lastPosition->altitude_accuracy = position->canProvideAltitudeAccuracy() ?
position->altitudeAccuracy() : -1; |
| 76 m_lastPosition->heading = position->canProvideHeading() ? position->heading(
) : -1; |
| 77 m_lastPosition->speed = position->canProvideSpeed() ? position->speed() : -1
; |
| 78 m_lastPosition->timestamp = position->timestamp(); |
| 79 m_lastPosition->error_message = ""; |
| 80 m_lastPosition->valid = true; |
| 81 runGeolocationCallbacks(); |
| 60 } | 82 } |
| 61 | 83 |
| 62 void GeolocationClientMock::setPositionUnavailableError(const String& errorMessa
ge) | 84 void GeolocationClientMock::setPositionUnavailableError(const String& errorMessa
ge) |
| 63 { | 85 { |
| 64 m_hasError = true; | 86 m_lastPosition = content::MojoGeoposition::New(); |
| 65 m_errorMessage = errorMessage; | 87 m_lastPosition->error_code = content::MojoGeoposition::ERROR_CODE_ERROR_CODE
_POSITION_UNAVAILABLE; |
| 66 m_lastPosition = nullptr; | 88 m_lastPosition->error_message = errorMessage.utf8().data(); |
| 67 asyncUpdateController(); | 89 runGeolocationCallbacks(); |
| 68 } | 90 } |
| 69 | 91 |
| 70 void GeolocationClientMock::setPermission(bool allowed) | 92 void GeolocationClientMock::setPermission(bool allowed) |
| 71 { | 93 { |
| 72 m_permissionState = allowed ? PermissionStateAllowed : PermissionStateDenied
; | 94 m_permissionState = allowed ? content::PERMISSION_STATUS_GRANTED : content::
PERMISSION_STATUS_DENIED; |
| 73 asyncUpdatePermission(); | 95 runPermissionCallbacks(); |
| 74 } | 96 } |
| 75 | 97 |
| 76 int GeolocationClientMock::numberOfPendingPermissionRequests() const | 98 int GeolocationClientMock::numberOfPendingPermissionRequests() const |
| 77 { | 99 { |
| 78 return m_pendingPermissions.size(); | 100 return m_pendingPermissions.size(); |
| 79 } | 101 } |
| 80 | 102 |
| 81 void GeolocationClientMock::requestPermission(Geolocation* geolocation) | 103 void GeolocationClientMock::SetHighAccuracy(bool highAccuracy) |
| 82 { | |
| 83 m_pendingPermissions.add(geolocation); | |
| 84 if (m_permissionState != PermissionStateUnset) | |
| 85 asyncUpdatePermission(); | |
| 86 } | |
| 87 | |
| 88 void GeolocationClientMock::cancelPermissionRequest(Geolocation* geolocation) | |
| 89 { | |
| 90 // Called from Geolocation::disconnectFrame() in response to LocalFrame dest
ruction. | |
| 91 m_pendingPermissions.remove(geolocation); | |
| 92 if (m_pendingPermissions.isEmpty() && m_permissionTimer.isActive()) | |
| 93 m_permissionTimer.stop(); | |
| 94 } | |
| 95 | |
| 96 void GeolocationClientMock::controllerForTestAdded(GeolocationController* contro
ller) | |
| 97 { | |
| 98 m_controllers.add(controller); | |
| 99 } | |
| 100 | |
| 101 void GeolocationClientMock::controllerForTestRemoved(GeolocationController* cont
roller) | |
| 102 { | |
| 103 m_controllers.remove(controller); | |
| 104 } | |
| 105 | |
| 106 void GeolocationClientMock::asyncUpdatePermission() | |
| 107 { | |
| 108 ASSERT(m_permissionState != PermissionStateUnset); | |
| 109 if (!m_permissionTimer.isActive()) | |
| 110 m_permissionTimer.startOneShot(0, FROM_HERE); | |
| 111 } | |
| 112 | |
| 113 void GeolocationClientMock::permissionTimerFired(Timer<GeolocationClientMock>* t
imer) | |
| 114 { | |
| 115 ASSERT_UNUSED(timer, timer == &m_permissionTimer); | |
| 116 ASSERT(m_permissionState != PermissionStateUnset); | |
| 117 bool allowed = m_permissionState == PermissionStateAllowed; | |
| 118 GeolocationSet::iterator end = m_pendingPermissions.end(); | |
| 119 | |
| 120 // Once permission has been set (or denied) on a Geolocation object, there c
an be | |
| 121 // no further requests for permission to the mock. Consequently the callback
s | |
| 122 // which fire synchronously from Geolocation::setIsAllowed() cannot reentran
tly modify | |
| 123 // m_pendingPermissions. | |
| 124 for (GeolocationSet::iterator it = m_pendingPermissions.begin(); it != end;
++it) | |
| 125 (*it)->setIsAllowed(allowed); | |
| 126 m_pendingPermissions.clear(); | |
| 127 } | |
| 128 | |
| 129 void GeolocationClientMock::startUpdating() | |
| 130 { | |
| 131 ASSERT(!m_isActive); | |
| 132 m_isActive = true; | |
| 133 asyncUpdateController(); | |
| 134 } | |
| 135 | |
| 136 void GeolocationClientMock::stopUpdating() | |
| 137 { | |
| 138 ASSERT(m_isActive); | |
| 139 m_isActive = false; | |
| 140 m_controllerTimer.stop(); | |
| 141 } | |
| 142 | |
| 143 void GeolocationClientMock::setEnableHighAccuracy(bool) | |
| 144 { | 104 { |
| 145 // FIXME: We need to add some tests regarding "high accuracy" mode. | 105 // FIXME: We need to add some tests regarding "high accuracy" mode. |
| 146 // See https://bugs.webkit.org/show_bug.cgi?id=49438 | 106 // See https://bugs.webkit.org/show_bug.cgi?id=49438 |
| 147 } | 107 } |
| 148 | 108 |
| 149 GeolocationPosition* GeolocationClientMock::lastPosition() | 109 void GeolocationClientMock::QueryNextPosition(const QueryNextPositionCallback& c
allback) |
| 150 { | 110 { |
| 151 return m_lastPosition.get(); | 111 m_pendingGeolocations.append(callback); |
| 112 runGeolocationCallbacks(); |
| 152 } | 113 } |
| 153 | 114 |
| 154 void GeolocationClientMock::asyncUpdateController() | 115 void GeolocationClientMock::HasPermission(content::PermissionName permission, |
| 116 const mojo::String& origin, |
| 117 const HasPermissionCallback& callback) |
| 155 { | 118 { |
| 156 if (m_isActive && !m_controllerTimer.isActive()) | 119 callback.Run(content::PERMISSION_STATUS_ASK); |
| 157 m_controllerTimer.startOneShot(0, FROM_HERE); | |
| 158 } | 120 } |
| 159 | 121 |
| 160 void GeolocationClientMock::controllerTimerFired(Timer<GeolocationClientMock>* t
imer) | 122 void GeolocationClientMock::RequestPermission(content::PermissionName permission
, |
| 123 const mojo::String& origin, |
| 124 bool userGesture, |
| 125 const RequestPermissionCallback& callback) |
| 161 { | 126 { |
| 162 ASSERT_UNUSED(timer, timer == &m_controllerTimer); | 127 m_pendingPermissions.append(callback); |
| 163 | 128 runPermissionCallbacks(); |
| 164 // Make a copy of the set of controllers since it might be modified while it
erating. | |
| 165 GeolocationControllers controllers = m_controllers; | |
| 166 if (m_lastPosition.get()) { | |
| 167 ASSERT(!m_hasError); | |
| 168 for (GeolocationControllers::iterator it = controllers.begin(); it != co
ntrollers.end(); ++it) | |
| 169 (*it)->positionChanged(m_lastPosition.get()); | |
| 170 } else if (m_hasError) { | |
| 171 for (GeolocationControllers::iterator it = controllers.begin(); it != co
ntrollers.end(); ++it) | |
| 172 (*it)->errorOccurred(GeolocationError::create(GeolocationError::Posi
tionUnavailable, m_errorMessage)); | |
| 173 } | |
| 174 } | 129 } |
| 175 | 130 |
| 176 void GeolocationClientMock::clearError() | 131 void GeolocationClientMock::RequestPermissions(mojo::Array<content::PermissionNa
me> permissions, |
| 132 const mojo::String& origin, |
| 133 bool userGesture, |
| 134 const RequestPermissionsCallback& callback) |
| 177 { | 135 { |
| 178 m_hasError = false; | 136 } |
| 179 m_errorMessage = String(); | 137 |
| 138 void GeolocationClientMock::RevokePermission(content::PermissionName permission, |
| 139 const mojo::String& origin, |
| 140 const RevokePermissionCallback& callback) |
| 141 { |
| 142 } |
| 143 |
| 144 void GeolocationClientMock::GetNextPermissionChange( |
| 145 content::PermissionName permission, |
| 146 const mojo::String& origin, |
| 147 content::PermissionStatus lastKnownStatus, |
| 148 const GetNextPermissionChangeCallback& callback) |
| 149 { |
| 150 } |
| 151 |
| 152 void GeolocationClientMock::ConnectToService(const mojo::String& interfaceName,
mojo::ScopedMessagePipeHandle pipe) |
| 153 { |
| 154 if (interfaceName == content::GeolocationService::Name_) |
| 155 m_geolocationBinding.Bind(pipe.Pass()); |
| 156 else if (interfaceName == content::PermissionService::Name_) |
| 157 m_permissionBinding.Bind(pipe.Pass()); |
| 158 } |
| 159 |
| 160 void GeolocationClientMock::runGeolocationCallbacks() |
| 161 { |
| 162 if (m_pendingGeolocations.isEmpty() || !m_lastPosition) |
| 163 return; |
| 164 |
| 165 for (const auto& callback : m_pendingGeolocations) |
| 166 callback.Run(m_lastPosition.Clone()); |
| 167 m_pendingGeolocations.clear(); |
| 168 m_lastPosition = nullptr; |
| 169 } |
| 170 |
| 171 void GeolocationClientMock::runPermissionCallbacks() |
| 172 { |
| 173 if (m_pendingPermissions.isEmpty() || m_permissionState == content::PERMISSI
ON_STATUS_ASK) |
| 174 return; |
| 175 |
| 176 for (const auto& pendingPermission : m_pendingPermissions) |
| 177 pendingPermission.Run(m_permissionState); |
| 178 m_permissionState = content::PERMISSION_STATUS_ASK; |
| 179 m_pendingPermissions.clear(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 DEFINE_TRACE(GeolocationClientMock) | 182 DEFINE_TRACE(GeolocationClientMock) |
| 183 { | 183 { |
| 184 #if ENABLE(OILPAN) | 184 WillBeHeapSupplement<Document>::trace(visitor); |
| 185 visitor->trace(m_controllers); | |
| 186 #endif | |
| 187 visitor->trace(m_lastPosition); | |
| 188 visitor->trace(m_pendingPermissions); | 185 visitor->trace(m_pendingPermissions); |
| 189 GeolocationClient::trace(visitor); | 186 visitor->trace(m_pendingGeolocations); |
| 190 } | 187 } |
| 191 | 188 |
| 192 } // namespace blink | 189 } // namespace blink |
| OLD | NEW |