| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "modules/geolocation/GeoNotifier.h" |
| |
| #include "modules/geolocation/Geolocation.h" |
| #include "modules/geolocation/PositionError.h" |
| #include "modules/geolocation/PositionOptions.h" |
| #include "platform/Histogram.h" |
| #include "wtf/Assertions.h" |
| |
| namespace blink { |
| |
| GeoNotifier::GeoNotifier(Geolocation* geolocation, |
| PositionCallback* successCallback, |
| PositionErrorCallback* errorCallback, |
| const PositionOptions& options) |
| : m_geolocation(geolocation), |
| m_successCallback(successCallback), |
| m_errorCallback(errorCallback), |
| m_options(options), |
| m_timer(this, &GeoNotifier::timerFired), |
| m_useCachedPosition(false) { |
| DCHECK(m_geolocation); |
| DCHECK(m_successCallback); |
| |
| DEFINE_STATIC_LOCAL(CustomCountHistogram, timeoutHistogram, |
| ("Geolocation.Timeout", 0, |
| 1000 * 60 * 10 /* 10 minute max */, 20 /* buckets */)); |
| timeoutHistogram.count(m_options.timeout()); |
| } |
| |
| DEFINE_TRACE(GeoNotifier) { |
| visitor->trace(m_geolocation); |
| visitor->trace(m_successCallback); |
| visitor->trace(m_errorCallback); |
| visitor->trace(m_fatalError); |
| } |
| |
| void GeoNotifier::setFatalError(PositionError* error) { |
| // If a fatal error has already been set, stick with it. This makes sure that |
| // when permission is denied, this is the error reported, as required by the |
| // spec. |
| if (m_fatalError) |
| return; |
| |
| m_fatalError = error; |
| // An existing timer may not have a zero timeout. |
| m_timer.stop(); |
| m_timer.startOneShot(0, BLINK_FROM_HERE); |
| } |
| |
| void GeoNotifier::setUseCachedPosition() { |
| m_useCachedPosition = true; |
| m_timer.startOneShot(0, BLINK_FROM_HERE); |
| } |
| |
| void GeoNotifier::runSuccessCallback(Geoposition* position) { |
| m_successCallback->handleEvent(position); |
| } |
| |
| void GeoNotifier::runErrorCallback(PositionError* error) { |
| if (m_errorCallback) |
| m_errorCallback->handleEvent(error); |
| } |
| |
| void GeoNotifier::startTimer() { |
| m_timer.startOneShot(m_options.timeout() / 1000.0, BLINK_FROM_HERE); |
| } |
| |
| void GeoNotifier::stopTimer() { |
| m_timer.stop(); |
| } |
| |
| void GeoNotifier::timerFired(TimerBase*) { |
| m_timer.stop(); |
| |
| // Test for fatal error first. This is required for the case where the |
| // LocalFrame is disconnected and requests are cancelled. |
| if (m_fatalError) { |
| runErrorCallback(m_fatalError); |
| // This will cause this notifier to be deleted. |
| m_geolocation->fatalErrorOccurred(this); |
| return; |
| } |
| |
| if (m_useCachedPosition) { |
| // Clear the cached position flag in case this is a watch request, which |
| // will continue to run. |
| m_useCachedPosition = false; |
| m_geolocation->requestUsesCachedPosition(this); |
| return; |
| } |
| |
| if (m_errorCallback) |
| m_errorCallback->handleEvent( |
| PositionError::create(PositionError::kTimeout, "Timeout expired")); |
| |
| DEFINE_STATIC_LOCAL(CustomCountHistogram, timeoutExpiredHistogram, |
| ("Geolocation.TimeoutExpired", 0, |
| 1000 * 60 * 10 /* 10 minute max */, 20 /* buckets */)); |
| timeoutExpiredHistogram.count(m_options.timeout()); |
| |
| m_geolocation->requestTimedOut(this); |
| } |
| |
| } // namespace blink |