Chromium Code Reviews| 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/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 Loading... | |
| 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 auto now = WTF::MonotonicallyIncreasingTime(); | |
|
Reilly Grant (use Gerrit)
2017/05/11 18:28:12
nit: use double here as the type of the return val
Mikhail
2017/05/12 08:42:13
Done.
| |
| 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 Loading... | |
| 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 Loading... | |
| 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(Mikhail) : We need to find out an algorithm for resulting | |
| 274 // polling frequency. | |
|
Reilly Grant (use Gerrit)
2017/05/10 14:53:28
Please create an issue for this.
Mikhail
2017/05/11 10:46:20
Done https://bugs.chromium.org/p/chromium/issues/d
Reilly Grant (use Gerrit)
2017/05/11 18:28:12
Please update the comment with the issue number. T
Mikhail
2017/05/12 08:42:13
Done.
| |
| 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 |
| OLD | NEW |