| Index: third_party/WebKit/Source/modules/sensor/Sensor.cpp
|
| diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
|
| index 7581a9ea08c7715856e5d5ca6e19d2d35f460ec9..130162ef5af0ef77819f71bd9df52c889947e7cb 100644
|
| --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp
|
| +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
|
| @@ -18,6 +18,13 @@ using namespace device::mojom::blink;
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +constexpr double kMinWaitingInterval =
|
| + 1 / device::mojom::blink::SensorConfiguration::kMaxAllowedFrequency;
|
| +
|
| +} // namespace
|
| +
|
| Sensor::Sensor(ExecutionContext* execution_context,
|
| const SensorOptions& sensor_options,
|
| ExceptionState& exception_state,
|
| @@ -26,7 +33,8 @@ Sensor::Sensor(ExecutionContext* execution_context,
|
| sensor_options_(sensor_options),
|
| type_(type),
|
| state_(SensorState::kIdle),
|
| - last_update_timestamp_(0.0) {
|
| + last_update_timestamp_(0.0),
|
| + pending_reading_update_(false) {
|
| // Check secure context.
|
| String error_message;
|
| if (!execution_context->IsSecureContext(error_message)) {
|
| @@ -89,7 +97,7 @@ DOMHighResTimeStamp Sensor::timestamp(ScriptState* script_state,
|
| is_null = false;
|
|
|
| return performance->MonotonicTimeToDOMHighResTimeStamp(
|
| - sensor_proxy_->Reading().timestamp);
|
| + sensor_proxy_->reading().timestamp);
|
| }
|
|
|
| DEFINE_TRACE(Sensor) {
|
| @@ -133,7 +141,7 @@ double Sensor::ReadingValue(int index, bool& is_null) const {
|
| double Sensor::ReadingValueUnchecked(int index) const {
|
| DCHECK(sensor_proxy_);
|
| DCHECK(index >= 0 && index < device::SensorReading::kValuesCount);
|
| - return sensor_proxy_->Reading().values[index];
|
| + return sensor_proxy_->reading().values[index];
|
| }
|
|
|
| void Sensor::InitSensorProxyIfNeeded() {
|
| @@ -162,16 +170,38 @@ void Sensor::OnSensorInitialized() {
|
| RequestAddConfiguration();
|
| }
|
|
|
| -void Sensor::NotifySensorChanged(double timestamp) {
|
| +void Sensor::OnSensorReadingChanged(double timestamp) {
|
| if (state_ != Sensor::SensorState::kActivated)
|
| return;
|
|
|
| - DCHECK_GT(configuration_->frequency, 0.0);
|
| - double period = 1 / configuration_->frequency;
|
| + // Return if reading update is already scheduled or the cached
|
| + // reading is up-to-date.
|
| + if (pending_reading_update_ ||
|
| + sensor_proxy_->reading().timestamp == reading_.timestamp)
|
| + return;
|
| +
|
| + pending_reading_update_ = true;
|
| +
|
| + double elapsedTime = timestamp - last_update_timestamp_;
|
|
|
| - if (timestamp - last_update_timestamp_ >= period) {
|
| - last_update_timestamp_ = timestamp;
|
| - NotifySensorReadingChanged();
|
| + DCHECK_GT(configuration_->frequency, 0.0);
|
| + double waitingTime = 1 / configuration_->frequency - elapsedTime;
|
| +
|
| + // Negative or zero 'waitingTime' means that polling period has elapsed.
|
| + // We also avoid scheduling if the elapsed time is slightly behind the
|
| + // polling period.
|
| + auto sensor_reading_changed =
|
| + WTF::Bind(&Sensor::UpdateReading, WrapWeakPersistent(this));
|
| + if (waitingTime < kMinWaitingInterval) {
|
| + // Invoke JS callbacks in a different callchain to obviate
|
| + // possible modifications of SensorProxy::observers_ container
|
| + // while it is being iterated through.
|
| + TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext())
|
| + ->PostTask(BLINK_FROM_HERE, std::move(sensor_reading_changed));
|
| + } else {
|
| + TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext())
|
| + ->PostDelayedTask(BLINK_FROM_HERE, std::move(sensor_reading_changed),
|
| + WTF::TimeDelta::FromSecondsD(waitingTime));
|
| }
|
| }
|
|
|
| @@ -273,13 +303,11 @@ void Sensor::HandleError(ExceptionCode code,
|
| }
|
| }
|
|
|
| -void Sensor::NotifySensorReadingChanged() {
|
| - DCHECK(sensor_proxy_);
|
| -
|
| - if (sensor_proxy_->Reading().timestamp != stored_data_.timestamp) {
|
| - stored_data_ = sensor_proxy_->Reading();
|
| - DispatchEvent(Event::Create(EventTypeNames::change));
|
| - }
|
| +void Sensor::UpdateReading() {
|
| + last_update_timestamp_ = WTF::MonotonicallyIncreasingTime();
|
| + reading_ = sensor_proxy_->reading();
|
| + pending_reading_update_ = false;
|
| + DispatchEvent(Event::Create(EventTypeNames::change));
|
| }
|
|
|
| void Sensor::NotifyOnActivate() {
|
| @@ -295,7 +323,7 @@ bool Sensor::CanReturnReadings() const {
|
| if (!IsActivated())
|
| return false;
|
| DCHECK(sensor_proxy_);
|
| - return sensor_proxy_->Reading().timestamp != 0.0;
|
| + return sensor_proxy_->reading().timestamp != 0.0;
|
| }
|
|
|
| } // namespace blink
|
|
|