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

Side by Side Diff: device/sensors/data_fetcher_shared_memory_win.cc

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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "device/sensors/data_fetcher_shared_memory.h"
6
7 #include <GuidDef.h>
8 #include <InitGuid.h>
9 #include <PortableDeviceTypes.h>
10 #include <Sensors.h>
11 #include <objbase.h>
12
13 #include "base/logging.h"
14 #include "base/macros.h"
15 #include "base/metrics/histogram_macros.h"
16 #include "base/win/iunknown_impl.h"
17 #include "base/win/windows_version.h"
18
19 namespace {
20
21 const double kMeanGravity = 9.80665;
22
23 } // namespace
24
25 namespace device {
26
27 class DataFetcherSharedMemory::SensorEventSink
28 : public ISensorEvents,
29 public base::win::IUnknownImpl {
30 public:
31 SensorEventSink() {}
32 ~SensorEventSink() override {}
33
34 // IUnknown interface
35 ULONG STDMETHODCALLTYPE AddRef() override { return IUnknownImpl::AddRef(); }
36
37 ULONG STDMETHODCALLTYPE Release() override { return IUnknownImpl::Release(); }
38
39 STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override {
40 if (riid == __uuidof(ISensorEvents)) {
41 *ppv = static_cast<ISensorEvents*>(this);
42 AddRef();
43 return S_OK;
44 }
45 return IUnknownImpl::QueryInterface(riid, ppv);
46 }
47
48 // ISensorEvents interface
49 STDMETHODIMP OnEvent(ISensor* sensor,
50 REFGUID event_id,
51 IPortableDeviceValues* event_data) override {
52 return S_OK;
53 }
54
55 STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) override { return S_OK; }
56
57 STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) override {
58 return S_OK;
59 }
60
61 STDMETHODIMP OnDataUpdated(ISensor* sensor,
62 ISensorDataReport* new_data) override {
63 if (nullptr == new_data || nullptr == sensor)
64 return E_INVALIDARG;
65 return UpdateSharedMemoryBuffer(sensor, new_data) ? S_OK : E_FAIL;
66 }
67
68 protected:
69 virtual bool UpdateSharedMemoryBuffer(ISensor* sensor,
70 ISensorDataReport* new_data) = 0;
71
72 void GetSensorValue(REFPROPERTYKEY property,
73 ISensorDataReport* new_data,
74 double* value,
75 bool* has_value) {
76 PROPVARIANT variant_value = {};
77 if (SUCCEEDED(new_data->GetSensorValue(property, &variant_value))) {
78 if (variant_value.vt == VT_R8)
79 *value = variant_value.dblVal;
80 else if (variant_value.vt == VT_R4)
81 *value = variant_value.fltVal;
82 *has_value = true;
83 } else {
84 *value = 0;
85 *has_value = false;
86 }
87 }
88
89 private:
90 DISALLOW_COPY_AND_ASSIGN(SensorEventSink);
91 };
92
93 class DataFetcherSharedMemory::SensorEventSinkOrientation
94 : public DataFetcherSharedMemory::SensorEventSink {
95 public:
96 explicit SensorEventSinkOrientation(
97 DeviceOrientationHardwareBuffer* const buffer)
98 : buffer_(buffer) {}
99 ~SensorEventSinkOrientation() override {}
100
101 protected:
102 bool UpdateSharedMemoryBuffer(ISensor* sensor,
103 ISensorDataReport* new_data) override {
104 double alpha, beta, gamma;
105 bool has_alpha, has_beta, has_gamma;
106
107 GetSensorValue(SENSOR_DATA_TYPE_TILT_X_DEGREES, new_data, &beta, &has_beta);
108 GetSensorValue(SENSOR_DATA_TYPE_TILT_Y_DEGREES, new_data, &gamma,
109 &has_gamma);
110 GetSensorValue(SENSOR_DATA_TYPE_TILT_Z_DEGREES, new_data, &alpha,
111 &has_alpha);
112
113 if (buffer_) {
114 buffer_->seqlock.WriteBegin();
115 buffer_->data.alpha = alpha;
116 buffer_->data.has_alpha = has_alpha;
117 buffer_->data.beta = beta;
118 buffer_->data.has_beta = has_beta;
119 buffer_->data.gamma = gamma;
120 buffer_->data.has_gamma = has_gamma;
121 buffer_->data.absolute = has_alpha || has_beta || has_gamma;
122 buffer_->data.all_available_sensors_are_active = true;
123 buffer_->seqlock.WriteEnd();
124 }
125
126 return true;
127 }
128
129 private:
130 DeviceOrientationHardwareBuffer* const buffer_;
131
132 DISALLOW_COPY_AND_ASSIGN(SensorEventSinkOrientation);
133 };
134
135 class DataFetcherSharedMemory::SensorEventSinkMotion
136 : public DataFetcherSharedMemory::SensorEventSink {
137 public:
138 explicit SensorEventSinkMotion(DeviceMotionHardwareBuffer* const buffer)
139 : buffer_(buffer) {}
140 ~SensorEventSinkMotion() override {}
141
142 protected:
143 bool UpdateSharedMemoryBuffer(ISensor* sensor,
144 ISensorDataReport* new_data) override {
145 SENSOR_TYPE_ID sensor_type = GUID_NULL;
146 if (!SUCCEEDED(sensor->GetType(&sensor_type)))
147 return false;
148
149 if (IsEqualIID(sensor_type, SENSOR_TYPE_ACCELEROMETER_3D)) {
150 double acceleration_including_gravity_x;
151 double acceleration_including_gravity_y;
152 double acceleration_including_gravity_z;
153 bool has_acceleration_including_gravity_x;
154 bool has_acceleration_including_gravity_y;
155 bool has_acceleration_including_gravity_z;
156
157 GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, new_data,
158 &acceleration_including_gravity_x,
159 &has_acceleration_including_gravity_x);
160 GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, new_data,
161 &acceleration_including_gravity_y,
162 &has_acceleration_including_gravity_y);
163 GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, new_data,
164 &acceleration_including_gravity_z,
165 &has_acceleration_including_gravity_z);
166
167 if (buffer_) {
168 buffer_->seqlock.WriteBegin();
169 buffer_->data.acceleration_including_gravity_x =
170 -acceleration_including_gravity_x * kMeanGravity;
171 buffer_->data.has_acceleration_including_gravity_x =
172 has_acceleration_including_gravity_x;
173 buffer_->data.acceleration_including_gravity_y =
174 -acceleration_including_gravity_y * kMeanGravity;
175 buffer_->data.has_acceleration_including_gravity_y =
176 has_acceleration_including_gravity_y;
177 buffer_->data.acceleration_including_gravity_z =
178 -acceleration_including_gravity_z * kMeanGravity;
179 buffer_->data.has_acceleration_including_gravity_z =
180 has_acceleration_including_gravity_z;
181 // TODO(timvolodine): consider setting this after all
182 // sensors have fired.
183 buffer_->data.all_available_sensors_are_active = true;
184 buffer_->seqlock.WriteEnd();
185 }
186
187 } else if (IsEqualIID(sensor_type, SENSOR_TYPE_GYROMETER_3D)) {
188 double alpha, beta, gamma;
189 bool has_alpha, has_beta, has_gamma;
190
191 GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND,
192 new_data, &alpha, &has_alpha);
193 GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND,
194 new_data, &beta, &has_beta);
195 GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND,
196 new_data, &gamma, &has_gamma);
197
198 if (buffer_) {
199 buffer_->seqlock.WriteBegin();
200 buffer_->data.rotation_rate_alpha = alpha;
201 buffer_->data.has_rotation_rate_alpha = has_alpha;
202 buffer_->data.rotation_rate_beta = beta;
203 buffer_->data.has_rotation_rate_beta = has_beta;
204 buffer_->data.rotation_rate_gamma = gamma;
205 buffer_->data.has_rotation_rate_gamma = has_gamma;
206 buffer_->data.all_available_sensors_are_active = true;
207 buffer_->seqlock.WriteEnd();
208 }
209 }
210
211 return true;
212 }
213
214 private:
215 DeviceMotionHardwareBuffer* const buffer_;
216
217 DISALLOW_COPY_AND_ASSIGN(SensorEventSinkMotion);
218 };
219
220 DataFetcherSharedMemory::DataFetcherSharedMemory() {}
221
222 DataFetcherSharedMemory::~DataFetcherSharedMemory() {}
223
224 DataFetcherSharedMemory::FetcherType DataFetcherSharedMemory::GetType() const {
225 return FETCHER_TYPE_SEPARATE_THREAD;
226 }
227
228 bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
229 DCHECK(buffer);
230
231 switch (consumer_type) {
232 case CONSUMER_TYPE_ORIENTATION: {
233 orientation_buffer_ =
234 static_cast<DeviceOrientationHardwareBuffer*>(buffer);
235 scoped_refptr<SensorEventSink> sink(
236 new SensorEventSinkOrientation(orientation_buffer_));
237 bool inclinometer_available =
238 RegisterForSensor(SENSOR_TYPE_INCLINOMETER_3D,
239 sensor_inclinometer_.GetAddressOf(), sink);
240 UMA_HISTOGRAM_BOOLEAN("InertialSensor.InclinometerWindowsAvailable",
241 inclinometer_available);
242 if (inclinometer_available)
243 return true;
244 // if no sensors are available set buffer to ready, to fire null-events.
245 SetBufferAvailableState(consumer_type, true);
246 } break;
247 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE: {
248 orientation_absolute_buffer_ =
249 static_cast<DeviceOrientationHardwareBuffer*>(buffer);
250 scoped_refptr<SensorEventSink> sink(
251 new SensorEventSinkOrientation(orientation_absolute_buffer_));
252 // Currently we use the same sensor as for orientation which provides
253 // absolute angles.
254 bool inclinometer_available =
255 RegisterForSensor(SENSOR_TYPE_INCLINOMETER_3D,
256 sensor_inclinometer_absolute_.GetAddressOf(), sink);
257 // TODO(timvolodine): consider adding UMA.
258 if (inclinometer_available)
259 return true;
260 // if no sensors are available set buffer to ready, to fire null-events.
261 SetBufferAvailableState(consumer_type, true);
262 } break;
263 case CONSUMER_TYPE_MOTION: {
264 motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer);
265 scoped_refptr<SensorEventSink> sink(
266 new SensorEventSinkMotion(motion_buffer_));
267 bool accelerometer_available =
268 RegisterForSensor(SENSOR_TYPE_ACCELEROMETER_3D,
269 sensor_accelerometer_.GetAddressOf(), sink);
270 bool gyrometer_available = RegisterForSensor(
271 SENSOR_TYPE_GYROMETER_3D, sensor_gyrometer_.GetAddressOf(), sink);
272 UMA_HISTOGRAM_BOOLEAN("InertialSensor.AccelerometerWindowsAvailable",
273 accelerometer_available);
274 UMA_HISTOGRAM_BOOLEAN("InertialSensor.GyrometerWindowsAvailable",
275 gyrometer_available);
276 if (accelerometer_available || gyrometer_available) {
277 motion_buffer_->seqlock.WriteBegin();
278 motion_buffer_->data.interval = GetInterval().InMilliseconds();
279 motion_buffer_->seqlock.WriteEnd();
280 return true;
281 }
282 // if no sensors are available set buffer to ready, to fire null-events.
283 SetBufferAvailableState(consumer_type, true);
284 } break;
285 default:
286 NOTREACHED();
287 }
288 return false;
289 }
290
291 bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
292 DisableSensors(consumer_type);
293 switch (consumer_type) {
294 case CONSUMER_TYPE_ORIENTATION:
295 SetBufferAvailableState(consumer_type, false);
296 orientation_buffer_ = nullptr;
297 return true;
298 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
299 SetBufferAvailableState(consumer_type, false);
300 orientation_absolute_buffer_ = nullptr;
301 return true;
302 case CONSUMER_TYPE_MOTION:
303 SetBufferAvailableState(consumer_type, false);
304 motion_buffer_ = nullptr;
305 return true;
306 default:
307 NOTREACHED();
308 }
309 return false;
310 }
311
312 bool DataFetcherSharedMemory::RegisterForSensor(
313 REFSENSOR_TYPE_ID sensor_type,
314 ISensor** sensor,
315 scoped_refptr<SensorEventSink> event_sink) {
316 if (base::win::GetVersion() < base::win::VERSION_WIN7)
317 return false;
318
319 base::win::ScopedComPtr<ISensorManager> sensor_manager;
320 HRESULT hr = sensor_manager.CreateInstance(CLSID_SensorManager);
321 if (FAILED(hr) || !sensor_manager.Get())
322 return false;
323
324 base::win::ScopedComPtr<ISensorCollection> sensor_collection;
325 hr = sensor_manager->GetSensorsByType(sensor_type,
326 sensor_collection.GetAddressOf());
327
328 if (FAILED(hr) || !sensor_collection.Get())
329 return false;
330
331 ULONG count = 0;
332 hr = sensor_collection->GetCount(&count);
333 if (FAILED(hr) || !count)
334 return false;
335
336 hr = sensor_collection->GetAt(0, sensor);
337 if (FAILED(hr) || !(*sensor))
338 return false;
339
340 base::win::ScopedComPtr<IPortableDeviceValues> device_values;
341 if (SUCCEEDED(device_values.CreateInstance(CLSID_PortableDeviceValues))) {
342 if (SUCCEEDED(device_values->SetUnsignedIntegerValue(
343 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
344 GetInterval().InMilliseconds()))) {
345 base::win::ScopedComPtr<IPortableDeviceValues> return_values;
346 (*sensor)->SetProperties(device_values.Get(),
347 return_values.GetAddressOf());
348 }
349 }
350
351 base::win::ScopedComPtr<ISensorEvents> sensor_events;
352 hr = event_sink->QueryInterface(IID_PPV_ARGS(&sensor_events));
353 if (FAILED(hr) || !sensor_events.Get())
354 return false;
355
356 hr = (*sensor)->SetEventSink(sensor_events.Get());
357 if (FAILED(hr))
358 return false;
359
360 return true;
361 }
362
363 void DataFetcherSharedMemory::DisableSensors(ConsumerType consumer_type) {
364 switch (consumer_type) {
365 case CONSUMER_TYPE_ORIENTATION:
366 if (sensor_inclinometer_.Get()) {
367 sensor_inclinometer_->SetEventSink(nullptr);
368 sensor_inclinometer_.Reset();
369 }
370 break;
371 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
372 if (sensor_inclinometer_absolute_.Get()) {
373 sensor_inclinometer_absolute_->SetEventSink(nullptr);
374 sensor_inclinometer_absolute_.Reset();
375 }
376 break;
377 case CONSUMER_TYPE_MOTION:
378 if (sensor_accelerometer_.Get()) {
379 sensor_accelerometer_->SetEventSink(nullptr);
380 sensor_accelerometer_.Reset();
381 }
382 if (sensor_gyrometer_.Get()) {
383 sensor_gyrometer_->SetEventSink(nullptr);
384 sensor_gyrometer_.Reset();
385 }
386 break;
387 default:
388 NOTREACHED();
389 }
390 }
391
392 void DataFetcherSharedMemory::SetBufferAvailableState(
393 ConsumerType consumer_type,
394 bool enabled) {
395 switch (consumer_type) {
396 case CONSUMER_TYPE_ORIENTATION:
397 if (orientation_buffer_) {
398 orientation_buffer_->seqlock.WriteBegin();
399 orientation_buffer_->data.all_available_sensors_are_active = enabled;
400 orientation_buffer_->seqlock.WriteEnd();
401 }
402 break;
403 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
404 if (orientation_absolute_buffer_) {
405 orientation_absolute_buffer_->seqlock.WriteBegin();
406 orientation_absolute_buffer_->data.all_available_sensors_are_active =
407 enabled;
408 orientation_absolute_buffer_->seqlock.WriteEnd();
409 }
410 break;
411 case CONSUMER_TYPE_MOTION:
412 if (motion_buffer_) {
413 motion_buffer_->seqlock.WriteBegin();
414 motion_buffer_->data.all_available_sensors_are_active = enabled;
415 motion_buffer_->seqlock.WriteEnd();
416 }
417 break;
418 default:
419 NOTREACHED();
420 }
421 }
422
423 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698