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

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

Issue 2051083002: WIP : Generic Sensor API implementation Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Created 4 years, 6 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 "bindings/core/v8/ScriptPromise.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h"
7 #include "core/dom/Document.h" 9 #include "core/dom/Document.h"
8 #include "core/dom/ExceptionCode.h" 10 #include "core/dom/ExceptionCode.h"
9 #include "core/dom/ExecutionContextTask.h" 11 #include "modules/sensor/SensorErrorEvent.h"
10 #include "core/events/Event.h" 12 #include "modules/sensor/SensorPollingStrategy.h"
11
12 #include "modules/sensor/SensorReading.h" 13 #include "modules/sensor/SensorReading.h"
14 #include "modules/sensor/SensorReadingEvent.h"
13 15
14 namespace blink { 16 namespace blink {
15 17
16 Sensor::~Sensor() 18 Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOp tions, device::sensors::blink::SensorType type)
17 {
18 }
19
20 Sensor::Sensor(ExecutionContext* executionContext, const SensorOptions& sensorOp tions)
21 : ActiveScriptWrappable(this) 19 : ActiveScriptWrappable(this)
22 , ActiveDOMObject(executionContext) 20 , ActiveDOMObject(executionContext)
23 , PlatformEventController(toDocument(executionContext)->page())
24 , m_sensorState(SensorState::Idle)
25 , m_sensorReading(nullptr)
26 , m_sensorOptions(sensorOptions) 21 , m_sensorOptions(sensorOptions)
27 { 22 , m_type(type)
23 , m_state(Sensor::SensorState::IDLE)
24 {
25 }
26
27 void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState)
28 {
29 // 1. Check if sensor_instance’s state is neither "idle" nor "errored"
30 if (m_state != Sensor::SensorState::IDLE && m_state != Sensor::SensorState:: ERRORED) {
31 exceptionState.throwDOMException(InvalidStateError, "Invalid State: Sens orState is not idle or errored");
32 return;
33 }
34
35 InitControllerIfNeeded();
36
37 if (!m_controller) {
38 exceptionState.throwDOMException(InvalidStateError, "The Sensor is no lo nger associated to a frame.");
39 return;
40 }
41
42 // 2. Invoke the update state algorithm passing sensor_instance and "activat ing" as the arguments.
43 updateState(Sensor::SensorState::ACTIVATING);
44
45 m_sensorReading = createSensorReading();
46
47 m_controller->addObserver(this);
48 if (m_controller->isInitialized()) {
49 auto callback = bind<bool>(&Sensor::onStartRequestCompleted, WeakPersist entThisPointer<Sensor>(this));
50 m_controller->startConfiguration(createSensorOptions(), std::move(callba ck));
51 } else {
52 m_controller->initialize();
53 }
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, "Invalid State: Sens orState is either idle or errored");
60 return;
61 }
62
63 if (!m_controller) {
64 exceptionState.throwDOMException(InvalidStateError, "The Sensor is no lo nger associated to a frame.");
65 return;
66 }
67 m_sensorReading = nullptr;
68
69 updateState(Sensor::SensorState::IDLE);
70
71 if (m_controller->isInitialized()) {
72 auto callback = bind<bool>(&Sensor::onStopRequestCompleted, WeakPersiste ntThisPointer<Sensor>(this));
73 m_controller->stopConfiguration(createSensorOptions(), std::move(callbac k));
74 } else {
75 m_controller->removeObserver(this);
76 }
77 }
78
79 static String ToString(Sensor::SensorState state) {
80 switch (state) {
81 case Sensor::SensorState::IDLE:
82 return "idle";
83 case Sensor::SensorState::ACTIVATING:
84 return "activating";
85 case Sensor::SensorState::ACTIVE:
86 return "active";
87 case Sensor::SensorState::ERRORED:
88 return "errored";
89 default:
90 ASSERT_NOT_REACHED();
91 }
92 return "idle";
28 } 93 }
29 94
30 // Getters 95 // Getters
31 String Sensor::state() const 96 String Sensor::state() const
32 { 97 {
33 // TODO(riju): Validate the transitions. 98 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 } 99 }
47 100
48 SensorReading* Sensor::reading() const 101 SensorReading* Sensor::reading() const
49 { 102 {
50 return m_sensorReading.get(); 103 return m_sensorReading.get();
51 } 104 }
52 105
53 void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState)
54 {
55
56 if (m_sensorState != SensorState::Idle && m_sensorState != SensorState::Erro red) {
57 exceptionState.throwDOMException(InvalidStateError, "Invalid State: Sens orState is not idle or errored");
58 return;
59 }
60
61 updateState(SensorState::Activating);
62
63 // TODO(riju) : Add Permissions stuff later.
64
65 m_hasEventListener = true;
66
67 // TODO(riju): verify the correct order of onstatechange(active) and the fir st onchange(event).
68 startUpdating();
69 }
70
71 void Sensor::stop(ScriptState* scriptState, ExceptionState& exceptionState)
72 {
73 if (m_sensorState == SensorState::Idle || m_sensorState == SensorState::Erro red) {
74 exceptionState.throwDOMException(InvalidStateError, "Invalid State: Sens orState is either idle or errored");
75 return;
76 }
77
78 m_hasEventListener = false;
79 stopUpdating();
80
81 m_sensorReading.clear();
82 updateState(SensorState::Idle);
83 }
84
85 void Sensor::updateState(SensorState newState)
86 {
87 DCHECK(isMainThread());
88 if (m_sensorState == newState)
89 return;
90
91 m_sensorState = newState;
92 // Notify context that state changed.
93 if (getExecutionContext())
94 getExecutionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&S ensor::notifyStateChange, this));
95 }
96
97 void Sensor::notifyStateChange()
98 {
99 dispatchEvent(Event::create(EventTypeNames::statechange));
100 }
101
102 void Sensor::suspend()
103 {
104 m_hasEventListener = false;
105 stopUpdating();
106 }
107
108 void Sensor::resume()
109 {
110 m_hasEventListener = true;
111 startUpdating();
112 }
113
114 void Sensor::stop()
115 {
116 m_hasEventListener = false;
117 stopUpdating();
118 }
119
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) 106 DEFINE_TRACE(Sensor)
128 { 107 {
108 visitor->trace(m_polling);
109 visitor->trace(m_controller);
110 visitor->trace(m_sensorReading);
129 ActiveDOMObject::trace(visitor); 111 ActiveDOMObject::trace(visitor);
130 EventTargetWithInlineData::trace(visitor); 112 EventTargetWithInlineData::trace(visitor);
131 PlatformEventController::trace(visitor); 113 }
132 visitor->trace(m_sensorReading); 114
115 void Sensor::InitControllerIfNeeded()
116 {
117 if (m_controller)
118 return;
119
120 ExecutionContext* executionContext = getExecutionContext();
121 ASSERT(executionContext && executionContext->isDocument());
122
123 Document* document = toDocument(executionContext);
124 if (!document->frame())
125 return;
126
127 m_controller = SensorProvider::getOrCreateForFrame(*document->frame())->getO rCreateSensor(m_type);
128 }
129
130 void Sensor::addedEventListener(const AtomicString& eventType, RegisteredEventLi stener&)
131 {
132 if (EventTypeNames::change == eventType)
133 updatePollingStatus();
134 }
135
136 void Sensor::removedEventListener(const AtomicString& eventType, const Registere dEventListener&)
137 {
138 if (EventTypeNames::change == eventType)
139 updatePollingStatus();
140 }
141
142 void Sensor::onSensorInitialized()
143 {
144 if (m_state != Sensor::SensorState::ACTIVATING)
145 return;
146
147 if (!m_controller)
148 {
149 reportError();
150 return;
151 }
152
153 auto startCallback = bind<bool>(&Sensor::onStartRequestCompleted, WeakPersis tentThisPointer<Sensor>(this));
154 m_controller->startConfiguration(createSensorOptions(), std::move(startCallb ack));
155 }
156
157 void Sensor::onSensorReadingChanged()
158 {
159 if (m_polling)
160 m_polling->onSensorReadingChanged();
161 }
162
163 void Sensor::onSensorError()
164 {
165 reportError();
166 }
167
168 bool Sensor::hasPendingActivity() const {
169 if (!getExecutionContext() || getExecutionContext()->activeDOMObjectsAreStop ped())
170 return false;
171 return hasEventListeners();
172 }
173
174 void Sensor::onStartRequestCompleted(bool success)
175 {
176 if (m_state != Sensor::SensorState::ACTIVATING)
177 return;
178
179 if (!success || !m_controller) {
180 reportError();
181 return;
182 }
183
184 updateState(Sensor::SensorState::ACTIVE);
185
186 double frequency = options().hasFrequency() ? options().frequency() : 1;
187 auto pollCallback = bind(&Sensor::pollForData, WeakPersistentThisPointer<Sen sor>(this));
188 m_polling = SensorPollingStrategy::create(frequency, std::move(pollCallback) , m_controller->reportingMode());
189 updatePollingStatus();
190 }
191
192 void Sensor::onStopRequestCompleted(bool success)
193 {
194 if (m_state == Sensor::SensorState::IDLE)
195 return;
196
197 if (!success)
198 reportError();
199
200 if (m_controller)
201 m_controller->removeObserver(this);
202 }
203
204 void Sensor::pollForData()
205 {
206 if (m_state != Sensor::SensorState::ACTIVE)
207 {
208 ASSERT(m_polling);
209 m_polling->stopPolling();
210 return;
211 }
212
213 switch (m_sensorReading->updateInternalData())
214 {
215 case SensorReading::Updated:
216 dispatchEvent(SensorReadingEvent::create(EventTypeNames::change, *m_sens orReading));
217 break;
218 case SensorReading::Error:
219 reportError();
220 break;
221 case SensorReading::Same:
222 break;
223 default:
224 ASSERT_NOT_REACHED();
225 }
226 }
227
228 void Sensor::updateState(Sensor::SensorState newState) {
229 if (newState == m_state)
230 return;
231 m_state = newState;
232 dispatchEvent(Event::create(EventTypeNames::statechange));
233 }
234
235 void Sensor::reportError()
236 {
237 updateState(Sensor::SensorState::ERRORED);
238 dispatchEvent(SensorErrorEvent::create(EventTypeNames::error));
239 }
240
241 void Sensor::updatePollingStatus()
242 {
243 if (!m_polling)
244 return;
245
246 if (m_state != Sensor::SensorState::ACTIVE || !hasEventListeners(EventTypeNa mes::change)) {
247 // Do not poll if noone is listening 'onchange' event.
248 m_polling->stopPolling();
249 } else {
250 m_polling->startPolling();
251 }
133 } 252 }
134 253
135 } // namespace blink 254 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/sensor/Sensor.h ('k') | third_party/WebKit/Source/modules/sensor/SensorController.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698