| 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 |