Index: third_party/WebKit/Source/modules/sensor/SensorProxy.cpp |
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp |
index eb6e6510a3758e86683e6bbfaff00e5fdcdf6c0a..71cdda1436a39dd1fe5c1f29fd641eeb4684d470 100644 |
--- a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp |
+++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp |
@@ -4,30 +4,54 @@ |
#include "modules/sensor/SensorProxy.h" |
+#include "core/dom/Document.h" |
+#include "core/dom/FrameRequestCallback.h" |
#include "core/frame/LocalFrame.h" |
#include "modules/sensor/SensorProviderProxy.h" |
#include "modules/sensor/SensorReading.h" |
#include "platform/mojo/MojoHelper.h" |
#include "public/platform/Platform.h" |
+#include "wtf/CurrentTime.h" |
using namespace device::mojom::blink; |
namespace blink { |
+class SensorFrameRequestCallback : public FrameRequestCallback { |
+ public: |
+ explicit SensorFrameRequestCallback(SensorProxy* sensorProxy) |
+ : m_sensorProxy(sensorProxy) {} |
+ |
+ void handleEvent(double highResTimeMs) override { |
+ if (m_sensorProxy) |
+ m_sensorProxy->onAnimationFrame(highResTimeMs * 0.001); |
+ } |
+ |
+ DEFINE_INLINE_VIRTUAL_TRACE() { |
+ visitor->trace(m_sensorProxy); |
+ FrameRequestCallback::trace(visitor); |
+ } |
+ |
+ private: |
+ WeakMember<SensorProxy> m_sensorProxy; |
+}; |
+ |
SensorProxy::SensorProxy(SensorType sensorType, |
SensorProviderProxy* provider, |
- Page* page, |
+ Document* document, |
std::unique_ptr<SensorReadingFactory> readingFactory) |
- : PageVisibilityObserver(page), |
+ : PageVisibilityObserver(document->page()), |
m_type(sensorType), |
m_mode(ReportingMode::CONTINUOUS), |
m_provider(provider), |
m_clientBinding(this), |
m_state(SensorProxy::Uninitialized), |
m_suspended(false), |
+ m_document(document), |
m_readingFactory(std::move(readingFactory)), |
m_maximumFrequency(0.0), |
- m_timer(this, &SensorProxy::onTimerFired) {} |
+ m_rafCallbackId(0), |
+ m_lastRafTimestamp(0.0) {} |
SensorProxy::~SensorProxy() {} |
@@ -36,6 +60,8 @@ void SensorProxy::dispose() { |
} |
DEFINE_TRACE(SensorProxy) { |
+ visitor->trace(m_document); |
+ visitor->trace(m_rafCallback); |
visitor->trace(m_reading); |
visitor->trace(m_observers); |
visitor->trace(m_provider); |
@@ -94,7 +120,7 @@ void SensorProxy::suspend() { |
m_sensor->Suspend(); |
m_suspended = true; |
- if (usesPollingTimer()) |
+ if (isPollingBuffer()) |
updatePollingStatus(); |
for (Observer* observer : m_observers) |
@@ -109,7 +135,7 @@ void SensorProxy::resume() { |
m_sensor->Resume(); |
m_suspended = false; |
- if (usesPollingTimer()) |
+ if (isPollingBuffer()) |
updatePollingStatus(); |
} |
@@ -118,11 +144,11 @@ const SensorConfiguration* SensorProxy::defaultConfig() const { |
return m_defaultConfig.get(); |
} |
-bool SensorProxy::usesPollingTimer() const { |
+bool SensorProxy::isPollingBuffer() const { |
return isInitialized() && (m_mode == ReportingMode::CONTINUOUS); |
} |
-void SensorProxy::updateSensorReading() { |
+void SensorProxy::updateSensorReading(double timestamp) { |
DCHECK(isInitialized()); |
DCHECK(m_readingFactory); |
int readAttempts = 0; |
@@ -138,7 +164,7 @@ void SensorProxy::updateSensorReading() { |
m_reading = m_readingFactory->createSensorReading(readingData); |
for (Observer* observer : m_observers) |
- observer->onSensorReadingChanged(); |
+ observer->onSensorReadingChanged(timestamp); |
} |
void SensorProxy::RaiseError() { |
@@ -147,7 +173,7 @@ void SensorProxy::RaiseError() { |
void SensorProxy::SensorReadingChanged() { |
DCHECK_EQ(ReportingMode::ON_CHANGE, m_mode); |
- updateSensorReading(); |
+ updateSensorReading(WTF::monotonicallyIncreasingTime()); |
} |
void SensorProxy::pageVisibilityChanged() { |
@@ -169,7 +195,7 @@ void SensorProxy::handleSensorError(ExceptionCode code, |
return; |
} |
- if (usesPollingTimer()) { // Stop polling. |
+ if (isPollingBuffer()) { // Stop polling. |
m_frequenciesUsed.clear(); |
updatePollingStatus(); |
} |
@@ -229,6 +255,10 @@ void SensorProxy::onSensorCreated(SensorInitParamsPtr params, |
convertToBaseCallback(std::move(errorCallback))); |
m_state = Initialized; |
+ |
+ if (isPollingBuffer()) |
+ m_rafCallback = new SensorFrameRequestCallback(this); |
+ |
for (Observer* observer : m_observers) |
observer->onSensorInitialized(); |
} |
@@ -237,8 +267,9 @@ void SensorProxy::onAddConfigurationCompleted( |
double frequency, |
std::unique_ptr<Function<void(bool)>> callback, |
bool result) { |
- if (usesPollingTimer() && result) { |
+ if (isPollingBuffer() && result) { |
m_frequenciesUsed.append(frequency); |
+ std::sort(m_frequenciesUsed.begin(), m_frequenciesUsed.end()); |
updatePollingStatus(); |
} |
@@ -250,7 +281,7 @@ void SensorProxy::onRemoveConfigurationCompleted(double frequency, |
if (!result) |
DVLOG(1) << "Failure at sensor configuration removal"; |
- if (!usesPollingTimer()) |
+ if (!isPollingBuffer()) |
return; |
size_t index = m_frequenciesUsed.find(frequency); |
@@ -277,27 +308,30 @@ bool SensorProxy::tryReadFromBuffer(device::SensorReading& result) { |
} |
void SensorProxy::updatePollingStatus() { |
- DCHECK(usesPollingTimer()); |
- |
- if (m_suspended || m_frequenciesUsed.isEmpty()) { |
- m_timer.stop(); |
+ DCHECK(isPollingBuffer()); |
+ if (m_document && !m_suspended && !m_frequenciesUsed.isEmpty()) { |
+ DCHECK(m_rafCallback); |
+ m_rafCallbackId = m_document->requestAnimationFrame(m_rafCallback); |
return; |
} |
- // TODO(Mikhail): Consider using sorted queue instead of searching |
- // max element each time. |
- auto it = |
- std::max_element(m_frequenciesUsed.begin(), m_frequenciesUsed.end()); |
- DCHECK_GT(*it, 0.0); |
- |
- double repeatInterval = 1 / *it; |
- if (!m_timer.isActive() || m_timer.repeatInterval() != repeatInterval) { |
- updateSensorReading(); |
- m_timer.startRepeating(repeatInterval, BLINK_FROM_HERE); |
- } |
+ |
+ if (m_rafCallbackId && m_document) |
+ m_document->cancelAnimationFrame(m_rafCallbackId); |
} |
-void SensorProxy::onTimerFired(TimerBase*) { |
- updateSensorReading(); |
+void SensorProxy::onAnimationFrame(double timestamp) { |
+ DCHECK(isPollingBuffer()); |
+ m_rafCallbackId = 0; |
+ if (m_frequenciesUsed.isEmpty()) |
+ return; |
+ |
+ double minBufferPollingPeriod = 1 / m_frequenciesUsed.back(); |
+ if (timestamp - m_lastRafTimestamp >= minBufferPollingPeriod) { |
+ updateSensorReading(timestamp); |
+ m_lastRafTimestamp = timestamp; |
+ } |
+ |
+ updatePollingStatus(); |
} |
} // namespace blink |