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

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

Issue 2503853002: [Sensors] Improvements in fetching reading for sensors with continuous reporting mode (Closed)
Patch Set: Comments from Alex Created 4 years, 1 month 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/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
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
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 =
timvolodine 2016/11/21 16:30:35 nit: maybe better to use a double instead of auto
Mikhail 2016/11/22 12:54:23 the returned type is actually 'std::vector<double>
287 std::max_element(m_frequenciesUsed.begin(), m_frequenciesUsed.end());
timvolodine 2016/11/21 16:30:35 nit: I guess you could use a priority queue (max h
Mikhail 2016/11/22 12:54:23 Done.
288 DCHECK_GT(*it, 0.0);
289
290 double repeatInterval = 1 / *it;
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698