| 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..f92216b6e547fcb4c0a189e5211fc805fbc88e7b 100644
|
| --- a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
|
| +++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
|
| @@ -4,30 +4,53 @@
|
|
|
| #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 {
|
| + m_sensorProxy->onAnimationFrame(highResTimeMs * 0.001);
|
| + }
|
| +
|
| + DEFINE_INLINE_VIRTUAL_TRACE() {
|
| + visitor->trace(m_sensorProxy);
|
| + FrameRequestCallback::trace(visitor);
|
| + }
|
| +
|
| + private:
|
| + Member<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 +59,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,8 +119,8 @@ void SensorProxy::suspend() {
|
| m_sensor->Suspend();
|
| m_suspended = true;
|
|
|
| - if (usesPollingTimer())
|
| - updatePollingStatus();
|
| + if (isPollingBuffer())
|
| + processRAFQueue();
|
|
|
| for (Observer* observer : m_observers)
|
| observer->onSuspended();
|
| @@ -109,8 +134,8 @@ void SensorProxy::resume() {
|
| m_sensor->Resume();
|
| m_suspended = false;
|
|
|
| - if (usesPollingTimer())
|
| - updatePollingStatus();
|
| + if (isPollingBuffer())
|
| + processRAFQueue();
|
| }
|
|
|
| const SensorConfiguration* SensorProxy::defaultConfig() const {
|
| @@ -118,11 +143,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 +163,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 +172,7 @@ void SensorProxy::RaiseError() {
|
|
|
| void SensorProxy::SensorReadingChanged() {
|
| DCHECK_EQ(ReportingMode::ON_CHANGE, m_mode);
|
| - updateSensorReading();
|
| + updateSensorReading(WTF::monotonicallyIncreasingTime());
|
| }
|
|
|
| void SensorProxy::pageVisibilityChanged() {
|
| @@ -169,9 +194,9 @@ void SensorProxy::handleSensorError(ExceptionCode code,
|
| return;
|
| }
|
|
|
| - if (usesPollingTimer()) { // Stop polling.
|
| + if (isPollingBuffer()) { // Stop polling.
|
| m_frequenciesUsed.clear();
|
| - updatePollingStatus();
|
| + processRAFQueue();
|
| }
|
|
|
| m_state = Uninitialized;
|
| @@ -229,6 +254,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,9 +266,10 @@ void SensorProxy::onAddConfigurationCompleted(
|
| double frequency,
|
| std::unique_ptr<Function<void(bool)>> callback,
|
| bool result) {
|
| - if (usesPollingTimer() && result) {
|
| + if (isPollingBuffer() && result) {
|
| m_frequenciesUsed.append(frequency);
|
| - updatePollingStatus();
|
| + std::sort(m_frequenciesUsed.begin(), m_frequenciesUsed.end());
|
| + processRAFQueue();
|
| }
|
|
|
| (*callback)(result);
|
| @@ -250,7 +280,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);
|
| @@ -260,7 +290,7 @@ void SensorProxy::onRemoveConfigurationCompleted(double frequency,
|
| }
|
|
|
| m_frequenciesUsed.remove(index);
|
| - updatePollingStatus();
|
| + processRAFQueue();
|
| }
|
|
|
| bool SensorProxy::tryReadFromBuffer(device::SensorReading& result) {
|
| @@ -276,28 +306,33 @@ bool SensorProxy::tryReadFromBuffer(device::SensorReading& result) {
|
| return true;
|
| }
|
|
|
| -void SensorProxy::updatePollingStatus() {
|
| - DCHECK(usesPollingTimer());
|
| -
|
| - if (m_suspended || m_frequenciesUsed.isEmpty()) {
|
| - m_timer.stop();
|
| - return;
|
| +bool SensorProxy::processRAFQueue() {
|
| + DCHECK(isPollingBuffer());
|
| + if (m_rafCallbackId) { // Cancel pending request.
|
| + m_document->cancelAnimationFrame(m_rafCallbackId);
|
| + m_rafCallbackId = 0;
|
| }
|
| - // 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_suspended && !m_frequenciesUsed.isEmpty()) {
|
| + DCHECK(m_rafCallback);
|
| + m_rafCallbackId = m_document->requestAnimationFrame(m_rafCallback);
|
| + return true;
|
| }
|
| +
|
| + return false;
|
| }
|
|
|
| -void SensorProxy::onTimerFired(TimerBase*) {
|
| - updateSensorReading();
|
| +void SensorProxy::onAnimationFrame(double timestamp) {
|
| + DCHECK(isPollingBuffer());
|
| + m_rafCallbackId = 0;
|
| + if (!processRAFQueue())
|
| + return;
|
| +
|
| + double minBufferPollingPeriod = 1 / m_frequenciesUsed.back();
|
| + if (timestamp - m_lastRafTimestamp >= minBufferPollingPeriod) {
|
| + m_lastRafTimestamp = timestamp;
|
| + updateSensorReading(timestamp);
|
| + }
|
| }
|
|
|
| } // namespace blink
|
|
|