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

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

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

Powered by Google App Engine
This is Rietveld 408576698