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

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

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

Powered by Google App Engine
This is Rietveld 408576698