Commit ed85e05c authored by mikhail.pozdnyakov's avatar mikhail.pozdnyakov Committed by Commit bot

[Sensors] Implement sensor data polling

This patch contains implementations of SensorPollingStrategy interface, defining when sensor reading is updated from shared buffer.

Also it contains logic for Suspend/Resume mojo API calls based on the page visibility. For this purpose 'SensorProxy' inherits 'PageVisibilityObserver'.

Specification: https://w3c.github.io/sensors

BUG=606766

Review-Url: https://codereview.chromium.org/2323683002
Cr-Commit-Position: refs/heads/master@{#417541}
parent d4b40c09
......@@ -160,7 +160,8 @@ void Sensor::onStartRequestCompleted(bool result)
DCHECK(m_configuration);
DCHECK(m_sensorProxy);
auto pollCallback = WTF::bind(&Sensor::pollForData, wrapWeakPersistent(this));
m_polling = SensorPollingStrategy::create(m_configuration->frequency, std::move(pollCallback), m_sensorProxy->reportingMode());
DCHECK_GT(m_configuration->frequency, 0);
m_polling = SensorPollingStrategy::create(1 / m_configuration->frequency, std::move(pollCallback), m_sensorProxy->reportingMode());
updateState(Sensor::SensorState::ACTIVE);
}
......@@ -179,6 +180,15 @@ void Sensor::onStopRequestCompleted(bool result)
void Sensor::pageVisibilityChanged()
{
updatePollingStatus();
if (!m_sensorProxy || !m_sensorProxy->isInitialized())
return;
if (page()->visibilityState() != PageVisibilityStateVisible) {
m_sensorProxy->suspend();
} else {
m_sensorProxy->resume();
}
}
void Sensor::startListening()
......
......@@ -4,13 +4,108 @@
#include "modules/sensor/SensorPollingStrategy.h"
#include "wtf/CurrentTime.h"
namespace blink {
SensorPollingStrategy::SensorPollingStrategy(double pollingPeriod, std::unique_ptr<Function<void()>> func)
: m_pollingPeriod(pollingPeriod)
, m_pollFunc(std::move(func))
, m_timer(this, &SensorPollingStrategy::pollForData)
{
}
SensorPollingStrategy::~SensorPollingStrategy() = default;
// Polls the buffer continuously using the given 'pollingPeriod'.
class ContiniousSensorPollingStrategy : public SensorPollingStrategy {
public:
ContiniousSensorPollingStrategy(double pollingPeriod, std::unique_ptr<Function<void()>> func)
: SensorPollingStrategy(pollingPeriod, std::move(func)) {}
private:
// SensorPollingStrategy overrides.
void startPolling() override;
void stopPolling() override;
void pollForData(TimerBase*) override;
};
void ContiniousSensorPollingStrategy::startPolling()
{
(*m_pollFunc)();
m_timer.startRepeating(m_pollingPeriod, BLINK_FROM_HERE);
}
void ContiniousSensorPollingStrategy::stopPolling()
{
m_timer.stop();
}
void ContiniousSensorPollingStrategy::pollForData(TimerBase*)
{
(*m_pollFunc)();
}
// Polls the buffer on signal from platform but not more frequently
// than the given 'pollingPeriod'.
class OnChangeSensorPollingStrategy : public SensorPollingStrategy {
public:
OnChangeSensorPollingStrategy(double pollingPeriod, std::unique_ptr<Function<void()>> func)
: SensorPollingStrategy(pollingPeriod, std::move(func))
, m_polling(false)
, m_lastPollingTimestamp(0.0) {}
private:
// SensorPollingStrategy overrides.
void startPolling() override;
void stopPolling() override;
void onSensorReadingChanged() override;
void pollForData(TimerBase*) override;
bool m_polling;
double m_lastPollingTimestamp;
};
void OnChangeSensorPollingStrategy::startPolling()
{
(*m_pollFunc)();
m_polling = true;
}
void OnChangeSensorPollingStrategy::stopPolling()
{
m_polling = false;
}
void OnChangeSensorPollingStrategy::onSensorReadingChanged()
{
if (!m_polling || m_timer.isActive())
return;
double elapsedTime = WTF::monotonicallyIncreasingTime() - m_lastPollingTimestamp;
if (elapsedTime >= m_pollingPeriod) {
m_lastPollingTimestamp = WTF::monotonicallyIncreasingTime();
(*m_pollFunc)();
} else {
m_timer.startOneShot(m_pollingPeriod - elapsedTime, BLINK_FROM_HERE);
}
}
void OnChangeSensorPollingStrategy::pollForData(TimerBase*)
{
if (!m_polling)
return;
m_lastPollingTimestamp = WTF::monotonicallyIncreasingTime();
(*m_pollFunc)();
}
// static
std::unique_ptr<SensorPollingStrategy> SensorPollingStrategy::create(double frequency, std::unique_ptr<Function<void()>> func, device::mojom::blink::ReportingMode mode)
std::unique_ptr<SensorPollingStrategy> SensorPollingStrategy::create(double pollingPeriod, std::unique_ptr<Function<void()>> func, device::mojom::blink::ReportingMode mode)
{
// TODO(Mikhail): Implement.
return nullptr;
if (mode == device::mojom::blink::ReportingMode::CONTINUOUS)
return std::unique_ptr<SensorPollingStrategy>(new ContiniousSensorPollingStrategy(pollingPeriod, std::move(func)));
return std::unique_ptr<SensorPollingStrategy>(new OnChangeSensorPollingStrategy(pollingPeriod, std::move(func)));
}
} // namespace blink
......@@ -6,6 +6,7 @@
#define SensorPollingStrategy_h
#include "device/generic_sensor/public/interfaces/sensor_provider.mojom-blink.h"
#include "platform/Timer.h"
#include "platform/heap/Handle.h"
#include "wtf/Functional.h"
......@@ -14,19 +15,27 @@ namespace blink {
// This class provides different polling behaviour depending on
// the given 'ReportingMode':
// - for 'CONTINUOUS' mode the polling function is invoked periodically
// with the given frequency (on timer event).
// with the given polling period (on timer event).
// - for 'ONCHANGE' mode the polling function is invoked only after client
// calls 'onSensorReadingChanged()' however considering the given frequency:
// calls 'onSensorReadingChanged()' however considering the given polling period:
// guaranteed not to be called more often than expected.
class SensorPollingStrategy {
public:
static std::unique_ptr<SensorPollingStrategy> create(double frequency, std::unique_ptr<Function<void()>> pollFunc, device::mojom::blink::ReportingMode);
static std::unique_ptr<SensorPollingStrategy> create(double pollingPeriod, std::unique_ptr<Function<void()>> pollFunc, device::mojom::blink::ReportingMode);
virtual void onSensorReadingChanged() {}
virtual void startPolling() = 0;
virtual void stopPolling() = 0;
virtual ~SensorPollingStrategy() {}
virtual ~SensorPollingStrategy();
protected:
SensorPollingStrategy(double pollingPeriod, std::unique_ptr<Function<void()>>);
virtual void pollForData(TimerBase*) = 0;
double m_pollingPeriod;
std::unique_ptr<Function<void()>> m_pollFunc;
Timer<SensorPollingStrategy> m_timer;
};
} // namespace blink
......
......@@ -19,6 +19,7 @@ SensorProxy::SensorProxy(SensorType sensorType, SensorProviderProxy* provider)
, m_clientBinding(this)
, m_state(SensorProxy::Uninitialized)
, m_reading()
, m_suspended(false)
{
}
......@@ -76,6 +77,26 @@ void SensorProxy::removeConfiguration(SensorConfigurationPtr configuration, std:
m_sensor->RemoveConfiguration(std::move(configuration), convertToBaseCallback(std::move(callback)));
}
void SensorProxy::suspend()
{
DCHECK(isInitialized());
if (m_suspended)
return;
m_sensor->Suspend();
m_suspended = true;
}
void SensorProxy::resume()
{
DCHECK(isInitialized());
if (!m_suspended)
return;
m_sensor->Resume();
m_suspended = false;
}
void SensorProxy::updateInternalReading()
{
DCHECK(isInitialized());
......
......@@ -49,6 +49,9 @@ public:
void addConfiguration(device::mojom::blink::SensorConfigurationPtr, std::unique_ptr<Function<void(bool)>>);
void removeConfiguration(device::mojom::blink::SensorConfigurationPtr, std::unique_ptr<Function<void(bool)>>);
void suspend();
void resume();
device::mojom::blink::SensorType type() const { return m_type; }
device::mojom::blink::ReportingMode reportingMode() const { return m_mode; }
......@@ -95,6 +98,7 @@ private:
mojo::ScopedSharedBufferHandle m_sharedBufferHandle;
mojo::ScopedSharedBufferMapping m_sharedBuffer;
Reading m_reading;
bool m_suspended;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment