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/SensorProxy.h" | 5 #include "modules/sensor/SensorProxy.h" |
6 | 6 |
7 #include "core/frame/LocalFrame.h" | 7 #include "core/frame/LocalFrame.h" |
8 #include "modules/sensor/SensorProviderProxy.h" | 8 #include "modules/sensor/SensorProviderProxy.h" |
9 #include "modules/sensor/SensorReading.h" | 9 #include "modules/sensor/SensorReading.h" |
10 #include "platform/mojo/MojoHelper.h" | 10 #include "platform/mojo/MojoHelper.h" |
11 #include "public/platform/Platform.h" | 11 #include "public/platform/Platform.h" |
12 | 12 |
13 using namespace device::mojom::blink; | 13 using namespace device::mojom::blink; |
14 | 14 |
15 namespace blink { | 15 namespace blink { |
16 | 16 |
17 SensorProxy::SensorProxy(SensorType sensorType, | 17 SensorProxy::SensorProxy(SensorType sensorType, |
18 SensorProviderProxy* provider, | 18 SensorProviderProxy* provider, |
19 Page* page, | |
19 std::unique_ptr<SensorReadingFactory> readingFactory) | 20 std::unique_ptr<SensorReadingFactory> readingFactory) |
20 : m_type(sensorType), | 21 : PageVisibilityObserver(page), |
22 m_type(sensorType), | |
21 m_mode(ReportingMode::CONTINUOUS), | 23 m_mode(ReportingMode::CONTINUOUS), |
22 m_provider(provider), | 24 m_provider(provider), |
23 m_clientBinding(this), | 25 m_clientBinding(this), |
24 m_state(SensorProxy::Uninitialized), | 26 m_state(SensorProxy::Uninitialized), |
25 m_suspended(false), | 27 m_suspended(false), |
26 m_readingFactory(std::move(readingFactory)), | 28 m_readingFactory(std::move(readingFactory)), |
27 m_maximumFrequency(0.0) {} | 29 m_maximumFrequency(0.0), |
30 m_timer(this, &SensorProxy::onTimerFired) {} | |
28 | 31 |
29 SensorProxy::~SensorProxy() {} | 32 SensorProxy::~SensorProxy() {} |
30 | 33 |
31 void SensorProxy::dispose() { | 34 void SensorProxy::dispose() { |
32 m_clientBinding.Close(); | 35 m_clientBinding.Close(); |
33 } | 36 } |
34 | 37 |
35 DEFINE_TRACE(SensorProxy) { | 38 DEFINE_TRACE(SensorProxy) { |
36 visitor->trace(m_reading); | 39 visitor->trace(m_reading); |
37 visitor->trace(m_observers); | 40 visitor->trace(m_observers); |
38 visitor->trace(m_provider); | 41 visitor->trace(m_provider); |
42 PageVisibilityObserver::trace(visitor); | |
39 } | 43 } |
40 | 44 |
41 void SensorProxy::addObserver(Observer* observer) { | 45 void SensorProxy::addObserver(Observer* observer) { |
42 if (!m_observers.contains(observer)) | 46 if (!m_observers.contains(observer)) |
43 m_observers.add(observer); | 47 m_observers.add(observer); |
44 } | 48 } |
45 | 49 |
46 void SensorProxy::removeObserver(Observer* observer) { | 50 void SensorProxy::removeObserver(Observer* observer) { |
47 m_observers.remove(observer); | 51 m_observers.remove(observer); |
48 } | 52 } |
(...skipping 11 matching lines...) Expand all Loading... | |
60 auto callback = convertToBaseCallback( | 64 auto callback = convertToBaseCallback( |
61 WTF::bind(&SensorProxy::onSensorCreated, wrapWeakPersistent(this))); | 65 WTF::bind(&SensorProxy::onSensorCreated, wrapWeakPersistent(this))); |
62 m_provider->sensorProvider()->GetSensor(m_type, mojo::GetProxy(&m_sensor), | 66 m_provider->sensorProvider()->GetSensor(m_type, mojo::GetProxy(&m_sensor), |
63 callback); | 67 callback); |
64 } | 68 } |
65 | 69 |
66 void SensorProxy::addConfiguration( | 70 void SensorProxy::addConfiguration( |
67 SensorConfigurationPtr configuration, | 71 SensorConfigurationPtr configuration, |
68 std::unique_ptr<Function<void(bool)>> callback) { | 72 std::unique_ptr<Function<void(bool)>> callback) { |
69 DCHECK(isInitialized()); | 73 DCHECK(isInitialized()); |
74 auto wrapper = WTF::bind(&SensorProxy::onAddConfigurationCompleted, | |
75 wrapWeakPersistent(this), configuration->frequency, | |
76 passed(std::move(callback))); | |
70 m_sensor->AddConfiguration(std::move(configuration), | 77 m_sensor->AddConfiguration(std::move(configuration), |
71 convertToBaseCallback(std::move(callback))); | 78 convertToBaseCallback(std::move(wrapper))); |
72 } | 79 } |
73 | 80 |
74 void SensorProxy::removeConfiguration( | 81 void SensorProxy::removeConfiguration(SensorConfigurationPtr configuration) { |
75 SensorConfigurationPtr configuration, | |
76 std::unique_ptr<Function<void(bool)>> callback) { | |
77 DCHECK(isInitialized()); | 82 DCHECK(isInitialized()); |
83 auto callback = WTF::bind(&SensorProxy::onRemoveConfigurationCompleted, | |
84 wrapWeakPersistent(this), configuration->frequency); | |
78 m_sensor->RemoveConfiguration(std::move(configuration), | 85 m_sensor->RemoveConfiguration(std::move(configuration), |
79 convertToBaseCallback(std::move(callback))); | 86 convertToBaseCallback(std::move(callback))); |
80 } | 87 } |
81 | 88 |
82 void SensorProxy::suspend() { | 89 void SensorProxy::suspend() { |
83 DCHECK(isInitialized()); | 90 DCHECK(isInitialized()); |
84 if (m_suspended) | 91 if (m_suspended) |
85 return; | 92 return; |
86 | 93 |
87 m_sensor->Suspend(); | 94 m_sensor->Suspend(); |
88 m_suspended = true; | 95 m_suspended = true; |
96 | |
97 if (usesPollingTimer()) | |
98 updatePollingStatus(); | |
99 | |
100 for (Observer* observer : m_observers) | |
101 observer->onSuspended(); | |
89 } | 102 } |
90 | 103 |
91 void SensorProxy::resume() { | 104 void SensorProxy::resume() { |
92 DCHECK(isInitialized()); | 105 DCHECK(isInitialized()); |
93 if (!m_suspended) | 106 if (!m_suspended) |
94 return; | 107 return; |
95 | 108 |
96 m_sensor->Resume(); | 109 m_sensor->Resume(); |
97 m_suspended = false; | 110 m_suspended = false; |
111 | |
112 if (usesPollingTimer()) | |
113 updatePollingStatus(); | |
98 } | 114 } |
99 | 115 |
100 const device::mojom::blink::SensorConfiguration* SensorProxy::defaultConfig() | 116 const SensorConfiguration* SensorProxy::defaultConfig() const { |
101 const { | |
102 DCHECK(isInitialized()); | 117 DCHECK(isInitialized()); |
103 return m_defaultConfig.get(); | 118 return m_defaultConfig.get(); |
104 } | 119 } |
105 | 120 |
121 bool SensorProxy::usesPollingTimer() const { | |
122 return isInitialized() && (m_mode == ReportingMode::CONTINUOUS); | |
123 } | |
124 | |
106 void SensorProxy::updateSensorReading() { | 125 void SensorProxy::updateSensorReading() { |
107 DCHECK(isInitialized()); | 126 DCHECK(isInitialized()); |
108 DCHECK(m_readingFactory); | 127 DCHECK(m_readingFactory); |
109 int readAttempts = 0; | 128 int readAttempts = 0; |
110 const int kMaxReadAttemptsCount = 10; | 129 const int kMaxReadAttemptsCount = 10; |
111 device::SensorReading readingData; | 130 device::SensorReading readingData; |
112 while (!tryReadFromBuffer(readingData)) { | 131 while (!tryReadFromBuffer(readingData)) { |
113 if (++readAttempts == kMaxReadAttemptsCount) { | 132 if (++readAttempts == kMaxReadAttemptsCount) { |
114 handleSensorError(); | 133 handleSensorError(); |
115 return; | 134 return; |
116 } | 135 } |
117 } | 136 } |
118 | 137 |
119 m_reading = m_readingFactory->createSensorReading(readingData); | 138 m_reading = m_readingFactory->createSensorReading(readingData); |
139 | |
140 for (Observer* observer : m_observers) | |
141 observer->onSensorReadingChanged(); | |
120 } | 142 } |
121 | 143 |
122 void SensorProxy::RaiseError() { | 144 void SensorProxy::RaiseError() { |
123 handleSensorError(); | 145 handleSensorError(); |
124 } | 146 } |
125 | 147 |
126 void SensorProxy::SensorReadingChanged() { | 148 void SensorProxy::SensorReadingChanged() { |
127 for (Observer* observer : m_observers) | 149 updateSensorReading(); |
128 observer->onSensorReadingChanged(); | 150 } |
151 | |
152 void SensorProxy::pageVisibilityChanged() { | |
153 if (!isInitialized()) | |
154 return; | |
155 | |
156 if (page()->visibilityState() != PageVisibilityStateVisible) { | |
157 suspend(); | |
158 } else { | |
159 resume(); | |
160 } | |
129 } | 161 } |
130 | 162 |
131 void SensorProxy::handleSensorError(ExceptionCode code, | 163 void SensorProxy::handleSensorError(ExceptionCode code, |
132 String sanitizedMessage, | 164 String sanitizedMessage, |
133 String unsanitizedMessage) { | 165 String unsanitizedMessage) { |
134 if (!Platform::current()) { | 166 if (!Platform::current()) { |
135 // TODO(rockot): Remove this hack once renderer shutdown sequence is fixed. | 167 // TODO(rockot): Remove this hack once renderer shutdown sequence is fixed. |
136 return; | 168 return; |
137 } | 169 } |
138 | 170 |
171 if (usesPollingTimer()) { // Stop polling. | |
172 m_frequenciesUsed.clear(); | |
173 updatePollingStatus(); | |
174 } | |
175 | |
139 m_state = Uninitialized; | 176 m_state = Uninitialized; |
140 // The m_sensor.reset() will release all callbacks and its bound parameters, | 177 // The m_sensor.reset() will release all callbacks and its bound parameters, |
141 // therefore, handleSensorError accepts messages by value. | 178 // therefore, handleSensorError accepts messages by value. |
142 m_sensor.reset(); | 179 m_sensor.reset(); |
143 m_sharedBuffer.reset(); | 180 m_sharedBuffer.reset(); |
144 m_sharedBufferHandle.reset(); | 181 m_sharedBufferHandle.reset(); |
145 m_defaultConfig.reset(); | 182 m_defaultConfig.reset(); |
146 m_clientBinding.Close(); | 183 m_clientBinding.Close(); |
147 m_reading = nullptr; | 184 m_reading = nullptr; |
148 | 185 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 WTF::bind(&SensorProxy::handleSensorError, wrapWeakPersistent(this), | 225 WTF::bind(&SensorProxy::handleSensorError, wrapWeakPersistent(this), |
189 UnknownError, String("Internal error"), String()); | 226 UnknownError, String("Internal error"), String()); |
190 m_sensor.set_connection_error_handler( | 227 m_sensor.set_connection_error_handler( |
191 convertToBaseCallback(std::move(errorCallback))); | 228 convertToBaseCallback(std::move(errorCallback))); |
192 | 229 |
193 m_state = Initialized; | 230 m_state = Initialized; |
194 for (Observer* observer : m_observers) | 231 for (Observer* observer : m_observers) |
195 observer->onSensorInitialized(); | 232 observer->onSensorInitialized(); |
196 } | 233 } |
197 | 234 |
235 void SensorProxy::onAddConfigurationCompleted( | |
236 double frequency, | |
237 std::unique_ptr<Function<void(bool)>> callback, | |
238 bool result) { | |
239 if (usesPollingTimer() && result) { | |
240 m_frequenciesUsed.append(frequency); | |
241 updatePollingStatus(); | |
242 } | |
243 | |
244 (*callback)(result); | |
245 } | |
246 | |
247 void SensorProxy::onRemoveConfigurationCompleted(double frequency, | |
248 bool result) { | |
249 if (!result) | |
250 DVLOG(1) << "Failure at sensor configuration removal"; | |
251 | |
252 if (!usesPollingTimer()) | |
253 return; | |
254 | |
255 size_t index = m_frequenciesUsed.find(frequency); | |
256 if (index == kNotFound) { | |
257 // Could happen e.g. if 'handleSensorError' was called before. | |
258 return; | |
259 } | |
260 | |
261 m_frequenciesUsed.remove(index); | |
262 updatePollingStatus(); | |
263 } | |
264 | |
198 bool SensorProxy::tryReadFromBuffer(device::SensorReading& result) { | 265 bool SensorProxy::tryReadFromBuffer(device::SensorReading& result) { |
199 DCHECK(isInitialized()); | 266 DCHECK(isInitialized()); |
200 const ReadingBuffer* buffer = | 267 const ReadingBuffer* buffer = |
201 static_cast<const ReadingBuffer*>(m_sharedBuffer.get()); | 268 static_cast<const ReadingBuffer*>(m_sharedBuffer.get()); |
202 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value(); | 269 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value(); |
203 auto version = seqlock.ReadBegin(); | 270 auto version = seqlock.ReadBegin(); |
204 auto readingData = buffer->reading; | 271 auto readingData = buffer->reading; |
205 if (seqlock.ReadRetry(version)) | 272 if (seqlock.ReadRetry(version)) |
206 return false; | 273 return false; |
207 result = readingData; | 274 result = readingData; |
208 return true; | 275 return true; |
209 } | 276 } |
210 | 277 |
278 void SensorProxy::updatePollingStatus() { | |
279 DCHECK(usesPollingTimer()); | |
280 | |
281 if (m_suspended || m_frequenciesUsed.isEmpty()) { | |
282 m_timer.stop(); | |
283 return; | |
284 } | |
285 | |
286 auto it = | |
287 std::max_element(m_frequenciesUsed.begin(), m_frequenciesUsed.end()); | |
288 DCHECK_GT(*it, 0.0); | |
289 | |
290 double repeatInterval = 1 / *it; | |
timvolodine
2016/11/15 18:27:56
does this mean that if I register a sensor with a
Mikhail
2016/11/15 19:19:00
not actually, the given frequency will remain for
| |
291 if (!m_timer.isActive() || m_timer.repeatInterval() != repeatInterval) { | |
292 updateSensorReading(); | |
293 m_timer.startRepeating(repeatInterval, BLINK_FROM_HERE); | |
294 } | |
295 } | |
296 | |
297 void SensorProxy::onTimerFired(TimerBase*) { | |
298 updateSensorReading(); | |
299 } | |
300 | |
211 } // namespace blink | 301 } // namespace blink |
OLD | NEW |