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

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

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

Powered by Google App Engine
This is Rietveld 408576698