Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/sensor/Sensor.h" | 5 #include "modules/sensor/Sensor.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/ExceptionCode.h" | 8 #include "core/dom/ExceptionCode.h" |
| 9 #include "core/dom/TaskRunnerHelper.h" | 9 #include "core/dom/TaskRunnerHelper.h" |
| 10 #include "core/inspector/ConsoleMessage.h" | 10 #include "core/inspector/ConsoleMessage.h" |
| 11 #include "core/timing/DOMWindowPerformance.h" | 11 #include "core/timing/DOMWindowPerformance.h" |
| 12 #include "core/timing/Performance.h" | 12 #include "core/timing/Performance.h" |
| 13 #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h" | 13 #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h" |
| 14 #include "modules/sensor/SensorErrorEvent.h" | 14 #include "modules/sensor/SensorErrorEvent.h" |
| 15 #include "modules/sensor/SensorProviderProxy.h" | 15 #include "modules/sensor/SensorProviderProxy.h" |
| 16 | 16 |
| 17 using namespace device::mojom::blink; | 17 using namespace device::mojom::blink; |
| 18 | 18 |
| 19 namespace blink { | 19 namespace blink { |
| 20 | 20 |
| 21 namespace { | |
| 22 | |
| 23 constexpr double kMinWaitingInterval = | |
| 24 1 / device::mojom::blink::SensorConfiguration::kMaxAllowedFrequency; | |
| 25 | |
| 26 } // namespace | |
| 27 | |
| 21 Sensor::Sensor(ExecutionContext* execution_context, | 28 Sensor::Sensor(ExecutionContext* execution_context, |
| 22 const SensorOptions& sensor_options, | 29 const SensorOptions& sensor_options, |
| 23 ExceptionState& exception_state, | 30 ExceptionState& exception_state, |
| 24 SensorType type) | 31 SensorType type) |
| 25 : ContextLifecycleObserver(execution_context), | 32 : ContextLifecycleObserver(execution_context), |
| 26 sensor_options_(sensor_options), | 33 sensor_options_(sensor_options), |
| 27 type_(type), | 34 type_(type), |
| 28 state_(SensorState::kIdle), | 35 state_(SensorState::kIdle), |
| 29 last_update_timestamp_(0.0) { | 36 last_update_timestamp_(0.0), |
| 37 pending_reading_update_(false) { | |
| 30 // Check secure context. | 38 // Check secure context. |
| 31 String error_message; | 39 String error_message; |
| 32 if (!execution_context->IsSecureContext(error_message)) { | 40 if (!execution_context->IsSecureContext(error_message)) { |
| 33 exception_state.ThrowDOMException(kSecurityError, error_message); | 41 exception_state.ThrowDOMException(kSecurityError, error_message); |
| 34 return; | 42 return; |
| 35 } | 43 } |
| 36 | 44 |
| 37 // Check top-level browsing context. | 45 // Check top-level browsing context. |
| 38 if (!ToDocument(execution_context)->domWindow()->GetFrame() || | 46 if (!ToDocument(execution_context)->domWindow()->GetFrame() || |
| 39 !ToDocument(execution_context)->GetFrame()->IsMainFrame()) { | 47 !ToDocument(execution_context)->GetFrame()->IsMainFrame()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 is_null = true; | 90 is_null = true; |
| 83 return 0.0; | 91 return 0.0; |
| 84 } | 92 } |
| 85 | 93 |
| 86 Performance* performance = DOMWindowPerformance::performance(*window); | 94 Performance* performance = DOMWindowPerformance::performance(*window); |
| 87 DCHECK(performance); | 95 DCHECK(performance); |
| 88 DCHECK(sensor_proxy_); | 96 DCHECK(sensor_proxy_); |
| 89 is_null = false; | 97 is_null = false; |
| 90 | 98 |
| 91 return performance->MonotonicTimeToDOMHighResTimeStamp( | 99 return performance->MonotonicTimeToDOMHighResTimeStamp( |
| 92 sensor_proxy_->Reading().timestamp); | 100 sensor_proxy_->reading().timestamp); |
| 93 } | 101 } |
| 94 | 102 |
| 95 DEFINE_TRACE(Sensor) { | 103 DEFINE_TRACE(Sensor) { |
| 96 visitor->Trace(sensor_proxy_); | 104 visitor->Trace(sensor_proxy_); |
| 97 ActiveScriptWrappable::Trace(visitor); | 105 ActiveScriptWrappable::Trace(visitor); |
| 98 ContextLifecycleObserver::Trace(visitor); | 106 ContextLifecycleObserver::Trace(visitor); |
| 99 EventTargetWithInlineData::Trace(visitor); | 107 EventTargetWithInlineData::Trace(visitor); |
| 100 } | 108 } |
| 101 | 109 |
| 102 bool Sensor::HasPendingActivity() const { | 110 bool Sensor::HasPendingActivity() const { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 126 } | 134 } |
| 127 | 135 |
| 128 double Sensor::ReadingValue(int index, bool& is_null) const { | 136 double Sensor::ReadingValue(int index, bool& is_null) const { |
| 129 is_null = !CanReturnReadings(); | 137 is_null = !CanReturnReadings(); |
| 130 return is_null ? 0.0 : ReadingValueUnchecked(index); | 138 return is_null ? 0.0 : ReadingValueUnchecked(index); |
| 131 } | 139 } |
| 132 | 140 |
| 133 double Sensor::ReadingValueUnchecked(int index) const { | 141 double Sensor::ReadingValueUnchecked(int index) const { |
| 134 DCHECK(sensor_proxy_); | 142 DCHECK(sensor_proxy_); |
| 135 DCHECK(index >= 0 && index < device::SensorReading::kValuesCount); | 143 DCHECK(index >= 0 && index < device::SensorReading::kValuesCount); |
| 136 return sensor_proxy_->Reading().values[index]; | 144 return sensor_proxy_->reading().values[index]; |
| 137 } | 145 } |
| 138 | 146 |
| 139 void Sensor::InitSensorProxyIfNeeded() { | 147 void Sensor::InitSensorProxyIfNeeded() { |
| 140 if (sensor_proxy_) | 148 if (sensor_proxy_) |
| 141 return; | 149 return; |
| 142 | 150 |
| 143 Document* document = ToDocument(GetExecutionContext()); | 151 Document* document = ToDocument(GetExecutionContext()); |
| 144 if (!document || !document->GetFrame()) | 152 if (!document || !document->GetFrame()) |
| 145 return; | 153 return; |
| 146 | 154 |
| 147 auto provider = SensorProviderProxy::From(document->GetFrame()); | 155 auto provider = SensorProviderProxy::From(document->GetFrame()); |
| 148 sensor_proxy_ = provider->GetSensorProxy(type_); | 156 sensor_proxy_ = provider->GetSensorProxy(type_); |
| 149 | 157 |
| 150 if (!sensor_proxy_) | 158 if (!sensor_proxy_) |
| 151 sensor_proxy_ = provider->CreateSensorProxy(type_, document->GetPage()); | 159 sensor_proxy_ = provider->CreateSensorProxy(type_, document->GetPage()); |
| 152 } | 160 } |
| 153 | 161 |
| 154 void Sensor::ContextDestroyed(ExecutionContext*) { | 162 void Sensor::ContextDestroyed(ExecutionContext*) { |
| 155 StopListening(); | 163 StopListening(); |
| 156 } | 164 } |
| 157 | 165 |
| 158 void Sensor::OnSensorInitialized() { | 166 void Sensor::OnSensorInitialized() { |
| 159 if (state_ != Sensor::SensorState::kActivating) | 167 if (state_ != Sensor::SensorState::kActivating) |
| 160 return; | 168 return; |
| 161 | 169 |
| 162 RequestAddConfiguration(); | 170 RequestAddConfiguration(); |
| 163 } | 171 } |
| 164 | 172 |
| 165 void Sensor::NotifySensorChanged(double timestamp) { | 173 void Sensor::OnSensorReadingChanged(double timestamp) { |
| 166 if (state_ != Sensor::SensorState::kActivated) | 174 if (state_ != Sensor::SensorState::kActivated) |
| 167 return; | 175 return; |
| 168 | 176 |
| 177 // Return if reading update is already scheduled or the cached | |
| 178 // reading is up-to-date. | |
| 179 if (pending_reading_update_ || | |
| 180 sensor_proxy_->reading().timestamp == reading_.timestamp) | |
| 181 return; | |
| 182 | |
| 183 pending_reading_update_ = true; | |
| 184 | |
| 185 double elapsedTime = timestamp - last_update_timestamp_; | |
| 186 | |
| 169 DCHECK_GT(configuration_->frequency, 0.0); | 187 DCHECK_GT(configuration_->frequency, 0.0); |
| 170 double period = 1 / configuration_->frequency; | 188 double waitingTime = 1 / configuration_->frequency - elapsedTime; |
| 171 | 189 |
| 172 if (timestamp - last_update_timestamp_ >= period) { | 190 // Negative or zero 'waitingTime' means that polling period has elapsed. |
| 173 last_update_timestamp_ = timestamp; | 191 // We also avoid scheduling if the elapsed time is slightly behind the |
| 174 NotifySensorReadingChanged(); | 192 // polling period. |
| 193 auto sensor_reading_changed = | |
| 194 WTF::Bind(&Sensor::UpdateReading, WrapWeakPersistent(this)); | |
| 195 if (waitingTime < kMinWaitingInterval) { | |
| 196 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) | |
| 197 ->PostTask(BLINK_FROM_HERE, std::move(sensor_reading_changed)); | |
|
Reilly Grant (use Gerrit)
2017/05/10 14:53:28
Why not call UpdateReading directly here?
Mikhail
2017/05/11 10:46:20
It would synchronously invoke JS callbacks that mi
Reilly Grant (use Gerrit)
2017/05/11 18:28:12
Can you add a comment explaining that here? I wish
Mikhail
2017/05/12 08:42:13
Done.
| |
| 198 } else { | |
| 199 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) | |
| 200 ->PostDelayedTask(BLINK_FROM_HERE, std::move(sensor_reading_changed), | |
| 201 waitingTime * 1000); | |
| 175 } | 202 } |
| 176 } | 203 } |
| 177 | 204 |
| 178 void Sensor::OnSensorError(ExceptionCode code, | 205 void Sensor::OnSensorError(ExceptionCode code, |
| 179 const String& sanitized_message, | 206 const String& sanitized_message, |
| 180 const String& unsanitized_message) { | 207 const String& unsanitized_message) { |
| 181 HandleError(code, sanitized_message, unsanitized_message); | 208 HandleError(code, sanitized_message, unsanitized_message); |
| 182 } | 209 } |
| 183 | 210 |
| 184 void Sensor::OnAddConfigurationRequestCompleted(bool result) { | 211 void Sensor::OnAddConfigurationRequestCompleted(bool result) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 if (GetExecutionContext()) { | 293 if (GetExecutionContext()) { |
| 267 auto error = | 294 auto error = |
| 268 DOMException::Create(code, sanitized_message, unsanitized_message); | 295 DOMException::Create(code, sanitized_message, unsanitized_message); |
| 269 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) | 296 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) |
| 270 ->PostTask(BLINK_FROM_HERE, | 297 ->PostTask(BLINK_FROM_HERE, |
| 271 WTF::Bind(&Sensor::NotifyError, WrapWeakPersistent(this), | 298 WTF::Bind(&Sensor::NotifyError, WrapWeakPersistent(this), |
| 272 WrapPersistent(error))); | 299 WrapPersistent(error))); |
| 273 } | 300 } |
| 274 } | 301 } |
| 275 | 302 |
| 276 void Sensor::NotifySensorReadingChanged() { | 303 void Sensor::UpdateReading() { |
| 277 DCHECK(sensor_proxy_); | 304 last_update_timestamp_ = WTF::MonotonicallyIncreasingTime(); |
| 278 | 305 reading_ = sensor_proxy_->reading(); |
| 279 if (sensor_proxy_->Reading().timestamp != stored_data_.timestamp) { | 306 pending_reading_update_ = false; |
| 280 stored_data_ = sensor_proxy_->Reading(); | 307 DispatchEvent(Event::Create(EventTypeNames::change)); |
| 281 DispatchEvent(Event::Create(EventTypeNames::change)); | |
| 282 } | |
| 283 } | 308 } |
| 284 | 309 |
| 285 void Sensor::NotifyOnActivate() { | 310 void Sensor::NotifyOnActivate() { |
| 286 DispatchEvent(Event::Create(EventTypeNames::activate)); | 311 DispatchEvent(Event::Create(EventTypeNames::activate)); |
| 287 } | 312 } |
| 288 | 313 |
| 289 void Sensor::NotifyError(DOMException* error) { | 314 void Sensor::NotifyError(DOMException* error) { |
| 290 DispatchEvent( | 315 DispatchEvent( |
| 291 SensorErrorEvent::Create(EventTypeNames::error, std::move(error))); | 316 SensorErrorEvent::Create(EventTypeNames::error, std::move(error))); |
| 292 } | 317 } |
| 293 | 318 |
| 294 bool Sensor::CanReturnReadings() const { | 319 bool Sensor::CanReturnReadings() const { |
| 295 if (!IsActivated()) | 320 if (!IsActivated()) |
| 296 return false; | 321 return false; |
| 297 DCHECK(sensor_proxy_); | 322 DCHECK(sensor_proxy_); |
| 298 return sensor_proxy_->Reading().timestamp != 0.0; | 323 return sensor_proxy_->reading().timestamp != 0.0; |
| 299 } | 324 } |
| 300 | 325 |
| 301 } // namespace blink | 326 } // namespace blink |
| OLD | NEW |