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

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

Issue 2870073002: [Sensors] Decouple sensor readings update from rAF (Closed)
Patch Set: [Sensors] Decouple sensor readings update from rAF Created 3 years, 7 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" 7 #include "core/dom/TaskRunnerHelper.h"
8 #include "core/frame/LocalFrame.h" 8 #include "core/frame/LocalFrame.h"
9 #include "modules/sensor/SensorProviderProxy.h" 9 #include "modules/sensor/SensorProviderProxy.h"
10 #include "modules/sensor/SensorReadingUpdater.h"
11 #include "platform/mojo/MojoHelper.h" 10 #include "platform/mojo/MojoHelper.h"
12 #include "public/platform/Platform.h" 11 #include "public/platform/Platform.h"
13 12
14 using namespace device::mojom::blink; 13 using namespace device::mojom::blink;
15 14
16 namespace blink { 15 namespace blink {
17 16
18 SensorProxy::SensorProxy(SensorType sensor_type, 17 SensorProxy::SensorProxy(SensorType sensor_type,
19 SensorProviderProxy* provider, 18 SensorProviderProxy* provider,
20 Page* page) 19 Page* page)
21 : PageVisibilityObserver(page), 20 : PageVisibilityObserver(page),
22 type_(sensor_type), 21 type_(sensor_type),
23 mode_(ReportingMode::CONTINUOUS), 22 mode_(ReportingMode::CONTINUOUS),
24 provider_(provider), 23 provider_(provider),
25 client_binding_(this), 24 client_binding_(this),
26 state_(SensorProxy::kUninitialized), 25 state_(SensorProxy::kUninitialized),
27 suspended_(false) {} 26 suspended_(false),
27 polling_timer_(TaskRunnerHelper::Get(TaskType::kSensor,
28 provider->GetSupplementable()),
29 this,
30 &SensorProxy::OnPollingTimer) {}
28 31
29 SensorProxy::~SensorProxy() {} 32 SensorProxy::~SensorProxy() {}
30 33
31 void SensorProxy::Dispose() { 34 void SensorProxy::Dispose() {
32 client_binding_.Close(); 35 client_binding_.Close();
33 } 36 }
34 37
35 DEFINE_TRACE(SensorProxy) { 38 DEFINE_TRACE(SensorProxy) {
36 visitor->Trace(reading_updater_);
37 visitor->Trace(observers_); 39 visitor->Trace(observers_);
38 visitor->Trace(provider_); 40 visitor->Trace(provider_);
39 PageVisibilityObserver::Trace(visitor); 41 PageVisibilityObserver::Trace(visitor);
40 } 42 }
41 43
42 void SensorProxy::AddObserver(Observer* observer) { 44 void SensorProxy::AddObserver(Observer* observer) {
43 if (!observers_.Contains(observer)) 45 if (!observers_.Contains(observer))
44 observers_.insert(observer); 46 observers_.insert(observer);
45 } 47 }
46 48
(...skipping 10 matching lines...) Expand all
57 return; 59 return;
58 } 60 }
59 61
60 state_ = kInitializing; 62 state_ = kInitializing;
61 auto callback = ConvertToBaseCallback( 63 auto callback = ConvertToBaseCallback(
62 WTF::Bind(&SensorProxy::OnSensorCreated, WrapWeakPersistent(this))); 64 WTF::Bind(&SensorProxy::OnSensorCreated, WrapWeakPersistent(this)));
63 provider_->GetSensorProvider()->GetSensor(type_, mojo::MakeRequest(&sensor_), 65 provider_->GetSensorProvider()->GetSensor(type_, mojo::MakeRequest(&sensor_),
64 callback); 66 callback);
65 } 67 }
66 68
67 bool SensorProxy::IsActive() const {
68 return IsInitialized() && !suspended_ && !frequencies_used_.IsEmpty();
69 }
70
71 void SensorProxy::AddConfiguration( 69 void SensorProxy::AddConfiguration(
72 SensorConfigurationPtr configuration, 70 SensorConfigurationPtr configuration,
73 std::unique_ptr<Function<void(bool)>> callback) { 71 std::unique_ptr<Function<void(bool)>> callback) {
74 DCHECK(IsInitialized()); 72 DCHECK(IsInitialized());
75 auto wrapper = WTF::Bind(&SensorProxy::OnAddConfigurationCompleted, 73 auto wrapper = WTF::Bind(&SensorProxy::OnAddConfigurationCompleted,
76 WrapWeakPersistent(this), configuration->frequency, 74 WrapWeakPersistent(this), configuration->frequency,
77 WTF::Passed(std::move(callback))); 75 WTF::Passed(std::move(callback)));
78 sensor_->AddConfiguration(std::move(configuration), 76 sensor_->AddConfiguration(std::move(configuration),
79 ConvertToBaseCallback(std::move(wrapper))); 77 ConvertToBaseCallback(std::move(wrapper)));
80 } 78 }
81 79
82 void SensorProxy::RemoveConfiguration(SensorConfigurationPtr configuration) { 80 void SensorProxy::RemoveConfiguration(SensorConfigurationPtr configuration) {
83 DCHECK(IsInitialized()); 81 DCHECK(IsInitialized());
84 auto callback = WTF::Bind(&SensorProxy::OnRemoveConfigurationCompleted, 82 auto callback = WTF::Bind(&SensorProxy::OnRemoveConfigurationCompleted,
85 WrapWeakPersistent(this), configuration->frequency); 83 WrapWeakPersistent(this), configuration->frequency);
86 sensor_->RemoveConfiguration(std::move(configuration), 84 sensor_->RemoveConfiguration(std::move(configuration),
87 ConvertToBaseCallback(std::move(callback))); 85 ConvertToBaseCallback(std::move(callback)));
88 } 86 }
89 87
90 void SensorProxy::Suspend() { 88 void SensorProxy::Suspend() {
91 DCHECK(IsInitialized()); 89 DCHECK(IsInitialized());
92 if (suspended_) 90 if (suspended_)
93 return; 91 return;
94 92
95 sensor_->Suspend(); 93 sensor_->Suspend();
96 suspended_ = true; 94 suspended_ = true;
95 UpdatePollingStatus();
97 } 96 }
98 97
99 void SensorProxy::Resume() { 98 void SensorProxy::Resume() {
100 DCHECK(IsInitialized()); 99 DCHECK(IsInitialized());
101 if (!suspended_) 100 if (!suspended_)
102 return; 101 return;
103 102
104 sensor_->Resume(); 103 sensor_->Resume();
105 suspended_ = false; 104 suspended_ = false;
106 105 UpdatePollingStatus();
107 if (IsActive())
108 reading_updater_->Start();
109 } 106 }
110 107
111 const SensorConfiguration* SensorProxy::DefaultConfig() const { 108 const SensorConfiguration* SensorProxy::DefaultConfig() const {
112 DCHECK(IsInitialized()); 109 DCHECK(IsInitialized());
113 return default_config_.get(); 110 return default_config_.get();
114 } 111 }
115 112
116 Document* SensorProxy::GetDocument() const {
117 return provider_->GetSupplementable()->GetDocument();
118 }
119
120 void SensorProxy::UpdateSensorReading() { 113 void SensorProxy::UpdateSensorReading() {
121 DCHECK(IsInitialized()); 114 DCHECK(IsInitialized());
122 int read_attempts = 0; 115 int read_attempts = 0;
123 const int kMaxReadAttemptsCount = 10; 116 const int kMaxReadAttemptsCount = 10;
124 device::SensorReading reading_data; 117 device::SensorReading reading_data;
125 while (!TryReadFromBuffer(reading_data)) { 118 while (!TryReadFromBuffer(reading_data)) {
126 if (++read_attempts == kMaxReadAttemptsCount) { 119 if (++read_attempts == kMaxReadAttemptsCount) {
127 HandleSensorError(); 120 HandleSensorError();
128 return; 121 return;
129 } 122 }
130 } 123 }
131 124
132 if (reading_.timestamp != reading_data.timestamp) { 125 if (reading_.timestamp != reading_data.timestamp) {
133 reading_ = reading_data; 126 reading_ = reading_data;
127 double now = WTF::MonotonicallyIncreasingTime();
134 for (Observer* observer : observers_) 128 for (Observer* observer : observers_)
135 observer->OnSensorReadingChanged(); 129 observer->OnSensorReadingChanged(now);
136 } 130 }
137 } 131 }
138 132
139 void SensorProxy::NotifySensorChanged(double timestamp) {
140 // This notification leads to sync 'onchange' event sending, so
141 // we must cache m_observers as it can be modified within event handlers.
142 auto copy = observers_;
143 for (Observer* observer : copy)
144 observer->NotifySensorChanged(timestamp);
145 }
146
147 void SensorProxy::RaiseError() { 133 void SensorProxy::RaiseError() {
148 HandleSensorError(); 134 HandleSensorError();
149 } 135 }
150 136
151 void SensorProxy::SensorReadingChanged() { 137 void SensorProxy::SensorReadingChanged() {
152 DCHECK_EQ(ReportingMode::ON_CHANGE, mode_); 138 DCHECK_EQ(ReportingMode::ON_CHANGE, mode_);
153 if (IsActive()) 139 UpdateSensorReading();
154 reading_updater_->Start();
155 } 140 }
156 141
157 void SensorProxy::PageVisibilityChanged() { 142 void SensorProxy::PageVisibilityChanged() {
158 if (!IsInitialized()) 143 if (!IsInitialized())
159 return; 144 return;
160 145
161 if (GetPage()->VisibilityState() != kPageVisibilityStateVisible) { 146 if (GetPage()->VisibilityState() != kPageVisibilityStateVisible) {
162 Suspend(); 147 Suspend();
163 } else { 148 } else {
164 Resume(); 149 Resume();
165 } 150 }
166 } 151 }
167 152
168 void SensorProxy::HandleSensorError() { 153 void SensorProxy::HandleSensorError() {
169 state_ = kUninitialized; 154 state_ = kUninitialized;
170 frequencies_used_.clear(); 155 frequencies_used_.clear();
171 reading_ = device::SensorReading(); 156 reading_ = device::SensorReading();
157 UpdatePollingStatus();
172 158
173 // The m_sensor.reset() will release all callbacks and its bound parameters, 159 // The m_sensor.reset() will release all callbacks and its bound parameters,
174 // therefore, handleSensorError accepts messages by value. 160 // therefore, handleSensorError accepts messages by value.
175 sensor_.reset(); 161 sensor_.reset();
176 shared_buffer_.reset(); 162 shared_buffer_.reset();
177 shared_buffer_handle_.reset(); 163 shared_buffer_handle_.reset();
178 default_config_.reset(); 164 default_config_.reset();
179 client_binding_.Close(); 165 client_binding_.Close();
180 166
181 auto copy = observers_; 167 auto copy = observers_;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 DCHECK_GE(frequency_limits_.second, frequency_limits_.first); 208 DCHECK_GE(frequency_limits_.second, frequency_limits_.first);
223 constexpr double kMaxAllowedFrequency = 209 constexpr double kMaxAllowedFrequency =
224 SensorConfiguration::kMaxAllowedFrequency; 210 SensorConfiguration::kMaxAllowedFrequency;
225 DCHECK_GE(kMaxAllowedFrequency, frequency_limits_.second); 211 DCHECK_GE(kMaxAllowedFrequency, frequency_limits_.second);
226 212
227 auto error_callback = 213 auto error_callback =
228 WTF::Bind(&SensorProxy::HandleSensorError, WrapWeakPersistent(this)); 214 WTF::Bind(&SensorProxy::HandleSensorError, WrapWeakPersistent(this));
229 sensor_.set_connection_error_handler( 215 sensor_.set_connection_error_handler(
230 ConvertToBaseCallback(std::move(error_callback))); 216 ConvertToBaseCallback(std::move(error_callback)));
231 217
232 reading_updater_ = SensorReadingUpdater::Create(this, mode_);
233
234 state_ = kInitialized; 218 state_ = kInitialized;
235 219
236 for (Observer* observer : observers_) 220 for (Observer* observer : observers_)
237 observer->OnSensorInitialized(); 221 observer->OnSensorInitialized();
238 } 222 }
239 223
240 void SensorProxy::OnAddConfigurationCompleted( 224 void SensorProxy::OnAddConfigurationCompleted(
241 double frequency, 225 double frequency,
242 std::unique_ptr<Function<void(bool)>> callback, 226 std::unique_ptr<Function<void(bool)>> callback,
243 bool result) { 227 bool result) {
244 if (result) { 228 if (result) {
245 frequencies_used_.push_back(frequency); 229 frequencies_used_.push_back(frequency);
246 std::sort(frequencies_used_.begin(), frequencies_used_.end()); 230 std::sort(frequencies_used_.begin(), frequencies_used_.end());
247 if (IsActive()) 231 UpdatePollingStatus();
248 reading_updater_->Start();
249 } 232 }
250 233
251 (*callback)(result); 234 (*callback)(result);
252 } 235 }
253 236
254 void SensorProxy::OnRemoveConfigurationCompleted(double frequency, 237 void SensorProxy::OnRemoveConfigurationCompleted(double frequency,
255 bool result) { 238 bool result) {
256 if (!result) 239 if (!result)
257 DVLOG(1) << "Failure at sensor configuration removal"; 240 DVLOG(1) << "Failure at sensor configuration removal";
258 241
(...skipping 12 matching lines...) Expand all
271 static_cast<const ReadingBuffer*>(shared_buffer_.get()); 254 static_cast<const ReadingBuffer*>(shared_buffer_.get());
272 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value(); 255 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value();
273 auto version = seqlock.ReadBegin(); 256 auto version = seqlock.ReadBegin();
274 auto reading_data = buffer->reading; 257 auto reading_data = buffer->reading;
275 if (seqlock.ReadRetry(version)) 258 if (seqlock.ReadRetry(version))
276 return false; 259 return false;
277 result = reading_data; 260 result = reading_data;
278 return true; 261 return true;
279 } 262 }
280 263
264 void SensorProxy::OnPollingTimer(TimerBase*) {
265 UpdateSensorReading();
266 }
267
268 void SensorProxy::UpdatePollingStatus() {
269 bool start_polling = (mode_ == ReportingMode::CONTINUOUS) &&
270 IsInitialized() && !suspended_ &&
271 !frequencies_used_.IsEmpty();
272 if (start_polling) {
273 // TODO(crbug/721297) : We need to find out an algorithm for resulting
274 // polling frequency.
275 polling_timer_.StartRepeating(1 / frequencies_used_.back(),
276 BLINK_FROM_HERE);
277 } else {
278 polling_timer_.Stop();
279 }
280 }
281
281 } // namespace blink 282 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698