blob: 3d35f7da1f8c0a31755ddbe5f2056c1113818b68 [file] [log] [blame]
// Copyright 2016 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/sensor/SensorReadingUpdater.h"
#include "core/dom/Document.h"
#include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h"
#include "modules/sensor/SensorProxy.h"
#include "wtf/CurrentTime.h"
using device::mojom::blink::ReportingMode;
namespace blink {
SensorReadingUpdater::SensorReadingUpdater(SensorProxy* sensorProxy)
: m_sensorProxy(sensorProxy), m_hasPendingAnimationFrameTask(false) {}
void SensorReadingUpdater::enqueueAnimationFrameTask() {
if (m_hasPendingAnimationFrameTask)
return;
auto callback = WTF::bind(&SensorReadingUpdater::onAnimationFrame,
wrapWeakPersistent(this));
m_sensorProxy->document()->enqueueAnimationFrameTask(std::move(callback));
m_hasPendingAnimationFrameTask = true;
}
void SensorReadingUpdater::start() {
enqueueAnimationFrameTask();
}
void SensorReadingUpdater::onAnimationFrame() {
m_hasPendingAnimationFrameTask = false;
onAnimationFrameInternal();
}
DEFINE_TRACE(SensorReadingUpdater) {
visitor->trace(m_sensorProxy);
}
class SensorReadingUpdaterContinuous : public SensorReadingUpdater {
public:
explicit SensorReadingUpdaterContinuous(SensorProxy* sensorProxy)
: SensorReadingUpdater(sensorProxy) {}
DEFINE_INLINE_VIRTUAL_TRACE() { SensorReadingUpdater::trace(visitor); }
protected:
void onAnimationFrameInternal() override {
if (!m_sensorProxy->isActive())
return;
m_sensorProxy->updateSensorReading();
m_sensorProxy->notifySensorChanged(WTF::monotonicallyIncreasingTime());
enqueueAnimationFrameTask();
}
};
// New data is fetched from shared buffer only once after 'start()'
// call. Further, notification is send until every client is updated
// (i.e. until longest notification period elapses) rAF stops after that.
class SensorReadingUpdaterOnChange : public SensorReadingUpdater {
public:
explicit SensorReadingUpdaterOnChange(SensorProxy* sensorProxy)
: SensorReadingUpdater(sensorProxy),
m_newDataArrivedTime(0.0),
m_newDataArrived(false) {}
DEFINE_INLINE_VIRTUAL_TRACE() { SensorReadingUpdater::trace(visitor); }
void start() override {
m_newDataArrived = true;
SensorReadingUpdater::start();
}
protected:
void onAnimationFrameInternal() override {
if (!m_sensorProxy->isActive())
return;
double timestamp = WTF::monotonicallyIncreasingTime();
if (m_newDataArrived) {
m_newDataArrived = false;
m_sensorProxy->updateSensorReading();
m_newDataArrivedTime = timestamp;
}
m_sensorProxy->notifySensorChanged(timestamp);
DCHECK_GT(m_sensorProxy->frequenciesUsed().front(), 0.0);
double longestNotificationPeriod =
1 / m_sensorProxy->frequenciesUsed().front();
if (timestamp - m_newDataArrivedTime <= longestNotificationPeriod)
enqueueAnimationFrameTask();
}
private:
double m_newDataArrivedTime;
bool m_newDataArrived;
};
// static
SensorReadingUpdater* SensorReadingUpdater::create(SensorProxy* proxy,
ReportingMode mode) {
if (mode == ReportingMode::CONTINUOUS)
return new SensorReadingUpdaterContinuous(proxy);
return new SensorReadingUpdaterOnChange(proxy);
}
} // namespace blink