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

Side by Side Diff: content/renderer/device_sensors/device_sensor_event_pump.h

Issue 2885203004: Refactor content/renderer/device_sensors to use device/generic_sensor instead of device/sensors (Closed)
Patch Set: updated content/renderer/BUILD.gn 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #ifndef CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_ 5 #ifndef CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
6 #define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_ 6 #define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
7 7
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
8 #include "base/bind.h" 12 #include "base/bind.h"
9 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
10 #include "base/macros.h" 14 #include "base/macros.h"
11 #include "base/memory/shared_memory.h"
12 #include "base/time/time.h" 15 #include "base/time/time.h"
13 #include "base/timer/timer.h" 16 #include "base/timer/timer.h"
14 #include "content/public/common/service_names.mojom.h" 17 #include "content/public/common/service_names.mojom.h"
15 #include "content/public/renderer/platform_event_observer.h" 18 #include "content/public/renderer/platform_event_observer.h"
16 #include "content/renderer/render_thread_impl.h" 19 #include "content/renderer/render_thread_impl.h"
20 #include "device/generic_sensor/public/cpp/sensor_reading.h"
21 #include "device/generic_sensor/public/interfaces/sensor.mojom.h"
22 #include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h"
23 #include "mojo/public/cpp/bindings/binding.h"
17 #include "mojo/public/cpp/system/platform_handle.h" 24 #include "mojo/public/cpp/system/platform_handle.h"
18 #include "services/device/public/interfaces/constants.mojom.h" 25 #include "services/device/public/interfaces/constants.mojom.h"
19 #include "services/service_manager/public/cpp/connector.h" 26 #include "services/service_manager/public/cpp/connector.h"
20 27
21 namespace content { 28 namespace content {
22 29
23 template <typename Base, typename MojoInterface> 30 template <typename ListenerType>
24 class CONTENT_EXPORT DeviceSensorMojoClientMixin : public Base { 31 class CONTENT_EXPORT DeviceSensorEventPump
32 : NON_EXPORTED_BASE(public PlatformEventObserver<ListenerType>) {
25 public: 33 public:
26 template <typename... Args> 34 // PlatformEventObserver:
27 explicit DeviceSensorMojoClientMixin(Args&&... args) 35 void Start(blink::WebPlatformEventListener* listener) override {
28 : Base(std::forward<Args>(args)...) { 36 DVLOG(2) << "requested start";
29 auto request = mojo::MakeRequest(&mojo_interface_); 37
38 if (state_ != PumpState::STOPPED)
39 return;
40
41 DCHECK(!timer_.IsRunning());
42
43 PlatformEventObserver<ListenerType>::Start(listener);
44 state_ = PumpState::PENDING_START;
45 }
46
47 // PlatformEventObserver:
48 void Stop() override {
49 DVLOG(2) << "requested stop";
50
51 if (state_ == PumpState::STOPPED)
52 return;
53
54 DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) ||
55 (state_ == PumpState::RUNNING && timer_.IsRunning()));
56
57 if (timer_.IsRunning())
58 timer_.Stop();
59
60 PlatformEventObserver<ListenerType>::Stop();
61 state_ = PumpState::STOPPED;
62 }
63
64 // PlatformEventObserver:
65 void SendStopMessage() override {
66 sensors_.clear();
67 num_sensors_tried_ = 0;
68 num_available_sensors_ = 0;
69 }
70
71 protected:
72 explicit DeviceSensorEventPump(RenderThread* thread)
73 : PlatformEventObserver<ListenerType>(thread),
74 pump_delay_microseconds_(kDefaultPumpDelayMicroseconds),
75 num_sensors_tried_(0),
76 num_available_sensors_(0),
77 state_(PumpState::STOPPED) {
78 auto request = mojo::MakeRequest(&sensor_provider_);
30 79
31 // When running layout tests, those observers should not listen to the 80 // When running layout tests, those observers should not listen to the
32 // actual hardware changes. In order to make that happen, don't connect 81 // actual hardware changes. In order to make that happen, don't connect
33 // the other end of the mojo pipe to anything. 82 // the other end of the mojo pipe to anything.
34 //
35 // TODO(sammc): Remove this when JS layout test support for shared buffers
36 // is ready and the layout tests are converted to use that for mocking.
37 if (RenderThreadImpl::current() && 83 if (RenderThreadImpl::current() &&
38 !RenderThreadImpl::current()->layout_test_mode()) { 84 !RenderThreadImpl::current()->layout_test_mode()) {
39 RenderThread::Get()->GetConnector()->BindInterface( 85 RenderThread::Get()->GetConnector()->BindInterface(
40 device::mojom::kServiceName, std::move(request)); 86 device::mojom::kServiceName, std::move(request));
41 } 87 sensor_provider_.set_connection_error_handler(
42 } 88 base::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
43 89 base::Unretained(this)));
44 void SendStartMessage() override { 90 }
45 mojo_interface_->StartPolling( 91 }
46 base::Bind(&DeviceSensorMojoClientMixin<Base, MojoInterface>::DidStart,
47 base::Unretained(this)));
48 }
49 void SendStopMessage() override { mojo_interface_->StopPolling(); }
50
51 protected:
52 void DidStart(mojo::ScopedSharedBufferHandle buffer_handle) {
53 Base::DidStart(std::move(buffer_handle));
54 }
55
56 private:
57 mojo::InterfacePtr<MojoInterface> mojo_interface_;
58 };
59
60 template <typename ListenerType>
61 class CONTENT_EXPORT DeviceSensorEventPump
62 : NON_EXPORTED_BASE(public PlatformEventObserver<ListenerType>) {
63 public:
64 // Default rate for firing events.
65 static const int kDefaultPumpFrequencyHz = 60;
66 static const int kDefaultPumpDelayMicroseconds =
67 base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz;
68
69 // PlatformEventObserver
70 void Start(blink::WebPlatformEventListener* listener) override {
71 DVLOG(2) << "requested start";
72
73 if (state_ != STOPPED)
74 return;
75
76 DCHECK(!timer_.IsRunning());
77
78 PlatformEventObserver<ListenerType>::Start(listener);
79 state_ = PENDING_START;
80 }
81
82 void Stop() override {
83 DVLOG(2) << "stop";
84
85 if (state_ == STOPPED)
86 return;
87
88 DCHECK((state_ == PENDING_START && !timer_.IsRunning()) ||
89 (state_ == RUNNING && timer_.IsRunning()));
90
91 if (timer_.IsRunning())
92 timer_.Stop();
93 PlatformEventObserver<ListenerType>::Stop();
94 state_ = STOPPED;
95 }
96
97 protected:
98 explicit DeviceSensorEventPump(RenderThread* thread)
99 : PlatformEventObserver<ListenerType>(thread),
100 pump_delay_microseconds_(kDefaultPumpDelayMicroseconds),
101 state_(STOPPED) {}
102 92
103 ~DeviceSensorEventPump() override { 93 ~DeviceSensorEventPump() override {
104 PlatformEventObserver<ListenerType>::StopIfObserving(); 94 PlatformEventObserver<ListenerType>::StopIfObserving();
105 } 95 }
106 96
97 // Default rate for firing events.
98 static constexpr int kDefaultPumpFrequencyHz = 60;
99 static constexpr int kDefaultPumpDelayMicroseconds =
100 base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz;
101
102 static constexpr int kMaxReadAttemptsCount = 10;
103
104 struct CONTENT_EXPORT SensorEntry : public device::mojom::SensorClient {
105 explicit SensorEntry(DeviceSensorEventPump* pump)
106 : event_pump(pump), active(false), client_binding(this) {}
107
108 ~SensorEntry() { client_binding.Close(); }
109
110 // device::mojom::SensorClient:
111 void RaiseError() override { HandleSensorError(); }
112
113 // device::mojom::SensorClient:
114 void SensorReadingChanged() override {
115 // Since DeviceSensorEventPump::FireEvent is called in a certain
116 // frequency, the |shared_buffer| is read frequently, so this
117 // method doesn't need to be implemented.
118 }
119
120 // Mojo callback for SensorProvider::GetSensor().
121 void OnSensorCreated(device::mojom::SensorInitParamsPtr params,
122 device::mojom::SensorClientRequest client_request) {
123 ++event_pump->num_sensors_tried_;
124
125 if (!params) {
126 HandleSensorError();
127 if (event_pump->CanStart())
128 event_pump->DidStart();
129 return;
130 }
131
132 constexpr size_t kReadBufferSize =
133 sizeof(device::SensorReadingSharedBuffer);
134
135 DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize);
136
137 mode = params->mode;
138 default_config = params->default_configuration;
139
140 DCHECK(sensor.is_bound());
141 client_binding.Bind(std::move(client_request));
142
143 shared_buffer_handle = std::move(params->memory);
144 DCHECK(!shared_buffer);
145 shared_buffer = shared_buffer_handle->MapAtOffset(kReadBufferSize,
146 params->buffer_offset);
147
148 if (!shared_buffer) {
149 HandleSensorError();
150 if (event_pump->CanStart())
151 event_pump->DidStart();
152 return;
153 }
154
155 ++event_pump->num_available_sensors_;
156
157 frequency_limits.first = params->minimum_frequency;
158 frequency_limits.second = params->maximum_frequency;
159
160 DCHECK_GT(frequency_limits.first, 0.0);
161 DCHECK_GE(frequency_limits.second, frequency_limits.first);
162 constexpr double kMaxAllowedFrequency =
163 device::mojom::SensorConfiguration::kMaxAllowedFrequency;
164 DCHECK_GE(kMaxAllowedFrequency, frequency_limits.second);
165
166 sensor.set_connection_error_handler(
167 base::Bind(&SensorEntry::HandleSensorError, base::Unretained(this)));
168 sensor->AddConfiguration(
169 default_config, base::Bind(&SensorEntry::OnSensorAddConfiguration,
170 base::Unretained(this)));
171 }
172
173 // Mojo callback for Sensor::AddConfiguration().
174 void OnSensorAddConfiguration(bool success) {
175 active = success;
176 if (event_pump->CanStart())
177 event_pump->DidStart();
178 }
179
180 void HandleSensorError() {
181 sensor.reset();
182 active = false;
183 shared_buffer_handle.reset();
184 shared_buffer.reset();
185 client_binding.Close();
186 }
187
188 // Updates sensor reading from shared buffer.
189 bool UpdateSensorReading() {
190 int read_attempts = 0;
191 device::SensorReading reading_data;
192 while (!TryReadFromBuffer(&reading_data)) {
193 if (++read_attempts == kMaxReadAttemptsCount) {
194 HandleSensorError();
195 return false;
196 }
197 }
198
199 reading = reading_data;
200 return true;
201 }
202
203 bool TryReadFromBuffer(device::SensorReading* result) {
204 const device::SensorReadingSharedBuffer* buffer =
205 static_cast<const device::SensorReadingSharedBuffer*>(
206 shared_buffer.get());
207 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value();
208 auto version = seqlock.ReadBegin();
209 auto reading_data = buffer->reading;
210 if (seqlock.ReadRetry(version))
211 return false;
212 *result = reading_data;
213 return true;
214 }
215
216 bool SensorReadingUpdated() { return active && UpdateSensorReading(); }
217
218 DeviceSensorEventPump* event_pump;
219 device::mojom::SensorPtr sensor;
220 device::mojom::SensorType type;
221 bool active;
222 device::mojom::ReportingMode mode;
223 device::PlatformSensorConfiguration default_config;
224 mojo::ScopedSharedBufferHandle shared_buffer_handle;
225 mojo::ScopedSharedBufferMapping shared_buffer;
226 device::SensorReading reading;
227 std::pair<double, double> frequency_limits;
228 mojo::Binding<device::mojom::SensorClient> client_binding;
229 };
230
231 friend struct SensorEntry;
232
107 // The pump is a tri-state automaton with allowed transitions as follows: 233 // The pump is a tri-state automaton with allowed transitions as follows:
108 // STOPPED -> PENDING_START 234 // STOPPED -> PENDING_START
109 // PENDING_START -> RUNNING 235 // PENDING_START -> RUNNING
110 // PENDING_START -> STOPPED 236 // PENDING_START -> STOPPED
111 // RUNNING -> STOPPED 237 // RUNNING -> STOPPED
112 enum PumpState { 238 enum class PumpState { STOPPED, RUNNING, PENDING_START };
113 STOPPED, 239
114 RUNNING, 240 void GetSensor(device::mojom::SensorType type, SensorEntry* sensor_entry) {
115 PENDING_START 241 sensor_entry->type = type;
116 }; 242 auto request = mojo::MakeRequest(&sensor_entry->sensor);
117 243 sensor_provider_->GetSensor(type, std::move(request),
118 void DidStart(mojo::ScopedSharedBufferHandle buffer_handle) { 244 base::Bind(&SensorEntry::OnSensorCreated,
245 base::Unretained(sensor_entry)));
246 }
247
248 void DidStart() {
119 DVLOG(2) << "did start sensor event pump"; 249 DVLOG(2) << "did start sensor event pump";
120 250
121 if (state_ != PENDING_START) 251 if (state_ != PumpState::PENDING_START)
122 return; 252 return;
123 253
124 DCHECK(!timer_.IsRunning()); 254 DCHECK(!timer_.IsRunning());
125 255
126 base::SharedMemoryHandle handle; 256 timer_.Start(FROM_HERE,
127 MojoResult result = mojo::UnwrapSharedMemoryHandle( 257 base::TimeDelta::FromMicroseconds(pump_delay_microseconds_),
128 std::move(buffer_handle), &handle, nullptr, nullptr); 258 this, &DeviceSensorEventPump::FireEvent);
129 DCHECK_EQ(MOJO_RESULT_OK, result); 259 state_ = PumpState::RUNNING;
130 260 }
131 if (InitializeReader(handle)) { 261
132 timer_.Start(FROM_HERE, 262 void HandleSensorProviderError() {
133 base::TimeDelta::FromMicroseconds(pump_delay_microseconds_), 263 sensor_provider_.reset();
134 this, 264 for (auto& sensor : sensors_)
135 &DeviceSensorEventPump::FireEvent); 265 sensor->HandleSensorError();
136 state_ = RUNNING; 266 }
137 } 267
138 } 268 // Notify the renderer of a certain device event.
139
140 virtual void FireEvent() = 0; 269 virtual void FireEvent() = 0;
141 virtual bool InitializeReader(base::SharedMemoryHandle handle) = 0; 270
142 271 mojo::InterfacePtr<device::mojom::SensorProvider> sensor_provider_;
272 std::vector<std::unique_ptr<SensorEntry>> sensors_;
143 int pump_delay_microseconds_; 273 int pump_delay_microseconds_;
274 // The number of sensors that are tried obtaining by calling
275 // SensorProvider::GetSensor().
276 int num_sensors_tried_;
277 // The number of sensors that are available from a successful
278 // SensorProvider::GetSensor() call.
279 int num_available_sensors_;
280
281 private:
282 // Returns if the |sensors_| are ready to start a certain device event.
283 virtual bool CanStart() const = 0;
284
144 PumpState state_; 285 PumpState state_;
145 base::RepeatingTimer timer_; 286 base::RepeatingTimer timer_;
146 287
147 DISALLOW_COPY_AND_ASSIGN(DeviceSensorEventPump); 288 DISALLOW_COPY_AND_ASSIGN(DeviceSensorEventPump);
148 }; 289 };
149 290
150 } // namespace content 291 } // namespace content
151 292
152 #endif // CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_ 293 #endif // CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698