| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/generic_sensor/platform_sensor_reader_win.h" | 5 #include "device/generic_sensor/platform_sensor_reader_win.h" |
| 6 | 6 |
| 7 #include <Sensors.h> | 7 #include <Sensors.h> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "base/win/iunknown_impl.h" | 13 #include "base/win/iunknown_impl.h" |
| 14 #include "base/win/scoped_propvariant.h" |
| 14 #include "device/generic_sensor/generic_sensor_consts.h" | 15 #include "device/generic_sensor/generic_sensor_consts.h" |
| 15 #include "device/generic_sensor/public/cpp/platform_sensor_configuration.h" | 16 #include "device/generic_sensor/public/cpp/platform_sensor_configuration.h" |
| 16 #include "device/generic_sensor/public/cpp/sensor_reading.h" | 17 #include "device/generic_sensor/public/cpp/sensor_reading.h" |
| 17 | 18 |
| 18 namespace device { | 19 namespace device { |
| 19 | 20 |
| 20 // Init params for the PlatformSensorReaderWin. | 21 // Init params for the PlatformSensorReaderWin. |
| 21 struct ReaderInitParams { | 22 struct ReaderInitParams { |
| 22 // ISensorDataReport::GetSensorValue is not const, therefore, report | 23 // ISensorDataReport::GetSensorValue is not const, therefore, report |
| 23 // cannot be passed as const ref. | 24 // cannot be passed as const ref. |
| 24 // ISensorDataReport& report - report that contains new sensor data. | 25 // ISensorDataReport& report - report that contains new sensor data. |
| 25 // SensorReading& reading - out parameter that must be populated. | 26 // SensorReading& reading - out parameter that must be populated. |
| 26 // Returns HRESULT - S_OK on success, otherwise error code. | 27 // Returns HRESULT - S_OK on success, otherwise error code. |
| 27 using ReaderFunctor = base::Callback<HRESULT(ISensorDataReport& report, | 28 using ReaderFunctor = base::Callback<HRESULT(ISensorDataReport& report, |
| 28 SensorReading& reading)>; | 29 SensorReading& reading)>; |
| 29 SENSOR_TYPE_ID sensor_type_id; | 30 SENSOR_TYPE_ID sensor_type_id; |
| 30 ReaderFunctor reader_func; | 31 ReaderFunctor reader_func; |
| 31 unsigned long min_reporting_interval_ms = 0; | 32 unsigned long min_reporting_interval_ms = 0; |
| 32 }; | 33 }; |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 // Gets value from the report for provided key. | 37 // Gets value from the report for provided key. |
| 37 bool GetReadingValueForProperty(REFPROPERTYKEY key, | 38 bool GetReadingValueForProperty(REFPROPERTYKEY key, |
| 38 ISensorDataReport& report, | 39 ISensorDataReport& report, |
| 39 double* value) { | 40 double* value) { |
| 40 DCHECK(value); | 41 DCHECK(value); |
| 41 PROPVARIANT variant_value = {}; | 42 base::win::ScopedPropVariant variant_value; |
| 42 if (SUCCEEDED(report.GetSensorValue(key, &variant_value))) { | 43 if (SUCCEEDED(report.GetSensorValue(key, variant_value.Receive()))) { |
| 43 if (variant_value.vt == VT_R8) | 44 if (variant_value.get().vt == VT_R8) |
| 44 *value = variant_value.dblVal; | 45 *value = variant_value.get().dblVal; |
| 45 else if (variant_value.vt == VT_R4) | 46 else if (variant_value.get().vt == VT_R4) |
| 46 *value = variant_value.fltVal; | 47 *value = variant_value.get().fltVal; |
| 47 else | 48 else |
| 48 return false; | 49 return false; |
| 49 return true; | 50 return true; |
| 50 } | 51 } |
| 51 | 52 |
| 52 *value = 0; | 53 *value = 0; |
| 53 return false; | 54 return false; |
| 54 } | 55 } |
| 55 | 56 |
| 56 // Ambient light sensor reader initialization parameters. | 57 // Ambient light sensor reader initialization parameters. |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 // sign for each axis. Values are converted from Milligaus to | 158 // sign for each axis. Values are converted from Milligaus to |
| 158 // Microtesla. | 159 // Microtesla. |
| 159 reading.values[0] = -x * kMicroteslaInMilligauss; | 160 reading.values[0] = -x * kMicroteslaInMilligauss; |
| 160 reading.values[1] = -y * kMicroteslaInMilligauss; | 161 reading.values[1] = -y * kMicroteslaInMilligauss; |
| 161 reading.values[2] = -z * kMicroteslaInMilligauss; | 162 reading.values[2] = -z * kMicroteslaInMilligauss; |
| 162 return S_OK; | 163 return S_OK; |
| 163 }); | 164 }); |
| 164 return params; | 165 return params; |
| 165 } | 166 } |
| 166 | 167 |
| 168 // AbsoluteOrientation sensor reader initialization parameters. |
| 169 std::unique_ptr<ReaderInitParams> CreateAbsoluteOrientationReaderInitParams() { |
| 170 auto params = base::MakeUnique<ReaderInitParams>(); |
| 171 params->sensor_type_id = SENSOR_TYPE_AGGREGATED_DEVICE_ORIENTATION; |
| 172 params->reader_func = |
| 173 base::Bind([](ISensorDataReport& report, SensorReading& reading) { |
| 174 base::win::ScopedPropVariant quat_variant; |
| 175 HRESULT hr = report.GetSensorValue(SENSOR_DATA_TYPE_QUATERNION, |
| 176 quat_variant.Receive()); |
| 177 if (FAILED(hr) || quat_variant.get().vt != (VT_VECTOR | VT_UI1) || |
| 178 quat_variant.get().caub.cElems < 16) { |
| 179 return E_FAIL; |
| 180 } |
| 181 |
| 182 float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems); |
| 183 |
| 184 // Windows uses coordinate system where Z axis points down from device |
| 185 // screen, therefore, using right hand notation, we have to reverse |
| 186 // sign for each quaternion component. |
| 187 reading.values[0] = -quat[0]; // x*sin(Theta/2) |
| 188 reading.values[1] = -quat[1]; // y*sin(Theta/2) |
| 189 reading.values[2] = -quat[2]; // z*sin(Theta/2) |
| 190 reading.values[3] = quat[3]; // cos(Theta/2) |
| 191 return S_OK; |
| 192 }); |
| 193 return params; |
| 194 } |
| 195 |
| 167 // Creates ReaderInitParams params structure. To implement support for new | 196 // Creates ReaderInitParams params structure. To implement support for new |
| 168 // sensor types, new switch case should be added and appropriate fields must | 197 // sensor types, new switch case should be added and appropriate fields must |
| 169 // be set: | 198 // be set: |
| 170 // sensor_type_id - GUID of the sensor supported by Windows. | 199 // sensor_type_id - GUID of the sensor supported by Windows. |
| 171 // reader_func - Functor that is responsible to populate SensorReading from | 200 // reader_func - Functor that is responsible to populate SensorReading from |
| 172 // ISensorDataReport data. | 201 // ISensorDataReport data. |
| 173 std::unique_ptr<ReaderInitParams> CreateReaderInitParamsForSensor( | 202 std::unique_ptr<ReaderInitParams> CreateReaderInitParamsForSensor( |
| 174 mojom::SensorType type) { | 203 mojom::SensorType type) { |
| 175 switch (type) { | 204 switch (type) { |
| 176 case mojom::SensorType::AMBIENT_LIGHT: | 205 case mojom::SensorType::AMBIENT_LIGHT: |
| 177 return CreateAmbientLightReaderInitParams(); | 206 return CreateAmbientLightReaderInitParams(); |
| 178 case mojom::SensorType::ACCELEROMETER: | 207 case mojom::SensorType::ACCELEROMETER: |
| 179 return CreateAccelerometerReaderInitParams(); | 208 return CreateAccelerometerReaderInitParams(); |
| 180 case mojom::SensorType::GYROSCOPE: | 209 case mojom::SensorType::GYROSCOPE: |
| 181 return CreateGyroscopeReaderInitParams(); | 210 return CreateGyroscopeReaderInitParams(); |
| 182 case mojom::SensorType::MAGNETOMETER: | 211 case mojom::SensorType::MAGNETOMETER: |
| 183 return CreateMagnetometerReaderInitParams(); | 212 return CreateMagnetometerReaderInitParams(); |
| 213 case mojom::SensorType::ABSOLUTE_ORIENTATION: |
| 214 return CreateAbsoluteOrientationReaderInitParams(); |
| 184 default: | 215 default: |
| 185 NOTIMPLEMENTED(); | 216 NOTIMPLEMENTED(); |
| 186 return nullptr; | 217 return nullptr; |
| 187 } | 218 } |
| 188 } | 219 } |
| 189 | 220 |
| 190 } // namespace | 221 } // namespace |
| 191 | 222 |
| 192 // Class that implements ISensorEvents and IUnknown interfaces and used | 223 // Class that implements ISensorEvents and IUnknown interfaces and used |
| 193 // by ISensor interface to dispatch state and data change events. | 224 // by ISensor interface to dispatch state and data change events. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 DCHECK(sensor_manager); | 329 DCHECK(sensor_manager); |
| 299 | 330 |
| 300 auto params = CreateReaderInitParamsForSensor(type); | 331 auto params = CreateReaderInitParamsForSensor(type); |
| 301 if (!params) | 332 if (!params) |
| 302 return nullptr; | 333 return nullptr; |
| 303 | 334 |
| 304 auto sensor = GetSensorForType(params->sensor_type_id, sensor_manager); | 335 auto sensor = GetSensorForType(params->sensor_type_id, sensor_manager); |
| 305 if (!sensor) | 336 if (!sensor) |
| 306 return nullptr; | 337 return nullptr; |
| 307 | 338 |
| 308 PROPVARIANT variant = {}; | 339 base::win::ScopedPropVariant min_interval; |
| 309 HRESULT hr = | 340 HRESULT hr = sensor->GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL, |
| 310 sensor->GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL, &variant); | 341 min_interval.Receive()); |
| 311 if (SUCCEEDED(hr) && variant.vt == VT_UI4) | 342 if (SUCCEEDED(hr) && min_interval.get().vt == VT_UI4) |
| 312 params->min_reporting_interval_ms = variant.ulVal; | 343 params->min_reporting_interval_ms = min_interval.get().ulVal; |
| 313 | 344 |
| 314 GUID interests[] = {SENSOR_EVENT_STATE_CHANGED, SENSOR_EVENT_DATA_UPDATED}; | 345 GUID interests[] = {SENSOR_EVENT_STATE_CHANGED, SENSOR_EVENT_DATA_UPDATED}; |
| 315 hr = sensor->SetEventInterest(interests, arraysize(interests)); | 346 hr = sensor->SetEventInterest(interests, arraysize(interests)); |
| 316 if (FAILED(hr)) | 347 if (FAILED(hr)) |
| 317 return nullptr; | 348 return nullptr; |
| 318 | 349 |
| 319 return base::WrapUnique( | 350 return base::WrapUnique( |
| 320 new PlatformSensorReaderWin(sensor, std::move(params))); | 351 new PlatformSensorReaderWin(sensor, std::move(params))); |
| 321 } | 352 } |
| 322 | 353 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 void PlatformSensorReaderWin::SensorError() { | 461 void PlatformSensorReaderWin::SensorError() { |
| 431 if (client_) | 462 if (client_) |
| 432 client_->OnSensorError(); | 463 client_->OnSensorError(); |
| 433 } | 464 } |
| 434 | 465 |
| 435 unsigned long PlatformSensorReaderWin::GetMinimalReportingIntervalMs() const { | 466 unsigned long PlatformSensorReaderWin::GetMinimalReportingIntervalMs() const { |
| 436 return init_params_->min_reporting_interval_ms; | 467 return init_params_->min_reporting_interval_ms; |
| 437 } | 468 } |
| 438 | 469 |
| 439 } // namespace device | 470 } // namespace device |
| OLD | NEW |