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

Side by Side Diff: content/renderer/device_sensors/device_motion_event_pump.cc

Issue 2953263002: Revert of Reland: Refactor DeviceMotionEventPump to use //device/generic_sensor instead of //device/sensors (Closed)
Patch Set: Created 3 years, 6 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 #include "content/renderer/device_sensors/device_motion_event_pump.h" 5 #include "device_motion_event_pump.h"
6 6
7 #include "base/memory/ptr_util.h"
8 #include "content/public/common/service_names.mojom.h"
9 #include "content/public/renderer/render_thread.h" 7 #include "content/public/renderer/render_thread.h"
10 #include "mojo/public/cpp/bindings/interface_request.h"
11 #include "services/device/public/interfaces/constants.mojom.h"
12 #include "services/service_manager/public/cpp/connector.h"
13 #include "third_party/WebKit/public/platform/modules/device_orientation/WebDevic eMotionListener.h" 8 #include "third_party/WebKit/public/platform/modules/device_orientation/WebDevic eMotionListener.h"
14 9
15 namespace {
16
17 constexpr int kMaxReadAttemptsCount = 10;
18
19 // TODO(juncai): Extracting mojo::ScopedSharedBufferMapping reading
20 // functionality into a helper class.
21 // http://crbug.com/727788
22 bool TryReadFromBuffer(const device::SensorReadingSharedBuffer* buffer,
23 device::SensorReading* result) {
24 const device::OneWriterSeqLock& seqlock = buffer->seqlock.value();
25 auto version = seqlock.ReadBegin();
26 auto reading_data = buffer->reading;
27 if (seqlock.ReadRetry(version))
28 return false;
29 *result = reading_data;
30 return true;
31 }
32
33 // Updates sensor reading from shared buffer.
34 bool UpdateSensorReading(const device::SensorReadingSharedBuffer* buffer,
35 device::SensorReading* result) {
36 int read_attempts = 0;
37 while (!TryReadFromBuffer(buffer, result)) {
38 if (++read_attempts == kMaxReadAttemptsCount)
39 return false;
40 }
41
42 return true;
43 }
44
45 } // namespace
46
47 namespace content { 10 namespace content {
48 11
49 DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread) 12 DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread)
50 : PlatformEventObserver<blink::WebDeviceMotionListener>(thread), 13 : DeviceSensorMojoClientMixin<
51 accelerometer_(this, device::mojom::SensorType::ACCELEROMETER), 14 DeviceSensorEventPump<blink::WebDeviceMotionListener>,
52 linear_acceleration_sensor_( 15 device::mojom::MotionSensor>(thread) {}
53 this,
54 device::mojom::SensorType::LINEAR_ACCELERATION),
55 gyroscope_(this, device::mojom::SensorType::GYROSCOPE),
56 state_(PumpState::STOPPED) {}
57 16
58 DeviceMotionEventPump::~DeviceMotionEventPump() { 17 DeviceMotionEventPump::~DeviceMotionEventPump() {
59 PlatformEventObserver<blink::WebDeviceMotionListener>::StopIfObserving();
60 } 18 }
61 19
62 void DeviceMotionEventPump::Start(blink::WebPlatformEventListener* listener) { 20 void DeviceMotionEventPump::FireEvent() {
63 DVLOG(2) << "requested start"; 21 DCHECK(listener());
64 22 device::MotionData data;
65 if (state_ != PumpState::STOPPED) 23 if (reader_->GetLatestData(&data) && data.all_available_sensors_are_active)
66 return; 24 listener()->DidChangeDeviceMotion(data);
67
68 DCHECK(!timer_.IsRunning());
69
70 state_ = PumpState::PENDING_START;
71 PlatformEventObserver<blink::WebDeviceMotionListener>::Start(listener);
72 } 25 }
73 26
74 void DeviceMotionEventPump::Stop() { 27 bool DeviceMotionEventPump::InitializeReader(base::SharedMemoryHandle handle) {
75 DVLOG(2) << "requested stop"; 28 if (!reader_)
76 29 reader_.reset(new DeviceMotionSharedMemoryReader());
77 if (state_ == PumpState::STOPPED) 30 return reader_->Initialize(handle);
78 return;
79
80 DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) ||
81 (state_ == PumpState::RUNNING && timer_.IsRunning()));
82
83 if (timer_.IsRunning())
84 timer_.Stop();
85
86 PlatformEventObserver<blink::WebDeviceMotionListener>::Stop();
87 state_ = PumpState::STOPPED;
88 }
89
90 void DeviceMotionEventPump::SendStartMessage() {
91 auto request = mojo::MakeRequest(&sensor_provider_);
92
93 // When running layout tests, those observers should not listen to the
94 // actual hardware changes. In order to make that happen, don't connect
95 // the other end of the mojo pipe to anything.
96 if (!RenderThreadImpl::current() ||
97 RenderThreadImpl::current()->layout_test_mode()) {
98 return;
99 }
100
101 if (!accelerometer_.sensor && !linear_acceleration_sensor_.sensor &&
102 !gyroscope_.sensor) {
103 RenderThread::Get()->GetConnector()->BindInterface(
104 device::mojom::kServiceName, std::move(request));
105 sensor_provider_.set_connection_error_handler(
106 base::Bind(&DeviceMotionEventPump::HandleSensorProviderError,
107 base::Unretained(this)));
108 GetSensor(&accelerometer_);
109 GetSensor(&linear_acceleration_sensor_);
110 GetSensor(&gyroscope_);
111 } else {
112 if (accelerometer_.sensor)
113 accelerometer_.sensor->Resume();
114
115 if (linear_acceleration_sensor_.sensor)
116 linear_acceleration_sensor_.sensor->Resume();
117
118 if (gyroscope_.sensor)
119 gyroscope_.sensor->Resume();
120
121 if (CanStart())
122 DidStart();
123 }
124 }
125
126 void DeviceMotionEventPump::SendStopMessage() {
127 // SendStopMessage() gets called both when the page visibility changes and if
128 // all device motion event listeners are unregistered. Since removing the
129 // event listener is more rare than the page visibility changing,
130 // Sensor::Suspend() is used to optimize this case for not doing extra work.
131 if (accelerometer_.sensor)
132 accelerometer_.sensor->Suspend();
133
134 if (linear_acceleration_sensor_.sensor)
135 linear_acceleration_sensor_.sensor->Suspend();
136
137 if (gyroscope_.sensor)
138 gyroscope_.sensor->Suspend();
139 } 31 }
140 32
141 void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) { 33 void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) {
142 device::MotionData data = *static_cast<device::MotionData*>(fake_data); 34 device::MotionData data = *static_cast<device::MotionData*>(fake_data);
35
143 listener()->DidChangeDeviceMotion(data); 36 listener()->DidChangeDeviceMotion(data);
144 } 37 }
145 38
146 DeviceMotionEventPump::SensorEntry::SensorEntry(
147 DeviceMotionEventPump* pump,
148 device::mojom::SensorType sensor_type)
149 : event_pump(pump), type(sensor_type), client_binding(this) {}
150
151 DeviceMotionEventPump::SensorEntry::~SensorEntry() {}
152
153 void DeviceMotionEventPump::SensorEntry::RaiseError() {
154 HandleSensorError();
155 }
156
157 void DeviceMotionEventPump::SensorEntry::SensorReadingChanged() {
158 // Since DeviceMotionEventPump::FireEvent is called in a certain
159 // frequency, the |shared_buffer| is read frequently, and
160 // PlatformSensorConfiguration::set_suppress_on_change_events()
161 // is set to true, so this method is not called and doesn't need
162 // to be implemented.
163 NOTREACHED();
164 }
165
166 void DeviceMotionEventPump::SensorEntry::OnSensorCreated(
167 device::mojom::SensorInitParamsPtr params,
168 device::mojom::SensorClientRequest client_request) {
169 if (!params) {
170 HandleSensorError();
171 if (event_pump->CanStart())
172 event_pump->DidStart();
173 return;
174 }
175
176 constexpr size_t kReadBufferSize = sizeof(device::SensorReadingSharedBuffer);
177
178 DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize);
179
180 mode = params->mode;
181 default_config = params->default_configuration;
182
183 DCHECK(sensor.is_bound());
184 client_binding.Bind(std::move(client_request));
185
186 shared_buffer_handle = std::move(params->memory);
187 DCHECK(!shared_buffer);
188 shared_buffer =
189 shared_buffer_handle->MapAtOffset(kReadBufferSize, params->buffer_offset);
190
191 if (!shared_buffer) {
192 HandleSensorError();
193 if (event_pump->CanStart())
194 event_pump->DidStart();
195 return;
196 }
197
198 DCHECK_GT(params->minimum_frequency, 0.0);
199 DCHECK_GE(params->maximum_frequency, params->minimum_frequency);
200 DCHECK_GE(device::mojom::SensorConfiguration::kMaxAllowedFrequency,
201 params->maximum_frequency);
202
203 default_config.set_frequency(kDefaultPumpFrequencyHz);
204 default_config.set_suppress_on_change_events(true);
205
206 sensor->AddConfiguration(default_config,
207 base::Bind(&SensorEntry::OnSensorAddConfiguration,
208 base::Unretained(this)));
209 }
210
211 void DeviceMotionEventPump::SensorEntry::OnSensorAddConfiguration(
212 bool success) {
213 if (!success)
214 HandleSensorError();
215 if (event_pump->CanStart())
216 event_pump->DidStart();
217 }
218
219 void DeviceMotionEventPump::SensorEntry::HandleSensorError() {
220 sensor.reset();
221 shared_buffer_handle.reset();
222 shared_buffer.reset();
223 client_binding.Close();
224 }
225
226 bool DeviceMotionEventPump::SensorEntry::SensorReadingCouldBeRead() {
227 if (!sensor || !shared_buffer)
228 return false;
229
230 const device::SensorReadingSharedBuffer* buffer =
231 static_cast<const device::SensorReadingSharedBuffer*>(
232 shared_buffer.get());
233 if (!UpdateSensorReading(buffer, &reading)) {
234 HandleSensorError();
235 return false;
236 }
237
238 return true;
239 }
240
241 void DeviceMotionEventPump::FireEvent() {
242 device::MotionData data;
243 // The device orientation spec states that interval should be in milliseconds.
244 // https://w3c.github.io/deviceorientation/spec-source-orientation.html#device motion
245 data.interval = kDefaultPumpDelayMicroseconds / 1000;
246
247 DCHECK(listener());
248
249 GetDataFromSharedMemory(&data);
250 listener()->DidChangeDeviceMotion(data);
251 }
252
253 void DeviceMotionEventPump::DidStart() {
254 DVLOG(2) << "did start sensor event pump";
255
256 if (state_ != PumpState::PENDING_START)
257 return;
258
259 DCHECK(!timer_.IsRunning());
260
261 timer_.Start(FROM_HERE,
262 base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds),
263 this, &DeviceMotionEventPump::FireEvent);
264 state_ = PumpState::RUNNING;
265 }
266
267 bool DeviceMotionEventPump::CanStart() const {
268 if (accelerometer_.sensor && !accelerometer_.shared_buffer)
269 return false;
270
271 if (linear_acceleration_sensor_.sensor &&
272 !linear_acceleration_sensor_.shared_buffer) {
273 return false;
274 }
275
276 if (gyroscope_.sensor && !gyroscope_.shared_buffer)
277 return false;
278
279 return true;
280 }
281
282 void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) {
283 if (accelerometer_.SensorReadingCouldBeRead()) {
284 data->acceleration_including_gravity_x =
285 accelerometer_.reading.values[0].value();
286 data->acceleration_including_gravity_y =
287 accelerometer_.reading.values[1].value();
288 data->acceleration_including_gravity_z =
289 accelerometer_.reading.values[2].value();
290 data->has_acceleration_including_gravity_x = true;
291 data->has_acceleration_including_gravity_y = true;
292 data->has_acceleration_including_gravity_z = true;
293 }
294
295 if (linear_acceleration_sensor_.SensorReadingCouldBeRead()) {
296 data->acceleration_x =
297 linear_acceleration_sensor_.reading.values[0].value();
298 data->acceleration_y =
299 linear_acceleration_sensor_.reading.values[1].value();
300 data->acceleration_z =
301 linear_acceleration_sensor_.reading.values[2].value();
302 data->has_acceleration_x = true;
303 data->has_acceleration_y = true;
304 data->has_acceleration_z = true;
305 }
306
307 if (gyroscope_.SensorReadingCouldBeRead()) {
308 data->rotation_rate_alpha = gyroscope_.reading.values[0].value();
309 data->rotation_rate_beta = gyroscope_.reading.values[1].value();
310 data->rotation_rate_gamma = gyroscope_.reading.values[2].value();
311 data->has_rotation_rate_alpha = true;
312 data->has_rotation_rate_beta = true;
313 data->has_rotation_rate_gamma = true;
314 }
315 }
316
317 void DeviceMotionEventPump::GetSensor(SensorEntry* sensor_entry) {
318 auto request = mojo::MakeRequest(&sensor_entry->sensor);
319 sensor_provider_->GetSensor(sensor_entry->type, std::move(request),
320 base::Bind(&SensorEntry::OnSensorCreated,
321 base::Unretained(sensor_entry)));
322 sensor_entry->sensor.set_connection_error_handler(base::Bind(
323 &SensorEntry::HandleSensorError, base::Unretained(sensor_entry)));
324 }
325
326 void DeviceMotionEventPump::HandleSensorProviderError() {
327 sensor_provider_.reset();
328 }
329
330 } // namespace content 39 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698