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

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

Issue 2121313002: [sensors] Generic Sensors Framework blink side (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sensors_mojo_interfaces
Patch Set: Comments from Tim. Removed the default sensor configuration management (to be added with a separate… Created 4 years, 3 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/ExecutionContextTask.h" 9 #include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h"
10 #include "core/events/Event.h" 10 #include "modules/sensor/SensorErrorEvent.h"
11 11 #include "modules/sensor/SensorPollingStrategy.h"
12 #include "modules/sensor/SensorProviderProxy.h"
12 #include "modules/sensor/SensorReading.h" 13 #include "modules/sensor/SensorReading.h"
14 #include "modules/sensor/SensorReadingEvent.h"
15
16 using namespace device::mojom::blink;
13 17
14 namespace blink { 18 namespace blink {
15 19
16 Sensor::~Sensor() 20 Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOp tions, SensorType type)
17 {
18 }
19
20 Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOp tions)
21 : ActiveScriptWrappable(this) 21 : ActiveScriptWrappable(this)
22 , ActiveDOMObject(executionContext) 22 , ActiveDOMObject(executionContext)
23 , PlatformEventController(toDocument(executionContext)->page()) 23 , PageVisibilityObserver(toDocument(executionContext)->page())
24 , m_sensorState(SensorState::Idle)
25 , m_sensorReading(nullptr)
26 , m_sensorOptions(sensorOptions) 24 , m_sensorOptions(sensorOptions)
27 { 25 , m_type(type)
26 , m_state(Sensor::SensorState::IDLE)
27 , m_storedData()
28 {
29 DCHECK(executionContext->isDocument());
30 }
31
32 void Sensor::dispose()
33 {
34 stopListening();
35 }
36
37 void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState)
38 {
39 if (m_state != Sensor::SensorState::IDLE && m_state != Sensor::SensorState:: ERRORED) {
40 exceptionState.throwDOMException(InvalidStateError, "Cannot start becaus e SensorState is not idle or errored");
41 return;
42 }
43
44 initSensorProxyIfNeeded();
45
46 if (!m_sensorProxy) {
47 exceptionState.throwDOMException(InvalidStateError, "The Sensor is no lo nger associated to a frame.");
48 return;
49 }
50
51 updateState(Sensor::SensorState::ACTIVATING);
52
53 startListening();
54 }
55
56 void Sensor::stop(ScriptState*, ExceptionState& exceptionState)
57 {
58 if (m_state == Sensor::SensorState::IDLE || m_state == Sensor::SensorState:: ERRORED) {
59 exceptionState.throwDOMException(InvalidStateError, "Cannot stop because SensorState is either idle or errored");
60 return;
61 }
62
63 if (!m_sensorProxy) {
64 exceptionState.throwDOMException(InvalidStateError, "The Sensor is no lo nger associated to a frame.");
65 return;
66 }
67
68 stopListening();
69 }
70
71 static String ToString(Sensor::SensorState state)
72 {
73 switch (state) {
74 case Sensor::SensorState::IDLE:
75 return "idle";
76 case Sensor::SensorState::ACTIVATING:
77 return "activating";
78 case Sensor::SensorState::ACTIVE:
79 return "active";
80 case Sensor::SensorState::ERRORED:
81 return "errored";
82 default:
83 NOTREACHED();
84 }
85 return "idle";
28 } 86 }
29 87
30 // Getters 88 // Getters
31 String Sensor::state() const 89 String Sensor::state() const
32 { 90 {
33 // TODO(riju): Validate the transitions. 91 return ToString(m_state);
34 switch (m_sensorState) {
35 case SensorState::Idle:
36 return "idle";
37 case SensorState::Activating:
38 return "activating";
39 case SensorState::Active:
40 return "active";
41 case SensorState::Errored:
42 return "errored";
43 }
44 NOTREACHED();
45 return "idle";
46 } 92 }
47 93
48 SensorReading* Sensor::reading() const 94 SensorReading* Sensor::reading() const
49 { 95 {
50 return m_sensorReading.get(); 96 return m_sensorReading.get();
51 } 97 }
52 98
53 void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState) 99 DEFINE_TRACE(Sensor)
54 { 100 {
55 101 visitor->trace(m_polling);
56 if (m_sensorState != SensorState::Idle && m_sensorState != SensorState::Erro red) { 102 visitor->trace(m_sensorProxy);
57 exceptionState.throwDOMException(InvalidStateError, "Invalid State: Sens orState is not idle or errored"); 103 visitor->trace(m_sensorReading);
58 return; 104 ActiveScriptWrappable::trace(visitor);
59 } 105 ActiveDOMObject::trace(visitor);
60 106 PageVisibilityObserver::trace(visitor);
61 updateState(SensorState::Activating); 107 EventTargetWithInlineData::trace(visitor);
62 108 }
63 // TODO(riju) : Add Permissions stuff later. 109
64 110 bool Sensor::hasPendingActivity() const
65 m_hasEventListener = true; 111 {
66 112 if (!getExecutionContext() || getExecutionContext()->activeDOMObjectsAreStop ped())
haraken 2016/09/06 05:04:28 I'd change this check to if(!m_sensorReading) or s
Mikhail 2016/09/06 07:13:58 I'll change accordingly, thanks
67 // TODO(riju): verify the correct order of onstatechange(active) and the fir st onchange(event). 113 return false;
68 startUpdating(); 114 return hasEventListeners();
69 } 115 }
70 116
71 void Sensor::stop(ScriptState* scriptState, ExceptionState& exceptionState) 117 void Sensor::initSensorProxyIfNeeded()
72 { 118 {
73 if (m_sensorState == SensorState::Idle || m_sensorState == SensorState::Erro red) { 119 if (m_sensorProxy)
74 exceptionState.throwDOMException(InvalidStateError, "Invalid State: Sens orState is either idle or errored"); 120 return;
75 return; 121
76 } 122 Document* document = toDocument(getExecutionContext());
77 123 if (!document->frame())
haraken 2016/09/06 05:04:28 document may be nullptr.
Mikhail 2016/09/06 07:13:58 we've DCHECK(executionContext->isDocument()); in t
78 m_hasEventListener = false; 124 return;
79 stopUpdating(); 125
80 126 m_sensorProxy = SensorProviderProxy::getOrCreateForFrame(document->frame())- >getOrCreateSensor(m_type);
81 m_sensorReading.clear(); 127 }
82 updateState(SensorState::Idle); 128
83 } 129 void Sensor::stop()
84 130 {
85 void Sensor::updateState(SensorState newState) 131 stopListening();
86 { 132 }
87 DCHECK(isMainThread()); 133
88 if (m_sensorState == newState) 134 void Sensor::onSensorInitialized()
89 return; 135 {
90 136 if (m_state != Sensor::SensorState::ACTIVATING)
91 m_sensorState = newState; 137 return;
92 // Notify context that state changed. 138
93 if (getExecutionContext()) 139 if (!m_sensorProxy) {
94 getExecutionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&S ensor::notifyStateChange, wrapPersistent(this))); 140 reportError();
95 } 141 return;
96 142 }
97 void Sensor::notifyStateChange() 143
98 { 144 // TODO(Mikhail) : Manage the default configuration properly
145 // (when provided with the actual configuration from the platform).
146 // So far assign to 5Hz which corresponds to 'SENSOR_DELAY_NORMAL'
147 // delay from Android Sensors framework.
148 SensorConfiguration defaultConfig;
149 defaultConfig.frequency = 5.0;
150
151 m_configuration = createSensorConfig(m_sensorOptions, &defaultConfig);
timvolodine 2016/09/05 23:22:40 would it make sense to drop defaultConfig here and
152 if (!m_configuration) {
153 reportError();
154 return;
155 }
156
157 auto startCallback = WTF::bind(&Sensor::onStartRequestCompleted, wrapWeakPer sistent(this));
158 m_sensorProxy->addConfiguration(m_configuration->Clone(), std::move(startCal lback));
159 }
160
161 void Sensor::onSensorReadingChanged()
162 {
163 if (m_polling)
164 m_polling->onSensorReadingChanged();
165 }
166
167 void Sensor::onSensorError()
168 {
169 reportError();
170 }
171
172 void Sensor::onStartRequestCompleted(bool result)
173 {
174 if (m_state != Sensor::SensorState::ACTIVATING)
175 return;
176
177 if (!result || !m_sensorProxy) {
178 reportError();
179 return;
180 }
181
182 updateState(Sensor::SensorState::ACTIVE);
183
184 DCHECK(m_configuration);
185 auto pollCallback = WTF::bind(&Sensor::pollForData, wrapWeakPersistent(this) );
186 m_polling = SensorPollingStrategy::create(m_configuration->frequency, std::m ove(pollCallback), m_sensorProxy->reportingMode());
187 updatePollingStatus();
188 }
189
190 void Sensor::onStopRequestCompleted(bool result)
191 {
192 if (m_state == Sensor::SensorState::IDLE)
193 return;
194
195 if (!result)
196 reportError();
197
198 if (m_sensorProxy)
199 m_sensorProxy->removeObserver(this);
200 }
201
202 void Sensor::pageVisibilityChanged()
203 {
204 updatePollingStatus();
205 }
206
207 void Sensor::startListening()
208 {
209 if (!m_sensorProxy)
210 return;
211
212 if (!m_sensorReading) {
213 m_sensorReading = createSensorReading(getExecutionContext());
214 m_sensorReading->attach(m_sensorProxy);
215 }
216
217 m_sensorProxy->addObserver(this);
218 if (m_sensorProxy->isInitialized()) {
219 auto callback = WTF::bind(&Sensor::onStartRequestCompleted, wrapWeakPers istent(this));
haraken 2016/09/06 05:04:28 WeakPersistent means that the callback may not run
Mikhail 2016/09/06 07:13:58 I think so, if the object is collected there is no
220 DCHECK(m_configuration);
221 m_sensorProxy->addConfiguration(m_configuration->Clone(), std::move(call back));
222 } else {
223 m_sensorProxy->initialize();
224 }
225 }
226
227 void Sensor::stopListening()
228 {
229 if (m_sensorReading) {
230 m_sensorReading->detach();
231 m_sensorReading = nullptr;
232 }
233
234 updateState(Sensor::SensorState::IDLE);
235
236 if (!m_sensorProxy)
237 return;
238
239 if (m_sensorProxy->isInitialized()) {
240 auto callback = WTF::bind(&Sensor::onStopRequestCompleted, wrapWeakPersi stent(this));
haraken 2016/09/06 05:04:28 Ditto.
241 DCHECK(m_configuration);
242 m_sensorProxy->removeConfiguration(m_configuration->Clone(), std::move(c allback));
243 } else {
244 m_sensorProxy->removeObserver(this);
245 }
246 }
247
248 void Sensor::pollForData()
249 {
250 if (m_state != Sensor::SensorState::ACTIVE) {
251 DCHECK(m_polling);
252 m_polling->stopPolling();
253 return;
254 }
255
256 DCHECK(m_sensorProxy);
257 m_sensorProxy->updateReading();
258
259 DCHECK(m_sensorReading);
260 if (m_sensorReading->isReadingUpdated(m_storedData))
261 dispatchEvent(SensorReadingEvent::create(EventTypeNames::change, m_senso rReading));
262
263 m_storedData = m_sensorProxy->reading();
264 }
265
266 void Sensor::updateState(Sensor::SensorState newState)
267 {
268 if (newState == m_state)
269 return;
270 m_state = newState;
99 dispatchEvent(Event::create(EventTypeNames::statechange)); 271 dispatchEvent(Event::create(EventTypeNames::statechange));
100 } 272 updatePollingStatus();
101 273 }
102 void Sensor::suspend() 274
103 { 275 void Sensor::reportError()
104 m_hasEventListener = false; 276 {
105 stopUpdating(); 277 updateState(Sensor::SensorState::ERRORED);
106 } 278 // TODO(Mikhail) : Dispatch Sensor Error event.
107 279 }
108 void Sensor::resume() 280
109 { 281 void Sensor::updatePollingStatus()
110 m_hasEventListener = true; 282 {
111 startUpdating(); 283 if (!m_polling)
112 } 284 return;
113 285
114 void Sensor::stop() 286 if (m_state != Sensor::SensorState::ACTIVE
115 { 287 || page()->visibilityState() != PageVisibilityStateVisible) {
116 m_hasEventListener = false; 288 m_polling->stopPolling();
117 stopUpdating(); 289 } else {
118 } 290 m_polling->startPolling();
119 291 }
120 bool Sensor::hasPendingActivity() const
121 {
122 // Prevent V8 from garbage collecting the wrapper object if there are
123 // event listeners attached to it.
124 return hasEventListeners();
125 }
126
127 DEFINE_TRACE(Sensor)
128 {
129 ActiveDOMObject::trace(visitor);
130 EventTargetWithInlineData::trace(visitor);
131 PlatformEventController::trace(visitor);
132 visitor->trace(m_sensorReading);
133 } 292 }
134 293
135 } // namespace blink 294 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698