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/ExecutionContextTask.h" | 9 #include "core/dom/ExecutionContextTask.h" |
10 #include "core/inspector/ConsoleMessage.h" | 10 #include "core/inspector/ConsoleMessage.h" |
11 #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h" | 11 #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h" |
12 #include "modules/sensor/SensorErrorEvent.h" | 12 #include "modules/sensor/SensorErrorEvent.h" |
13 #include "modules/sensor/SensorPollingStrategy.h" | |
14 #include "modules/sensor/SensorProviderProxy.h" | 13 #include "modules/sensor/SensorProviderProxy.h" |
15 #include "modules/sensor/SensorReading.h" | 14 #include "modules/sensor/SensorReading.h" |
| 15 #include "modules/sensor/SensorUpdateNotificationStrategy.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 Sensor::Sensor(ScriptState* scriptState, | 21 Sensor::Sensor(ScriptState* scriptState, |
22 const SensorOptions& sensorOptions, | 22 const SensorOptions& sensorOptions, |
23 ExceptionState& exceptionState, | 23 ExceptionState& exceptionState, |
24 SensorType type) | 24 SensorType type) |
25 : ActiveScriptWrappable(this), | 25 : ActiveScriptWrappable(this), |
26 ContextLifecycleObserver(scriptState->getExecutionContext()), | 26 ContextLifecycleObserver(scriptState->getExecutionContext()), |
27 PageVisibilityObserver( | |
28 toDocument(scriptState->getExecutionContext())->page()), | |
29 m_sensorOptions(sensorOptions), | 27 m_sensorOptions(sensorOptions), |
30 m_type(type), | 28 m_type(type), |
31 m_state(Sensor::SensorState::Idle) { | 29 m_state(Sensor::SensorState::Idle) { |
32 // Check secure context. | 30 // Check secure context. |
33 String errorMessage; | 31 String errorMessage; |
34 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { | 32 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { |
35 exceptionState.throwDOMException(SecurityError, errorMessage); | 33 exceptionState.throwDOMException(SecurityError, errorMessage); |
36 return; | 34 return; |
37 } | 35 } |
38 | 36 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 if (m_state != Sensor::SensorState::Active) | 118 if (m_state != Sensor::SensorState::Active) |
121 return nullptr; | 119 return nullptr; |
122 DCHECK(m_sensorProxy); | 120 DCHECK(m_sensorProxy); |
123 return m_sensorProxy->sensorReading(); | 121 return m_sensorProxy->sensorReading(); |
124 } | 122 } |
125 | 123 |
126 DEFINE_TRACE(Sensor) { | 124 DEFINE_TRACE(Sensor) { |
127 visitor->trace(m_sensorProxy); | 125 visitor->trace(m_sensorProxy); |
128 ActiveScriptWrappable::trace(visitor); | 126 ActiveScriptWrappable::trace(visitor); |
129 ContextLifecycleObserver::trace(visitor); | 127 ContextLifecycleObserver::trace(visitor); |
130 PageVisibilityObserver::trace(visitor); | |
131 EventTargetWithInlineData::trace(visitor); | 128 EventTargetWithInlineData::trace(visitor); |
132 } | 129 } |
133 | 130 |
134 bool Sensor::hasPendingActivity() const { | 131 bool Sensor::hasPendingActivity() const { |
135 if (m_state == Sensor::SensorState::Idle || | 132 if (m_state == Sensor::SensorState::Idle || |
136 m_state == Sensor::SensorState::Errored) | 133 m_state == Sensor::SensorState::Errored) |
137 return false; | 134 return false; |
138 return hasEventListeners(); | 135 return hasEventListeners(); |
139 } | 136 } |
140 | 137 |
(...skipping 16 matching lines...) Expand all Loading... |
157 | 154 |
158 void Sensor::initSensorProxyIfNeeded() { | 155 void Sensor::initSensorProxyIfNeeded() { |
159 if (m_sensorProxy) | 156 if (m_sensorProxy) |
160 return; | 157 return; |
161 | 158 |
162 Document* document = toDocument(getExecutionContext()); | 159 Document* document = toDocument(getExecutionContext()); |
163 if (!document || !document->frame()) | 160 if (!document || !document->frame()) |
164 return; | 161 return; |
165 | 162 |
166 auto provider = SensorProviderProxy::from(document->frame()); | 163 auto provider = SensorProviderProxy::from(document->frame()); |
167 m_sensorProxy = provider->getSensor(m_type); | 164 m_sensorProxy = provider->getSensorProxy(m_type); |
168 | 165 |
169 if (!m_sensorProxy) { | 166 if (!m_sensorProxy) { |
170 m_sensorProxy = | 167 m_sensorProxy = provider->createSensorProxy(m_type, document->page(), |
171 provider->createSensor(m_type, createSensorReadingFactory()); | 168 createSensorReadingFactory()); |
172 } | 169 } |
173 } | 170 } |
174 | 171 |
175 void Sensor::contextDestroyed() { | 172 void Sensor::contextDestroyed() { |
176 if (m_state == Sensor::SensorState::Active || | 173 if (m_state == Sensor::SensorState::Active || |
177 m_state == Sensor::SensorState::Activating) | 174 m_state == Sensor::SensorState::Activating) |
178 stopListening(); | 175 stopListening(); |
179 } | 176 } |
180 | 177 |
181 void Sensor::onSensorInitialized() { | 178 void Sensor::onSensorInitialized() { |
182 if (m_state != Sensor::SensorState::Activating) | 179 if (m_state != Sensor::SensorState::Activating) |
183 return; | 180 return; |
184 | 181 |
185 startListening(); | 182 startListening(); |
186 } | 183 } |
187 | 184 |
188 void Sensor::onSensorReadingChanged() { | 185 void Sensor::onSensorReadingChanged() { |
189 if (m_polling) | 186 if (m_state == Sensor::SensorState::Active) { |
190 m_polling->onSensorReadingChanged(); | 187 DCHECK(m_sensorUpdateNotifier); |
| 188 m_sensorUpdateNotifier->onSensorReadingChanged(); |
| 189 } |
191 } | 190 } |
192 | 191 |
193 void Sensor::onSensorError(ExceptionCode code, | 192 void Sensor::onSensorError(ExceptionCode code, |
194 const String& sanitizedMessage, | 193 const String& sanitizedMessage, |
195 const String& unsanitizedMessage) { | 194 const String& unsanitizedMessage) { |
196 reportError(code, sanitizedMessage, unsanitizedMessage); | 195 reportError(code, sanitizedMessage, unsanitizedMessage); |
| 196 if (m_sensorUpdateNotifier) |
| 197 m_sensorUpdateNotifier->cancelPendingNotifications(); |
197 } | 198 } |
198 | 199 |
199 void Sensor::onStartRequestCompleted(bool result) { | 200 void Sensor::onStartRequestCompleted(bool result) { |
200 if (m_state != Sensor::SensorState::Activating) | 201 if (m_state != Sensor::SensorState::Activating) |
201 return; | 202 return; |
202 | 203 |
203 if (!result) { | 204 if (!result) { |
204 reportError( | 205 reportError( |
205 OperationError, | 206 OperationError, |
206 "start() call has failed possibly due to inappropriate options."); | 207 "start() call has failed possibly due to inappropriate options."); |
207 return; | 208 return; |
208 } | 209 } |
209 | 210 |
210 DCHECK(m_configuration); | 211 DCHECK(m_configuration); |
211 DCHECK(m_sensorProxy); | 212 DCHECK(m_sensorProxy); |
212 auto pollCallback = WTF::bind(&Sensor::pollForData, wrapWeakPersistent(this)); | 213 auto updateCallback = |
| 214 WTF::bind(&Sensor::onSensorUpdateNotification, wrapWeakPersistent(this)); |
213 DCHECK_GT(m_configuration->frequency, 0); | 215 DCHECK_GT(m_configuration->frequency, 0); |
214 m_polling = SensorPollingStrategy::create(1 / m_configuration->frequency, | 216 m_sensorUpdateNotifier = SensorUpdateNotificationStrategy::create( |
215 std::move(pollCallback), | 217 m_configuration->frequency, std::move(updateCallback)); |
216 m_sensorProxy->reportingMode()); | |
217 updateState(Sensor::SensorState::Active); | 218 updateState(Sensor::SensorState::Active); |
218 } | 219 } |
219 | 220 |
220 void Sensor::onStopRequestCompleted(bool result) { | |
221 if (m_state == Sensor::SensorState::Idle) | |
222 return; | |
223 | |
224 if (!result) | |
225 reportError(OperationError); | |
226 | |
227 DCHECK(m_sensorProxy); | |
228 m_sensorProxy->removeObserver(this); | |
229 } | |
230 | |
231 void Sensor::pageVisibilityChanged() { | |
232 updatePollingStatus(); | |
233 | |
234 if (!m_sensorProxy || !m_sensorProxy->isInitialized()) | |
235 return; | |
236 | |
237 if (page()->visibilityState() != PageVisibilityStateVisible) { | |
238 m_sensorProxy->suspend(); | |
239 } else { | |
240 m_sensorProxy->resume(); | |
241 } | |
242 } | |
243 | |
244 void Sensor::startListening() { | 221 void Sensor::startListening() { |
245 DCHECK(m_sensorProxy); | 222 DCHECK(m_sensorProxy); |
246 updateState(Sensor::SensorState::Activating); | 223 updateState(Sensor::SensorState::Activating); |
247 | 224 |
248 m_sensorProxy->addObserver(this); | 225 m_sensorProxy->addObserver(this); |
249 if (!m_sensorProxy->isInitialized()) { | 226 if (!m_sensorProxy->isInitialized()) { |
250 m_sensorProxy->initialize(); | 227 m_sensorProxy->initialize(); |
251 return; | 228 return; |
252 } | 229 } |
253 | 230 |
254 if (!m_configuration) { | 231 if (!m_configuration) { |
255 m_configuration = createSensorConfig(); | 232 m_configuration = createSensorConfig(); |
256 DCHECK(m_configuration); | 233 DCHECK(m_configuration); |
257 DCHECK(m_configuration->frequency > 0 && | 234 DCHECK(m_configuration->frequency > 0 && |
258 m_configuration->frequency <= m_sensorProxy->maximumFrequency()); | 235 m_configuration->frequency <= m_sensorProxy->maximumFrequency()); |
259 } | 236 } |
260 | 237 |
261 auto startCallback = | 238 auto startCallback = |
262 WTF::bind(&Sensor::onStartRequestCompleted, wrapWeakPersistent(this)); | 239 WTF::bind(&Sensor::onStartRequestCompleted, wrapWeakPersistent(this)); |
263 m_sensorProxy->addConfiguration(m_configuration->Clone(), | 240 m_sensorProxy->addConfiguration(m_configuration->Clone(), |
264 std::move(startCallback)); | 241 std::move(startCallback)); |
265 } | 242 } |
266 | 243 |
267 void Sensor::stopListening() { | 244 void Sensor::stopListening() { |
268 DCHECK(m_sensorProxy); | 245 DCHECK(m_sensorProxy); |
269 updateState(Sensor::SensorState::Idle); | 246 updateState(Sensor::SensorState::Idle); |
270 | 247 |
| 248 if (m_sensorUpdateNotifier) |
| 249 m_sensorUpdateNotifier->cancelPendingNotifications(); |
| 250 |
271 if (m_sensorProxy->isInitialized()) { | 251 if (m_sensorProxy->isInitialized()) { |
272 auto callback = | |
273 WTF::bind(&Sensor::onStopRequestCompleted, wrapWeakPersistent(this)); | |
274 DCHECK(m_configuration); | 252 DCHECK(m_configuration); |
275 m_sensorProxy->removeConfiguration(m_configuration->Clone(), | 253 m_sensorProxy->removeConfiguration(m_configuration->Clone()); |
276 std::move(callback)); | |
277 } else { | |
278 m_sensorProxy->removeObserver(this); | |
279 } | 254 } |
| 255 m_sensorProxy->removeObserver(this); |
280 } | 256 } |
281 | 257 |
282 void Sensor::pollForData() { | 258 void Sensor::onSensorUpdateNotification() { |
283 if (m_state != Sensor::SensorState::Active) { | 259 if (m_state != Sensor::SensorState::Active) |
284 DCHECK(m_polling); | |
285 m_polling->stopPolling(); | |
286 return; | 260 return; |
287 } | |
288 | 261 |
289 DCHECK(m_sensorProxy); | 262 DCHECK(m_sensorProxy); |
290 DCHECK(m_sensorProxy->isInitialized()); | 263 DCHECK(m_sensorProxy->isInitialized()); |
291 m_sensorProxy->updateSensorReading(); | 264 DCHECK(m_sensorProxy->sensorReading()); |
292 | 265 |
293 DCHECK(m_sensorProxy->sensorReading()); | |
294 if (getExecutionContext() && | 266 if (getExecutionContext() && |
295 m_sensorProxy->sensorReading()->isReadingUpdated(m_storedData)) { | 267 m_sensorProxy->sensorReading()->isReadingUpdated(m_storedData)) { |
296 getExecutionContext()->postTask( | 268 getExecutionContext()->postTask( |
297 BLINK_FROM_HERE, | 269 BLINK_FROM_HERE, |
298 createSameThreadTask(&Sensor::notifySensorReadingChanged, | 270 createSameThreadTask(&Sensor::notifySensorReadingChanged, |
299 wrapWeakPersistent(this))); | 271 wrapWeakPersistent(this))); |
300 } | 272 } |
301 | 273 |
302 m_storedData = m_sensorProxy->sensorReading()->data(); | 274 m_storedData = m_sensorProxy->sensorReading()->data(); |
303 } | 275 } |
304 | 276 |
305 void Sensor::updateState(Sensor::SensorState newState) { | 277 void Sensor::updateState(Sensor::SensorState newState) { |
306 if (newState == m_state) | 278 if (newState == m_state) |
307 return; | 279 return; |
308 | 280 |
309 if (newState == SensorState::Active && getExecutionContext()) { | 281 if (newState == SensorState::Active && getExecutionContext()) { |
310 DCHECK_EQ(SensorState::Activating, m_state); | 282 DCHECK_EQ(SensorState::Activating, m_state); |
311 getExecutionContext()->postTask( | 283 getExecutionContext()->postTask( |
312 BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifyOnActivate, | 284 BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifyOnActivate, |
313 wrapWeakPersistent(this))); | 285 wrapWeakPersistent(this))); |
314 } | 286 } |
315 | 287 |
316 m_state = newState; | 288 m_state = newState; |
317 updatePollingStatus(); | |
318 } | 289 } |
319 | 290 |
320 void Sensor::reportError(ExceptionCode code, | 291 void Sensor::reportError(ExceptionCode code, |
321 const String& sanitizedMessage, | 292 const String& sanitizedMessage, |
322 const String& unsanitizedMessage) { | 293 const String& unsanitizedMessage) { |
323 updateState(Sensor::SensorState::Errored); | 294 updateState(Sensor::SensorState::Errored); |
324 if (getExecutionContext()) { | 295 if (getExecutionContext()) { |
325 auto error = | 296 auto error = |
326 DOMException::create(code, sanitizedMessage, unsanitizedMessage); | 297 DOMException::create(code, sanitizedMessage, unsanitizedMessage); |
327 getExecutionContext()->postTask( | 298 getExecutionContext()->postTask( |
328 BLINK_FROM_HERE, | 299 BLINK_FROM_HERE, |
329 createSameThreadTask(&Sensor::notifyError, wrapWeakPersistent(this), | 300 createSameThreadTask(&Sensor::notifyError, wrapWeakPersistent(this), |
330 wrapPersistent(error))); | 301 wrapPersistent(error))); |
331 } | 302 } |
332 } | 303 } |
333 | 304 |
334 void Sensor::updatePollingStatus() { | 305 void Sensor::onSuspended() { |
335 if (!m_polling) | 306 if (m_sensorUpdateNotifier) |
336 return; | 307 m_sensorUpdateNotifier->cancelPendingNotifications(); |
337 | |
338 if (m_state != Sensor::SensorState::Active || | |
339 page()->visibilityState() != PageVisibilityStateVisible) { | |
340 m_polling->stopPolling(); | |
341 } else { | |
342 m_polling->startPolling(); | |
343 } | |
344 } | 308 } |
345 | 309 |
346 void Sensor::notifySensorReadingChanged() { | 310 void Sensor::notifySensorReadingChanged() { |
347 dispatchEvent(Event::create(EventTypeNames::change)); | 311 dispatchEvent(Event::create(EventTypeNames::change)); |
348 } | 312 } |
349 | 313 |
350 void Sensor::notifyOnActivate() { | 314 void Sensor::notifyOnActivate() { |
351 dispatchEvent(Event::create(EventTypeNames::activate)); | 315 dispatchEvent(Event::create(EventTypeNames::activate)); |
352 } | 316 } |
353 | 317 |
354 void Sensor::notifyError(DOMException* error) { | 318 void Sensor::notifyError(DOMException* error) { |
355 dispatchEvent( | 319 dispatchEvent( |
356 SensorErrorEvent::create(EventTypeNames::error, std::move(error))); | 320 SensorErrorEvent::create(EventTypeNames::error, std::move(error))); |
357 } | 321 } |
358 | 322 |
359 } // namespace blink | 323 } // namespace blink |
OLD | NEW |