Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: third_party/WebKit/Source/modules/sensor/Sensor.cpp

Issue 2870073002: [Sensors] Decouple sensor readings update from rAF (Closed)
Patch Set: [Sensors] Decouple sensor readings update from rAF Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 // Invoke JS callbacks in a different callchain to obviate
197 // possible modifications of SensorProxy::observers_ container
198 // while it is being iterated through.
199 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext())
200 ->PostTask(BLINK_FROM_HERE, std::move(sensor_reading_changed));
201 } else {
202 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext())
203 ->PostDelayedTask(BLINK_FROM_HERE, std::move(sensor_reading_changed),
204 WTF::TimeDelta::FromSecondsD(waitingTime));
175 } 205 }
176 } 206 }
177 207
178 void Sensor::OnSensorError(ExceptionCode code, 208 void Sensor::OnSensorError(ExceptionCode code,
179 const String& sanitized_message, 209 const String& sanitized_message,
180 const String& unsanitized_message) { 210 const String& unsanitized_message) {
181 HandleError(code, sanitized_message, unsanitized_message); 211 HandleError(code, sanitized_message, unsanitized_message);
182 } 212 }
183 213
184 void Sensor::OnAddConfigurationRequestCompleted(bool result) { 214 void Sensor::OnAddConfigurationRequestCompleted(bool result) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 if (GetExecutionContext()) { 296 if (GetExecutionContext()) {
267 auto error = 297 auto error =
268 DOMException::Create(code, sanitized_message, unsanitized_message); 298 DOMException::Create(code, sanitized_message, unsanitized_message);
269 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) 299 TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext())
270 ->PostTask(BLINK_FROM_HERE, 300 ->PostTask(BLINK_FROM_HERE,
271 WTF::Bind(&Sensor::NotifyError, WrapWeakPersistent(this), 301 WTF::Bind(&Sensor::NotifyError, WrapWeakPersistent(this),
272 WrapPersistent(error))); 302 WrapPersistent(error)));
273 } 303 }
274 } 304 }
275 305
276 void Sensor::NotifySensorReadingChanged() { 306 void Sensor::UpdateReading() {
277 DCHECK(sensor_proxy_); 307 last_update_timestamp_ = WTF::MonotonicallyIncreasingTime();
278 308 reading_ = sensor_proxy_->reading();
279 if (sensor_proxy_->Reading().timestamp != stored_data_.timestamp) { 309 pending_reading_update_ = false;
280 stored_data_ = sensor_proxy_->Reading(); 310 DispatchEvent(Event::Create(EventTypeNames::change));
281 DispatchEvent(Event::Create(EventTypeNames::change));
282 }
283 } 311 }
284 312
285 void Sensor::NotifyOnActivate() { 313 void Sensor::NotifyOnActivate() {
286 DispatchEvent(Event::Create(EventTypeNames::activate)); 314 DispatchEvent(Event::Create(EventTypeNames::activate));
287 } 315 }
288 316
289 void Sensor::NotifyError(DOMException* error) { 317 void Sensor::NotifyError(DOMException* error) {
290 DispatchEvent( 318 DispatchEvent(
291 SensorErrorEvent::Create(EventTypeNames::error, std::move(error))); 319 SensorErrorEvent::Create(EventTypeNames::error, std::move(error)));
292 } 320 }
293 321
294 bool Sensor::CanReturnReadings() const { 322 bool Sensor::CanReturnReadings() const {
295 if (!IsActivated()) 323 if (!IsActivated())
296 return false; 324 return false;
297 DCHECK(sensor_proxy_); 325 DCHECK(sensor_proxy_);
298 return sensor_proxy_->Reading().timestamp != 0.0; 326 return sensor_proxy_->reading().timestamp != 0.0;
299 } 327 }
300 328
301 } // namespace blink 329 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/sensor/Sensor.h ('k') | third_party/WebKit/Source/modules/sensor/SensorProviderProxy.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698