| 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 "base/win/scoped_propvariant.h" |
| 15 #include "device/generic_sensor/generic_sensor_consts.h" | 15 #include "device/generic_sensor/generic_sensor_consts.h" |
| 16 #include "device/generic_sensor/public/cpp/platform_sensor_configuration.h" | 16 #include "device/generic_sensor/public/cpp/platform_sensor_configuration.h" |
| 17 #include "device/generic_sensor/public/cpp/sensor_reading.h" | 17 #include "device/generic_sensor/public/cpp/sensor_reading.h" |
| 18 | 18 |
| 19 namespace device { | 19 namespace device { |
| 20 | 20 |
| 21 // Init params for the PlatformSensorReaderWin. | 21 // Init params for the PlatformSensorReaderWin. |
| 22 struct ReaderInitParams { | 22 struct ReaderInitParams { |
| 23 // ISensorDataReport::GetSensorValue is not const, therefore, report | 23 // ISensorDataReport::GetSensorValue is not const, therefore, report |
| 24 // cannot be passed as const ref. | 24 // cannot be passed as const ref. |
| 25 // ISensorDataReport& report - report that contains new sensor data. | 25 // ISensorDataReport* report - report that contains new sensor data. |
| 26 // SensorReading& reading - out parameter that must be populated. | 26 // SensorReading* reading - out parameter that must be populated. |
| 27 // Returns HRESULT - S_OK on success, otherwise error code. | 27 // Returns HRESULT - S_OK on success, otherwise error code. |
| 28 using ReaderFunctor = base::Callback<HRESULT(ISensorDataReport& report, | 28 using ReaderFunctor = base::Callback<HRESULT(ISensorDataReport* report, |
| 29 SensorReading& reading)>; | 29 SensorReading* reading)>; |
| 30 SENSOR_TYPE_ID sensor_type_id; | 30 SENSOR_TYPE_ID sensor_type_id; |
| 31 ReaderFunctor reader_func; | 31 ReaderFunctor reader_func; |
| 32 unsigned long min_reporting_interval_ms = 0; | 32 unsigned long min_reporting_interval_ms = 0; |
| 33 }; | 33 }; |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 // Gets value from the report for provided key. | 37 // Gets value from the report for provided key. |
| 38 bool GetReadingValueForProperty(REFPROPERTYKEY key, | 38 bool GetReadingValueForProperty(REFPROPERTYKEY key, |
| 39 ISensorDataReport& report, | 39 ISensorDataReport* report, |
| 40 double* value) { | 40 double* value) { |
| 41 DCHECK(value); | 41 DCHECK(value); |
| 42 base::win::ScopedPropVariant variant_value; | 42 base::win::ScopedPropVariant variant_value; |
| 43 if (SUCCEEDED(report.GetSensorValue(key, variant_value.Receive()))) { | 43 if (SUCCEEDED(report->GetSensorValue(key, variant_value.Receive()))) { |
| 44 if (variant_value.get().vt == VT_R8) | 44 if (variant_value.get().vt == VT_R8) |
| 45 *value = variant_value.get().dblVal; | 45 *value = variant_value.get().dblVal; |
| 46 else if (variant_value.get().vt == VT_R4) | 46 else if (variant_value.get().vt == VT_R4) |
| 47 *value = variant_value.get().fltVal; | 47 *value = variant_value.get().fltVal; |
| 48 else | 48 else |
| 49 return false; | 49 return false; |
| 50 return true; | 50 return true; |
| 51 } | 51 } |
| 52 | 52 |
| 53 *value = 0; | 53 *value = 0; |
| 54 return false; | 54 return false; |
| 55 } | 55 } |
| 56 | 56 |
| 57 // Ambient light sensor reader initialization parameters. | 57 // Ambient light sensor reader initialization parameters. |
| 58 std::unique_ptr<ReaderInitParams> CreateAmbientLightReaderInitParams() { | 58 std::unique_ptr<ReaderInitParams> CreateAmbientLightReaderInitParams() { |
| 59 auto params = base::MakeUnique<ReaderInitParams>(); | 59 auto params = base::MakeUnique<ReaderInitParams>(); |
| 60 params->sensor_type_id = SENSOR_TYPE_AMBIENT_LIGHT; | 60 params->sensor_type_id = SENSOR_TYPE_AMBIENT_LIGHT; |
| 61 params->reader_func = | 61 params->reader_func = |
| 62 base::Bind([](ISensorDataReport& report, SensorReading& reading) { | 62 base::Bind([](ISensorDataReport* report, SensorReading* reading) { |
| 63 double lux = 0.0; | 63 double lux = 0.0; |
| 64 if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, | 64 if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, |
| 65 report, &lux)) { | 65 report, &lux)) { |
| 66 return E_FAIL; | 66 return E_FAIL; |
| 67 } | 67 } |
| 68 reading.values[0] = lux; | 68 reading->values[0] = lux; |
| 69 return S_OK; | 69 return S_OK; |
| 70 }); | 70 }); |
| 71 return params; | 71 return params; |
| 72 } | 72 } |
| 73 | 73 |
| 74 // Accelerometer sensor reader initialization parameters. | 74 // Accelerometer sensor reader initialization parameters. |
| 75 std::unique_ptr<ReaderInitParams> CreateAccelerometerReaderInitParams() { | 75 std::unique_ptr<ReaderInitParams> CreateAccelerometerReaderInitParams() { |
| 76 auto params = base::MakeUnique<ReaderInitParams>(); | 76 auto params = base::MakeUnique<ReaderInitParams>(); |
| 77 params->sensor_type_id = SENSOR_TYPE_ACCELEROMETER_3D; | 77 params->sensor_type_id = SENSOR_TYPE_ACCELEROMETER_3D; |
| 78 params->reader_func = | 78 params->reader_func = |
| 79 base::Bind([](ISensorDataReport& report, SensorReading& reading) { | 79 base::Bind([](ISensorDataReport* report, SensorReading* reading) { |
| 80 double x = 0.0; | 80 double x = 0.0; |
| 81 double y = 0.0; | 81 double y = 0.0; |
| 82 double z = 0.0; | 82 double z = 0.0; |
| 83 if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_X_G, | 83 if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_X_G, |
| 84 report, &x) || | 84 report, &x) || |
| 85 !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Y_G, | 85 !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Y_G, |
| 86 report, &y) || | 86 report, &y) || |
| 87 !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Z_G, | 87 !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Z_G, |
| 88 report, &z)) { | 88 report, &z)) { |
| 89 return E_FAIL; | 89 return E_FAIL; |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Windows uses coordinate system where Z axis points down from device | 92 // Windows uses coordinate system where Z axis points down from device |
| 93 // screen, therefore, using right hand notation, we have to reverse | 93 // screen, therefore, using right hand notation, we have to reverse |
| 94 // sign for each axis. Values are converted from G/s^2 to m/s^2. | 94 // sign for each axis. Values are converted from G/s^2 to m/s^2. |
| 95 reading.values[0] = -x * kMeanGravity; | 95 reading->values[0] = -x * kMeanGravity; |
| 96 reading.values[1] = -y * kMeanGravity; | 96 reading->values[1] = -y * kMeanGravity; |
| 97 reading.values[2] = -z * kMeanGravity; | 97 reading->values[2] = -z * kMeanGravity; |
| 98 return S_OK; | 98 return S_OK; |
| 99 }); | 99 }); |
| 100 return params; | 100 return params; |
| 101 } | 101 } |
| 102 | 102 |
| 103 // Gyroscope sensor reader initialization parameters. | 103 // Gyroscope sensor reader initialization parameters. |
| 104 std::unique_ptr<ReaderInitParams> CreateGyroscopeReaderInitParams() { | 104 std::unique_ptr<ReaderInitParams> CreateGyroscopeReaderInitParams() { |
| 105 auto params = base::MakeUnique<ReaderInitParams>(); | 105 auto params = base::MakeUnique<ReaderInitParams>(); |
| 106 params->sensor_type_id = SENSOR_TYPE_GYROMETER_3D; | 106 params->sensor_type_id = SENSOR_TYPE_GYROMETER_3D; |
| 107 params->reader_func = base::Bind([](ISensorDataReport& report, | 107 params->reader_func = base::Bind([](ISensorDataReport* report, |
| 108 SensorReading& reading) { | 108 SensorReading* reading) { |
| 109 double x = 0.0; | 109 double x = 0.0; |
| 110 double y = 0.0; | 110 double y = 0.0; |
| 111 double z = 0.0; | 111 double z = 0.0; |
| 112 if (!GetReadingValueForProperty( | 112 if (!GetReadingValueForProperty( |
| 113 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, report, | 113 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, report, |
| 114 &x) || | 114 &x) || |
| 115 !GetReadingValueForProperty( | 115 !GetReadingValueForProperty( |
| 116 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, report, | 116 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, report, |
| 117 &y) || | 117 &y) || |
| 118 !GetReadingValueForProperty( | 118 !GetReadingValueForProperty( |
| 119 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, report, | 119 SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, report, |
| 120 &z)) { | 120 &z)) { |
| 121 return E_FAIL; | 121 return E_FAIL; |
| 122 } | 122 } |
| 123 | 123 |
| 124 // Windows uses coordinate system where Z axis points down from device | 124 // Windows uses coordinate system where Z axis points down from device |
| 125 // screen, therefore, using right hand notation, we have to reverse | 125 // screen, therefore, using right hand notation, we have to reverse |
| 126 // sign for each axis. Values are converted from deg to rad. | 126 // sign for each axis. Values are converted from deg to rad. |
| 127 reading.values[0] = -x * kRadiansInDegrees; | 127 reading->values[0] = -x * kRadiansInDegrees; |
| 128 reading.values[1] = -y * kRadiansInDegrees; | 128 reading->values[1] = -y * kRadiansInDegrees; |
| 129 reading.values[2] = -z * kRadiansInDegrees; | 129 reading->values[2] = -z * kRadiansInDegrees; |
| 130 return S_OK; | 130 return S_OK; |
| 131 }); | 131 }); |
| 132 return params; | 132 return params; |
| 133 } | 133 } |
| 134 | 134 |
| 135 // Magnetometer sensor reader initialization parameters. | 135 // Magnetometer sensor reader initialization parameters. |
| 136 std::unique_ptr<ReaderInitParams> CreateMagnetometerReaderInitParams() { | 136 std::unique_ptr<ReaderInitParams> CreateMagnetometerReaderInitParams() { |
| 137 auto params = base::MakeUnique<ReaderInitParams>(); | 137 auto params = base::MakeUnique<ReaderInitParams>(); |
| 138 params->sensor_type_id = SENSOR_TYPE_COMPASS_3D; | 138 params->sensor_type_id = SENSOR_TYPE_COMPASS_3D; |
| 139 params->reader_func = | 139 params->reader_func = |
| 140 base::Bind([](ISensorDataReport& report, SensorReading& reading) { | 140 base::Bind([](ISensorDataReport* report, SensorReading* reading) { |
| 141 double x = 0.0; | 141 double x = 0.0; |
| 142 double y = 0.0; | 142 double y = 0.0; |
| 143 double z = 0.0; | 143 double z = 0.0; |
| 144 if (!GetReadingValueForProperty( | 144 if (!GetReadingValueForProperty( |
| 145 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_X_MILLIGAUSS, report, | 145 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_X_MILLIGAUSS, report, |
| 146 &x) || | 146 &x) || |
| 147 !GetReadingValueForProperty( | 147 !GetReadingValueForProperty( |
| 148 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Y_MILLIGAUSS, report, | 148 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Y_MILLIGAUSS, report, |
| 149 &y) || | 149 &y) || |
| 150 !GetReadingValueForProperty( | 150 !GetReadingValueForProperty( |
| 151 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Z_MILLIGAUSS, report, | 151 SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Z_MILLIGAUSS, report, |
| 152 &z)) { | 152 &z)) { |
| 153 return E_FAIL; | 153 return E_FAIL; |
| 154 } | 154 } |
| 155 | 155 |
| 156 // Windows uses coordinate system where Z axis points down from device | 156 // Windows uses coordinate system where Z axis points down from device |
| 157 // screen, therefore, using right hand notation, we have to reverse | 157 // screen, therefore, using right hand notation, we have to reverse |
| 158 // sign for each axis. Values are converted from Milligaus to | 158 // sign for each axis. Values are converted from Milligaus to |
| 159 // Microtesla. | 159 // Microtesla. |
| 160 reading.values[0] = -x * kMicroteslaInMilligauss; | 160 reading->values[0] = -x * kMicroteslaInMilligauss; |
| 161 reading.values[1] = -y * kMicroteslaInMilligauss; | 161 reading->values[1] = -y * kMicroteslaInMilligauss; |
| 162 reading.values[2] = -z * kMicroteslaInMilligauss; | 162 reading->values[2] = -z * kMicroteslaInMilligauss; |
| 163 return S_OK; | 163 return S_OK; |
| 164 }); | 164 }); |
| 165 return params; | 165 return params; |
| 166 } | 166 } |
| 167 | 167 |
| 168 // AbsoluteOrientation sensor reader initialization parameters. | 168 // AbsoluteOrientation sensor reader initialization parameters. |
| 169 std::unique_ptr<ReaderInitParams> CreateAbsoluteOrientationReaderInitParams() { | 169 std::unique_ptr<ReaderInitParams> CreateAbsoluteOrientationReaderInitParams() { |
| 170 auto params = base::MakeUnique<ReaderInitParams>(); | 170 auto params = base::MakeUnique<ReaderInitParams>(); |
| 171 params->sensor_type_id = SENSOR_TYPE_AGGREGATED_DEVICE_ORIENTATION; | 171 params->sensor_type_id = SENSOR_TYPE_AGGREGATED_DEVICE_ORIENTATION; |
| 172 params->reader_func = | 172 params->reader_func = |
| 173 base::Bind([](ISensorDataReport& report, SensorReading& reading) { | 173 base::Bind([](ISensorDataReport* report, SensorReading* reading) { |
| 174 base::win::ScopedPropVariant quat_variant; | 174 base::win::ScopedPropVariant quat_variant; |
| 175 HRESULT hr = report.GetSensorValue(SENSOR_DATA_TYPE_QUATERNION, | 175 HRESULT hr = report->GetSensorValue(SENSOR_DATA_TYPE_QUATERNION, |
| 176 quat_variant.Receive()); | 176 quat_variant.Receive()); |
| 177 if (FAILED(hr) || quat_variant.get().vt != (VT_VECTOR | VT_UI1) || | 177 if (FAILED(hr) || quat_variant.get().vt != (VT_VECTOR | VT_UI1) || |
| 178 quat_variant.get().caub.cElems < 16) { | 178 quat_variant.get().caub.cElems < 16) { |
| 179 return E_FAIL; | 179 return E_FAIL; |
| 180 } | 180 } |
| 181 | 181 |
| 182 float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems); | 182 float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems); |
| 183 | 183 |
| 184 // Windows uses coordinate system where Z axis points down from device | 184 // Windows uses coordinate system where Z axis points down from device |
| 185 // screen, therefore, using right hand notation, we have to reverse | 185 // screen, therefore, using right hand notation, we have to reverse |
| 186 // sign for each quaternion component. | 186 // sign for each quaternion component. |
| 187 reading.values[0] = -quat[0]; // x*sin(Theta/2) | 187 reading->values[0] = -quat[0]; // x*sin(Theta/2) |
| 188 reading.values[1] = -quat[1]; // y*sin(Theta/2) | 188 reading->values[1] = -quat[1]; // y*sin(Theta/2) |
| 189 reading.values[2] = -quat[2]; // z*sin(Theta/2) | 189 reading->values[2] = -quat[2]; // z*sin(Theta/2) |
| 190 reading.values[3] = quat[3]; // cos(Theta/2) | 190 reading->values[3] = quat[3]; // cos(Theta/2) |
| 191 return S_OK; | 191 return S_OK; |
| 192 }); | 192 }); |
| 193 return params; | 193 return params; |
| 194 } | 194 } |
| 195 | 195 |
| 196 // Creates ReaderInitParams params structure. To implement support for new | 196 // Creates ReaderInitParams params structure. To implement support for new |
| 197 // 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 |
| 198 // be set: | 198 // be set: |
| 199 // sensor_type_id - GUID of the sensor supported by Windows. | 199 // sensor_type_id - GUID of the sensor supported by Windows. |
| 200 // reader_func - Functor that is responsible to populate SensorReading from | 200 // reader_func - Functor that is responsible to populate SensorReading from |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 | 302 |
| 303 base::TimeDelta delta = time_now - timestamp; | 303 base::TimeDelta delta = time_now - timestamp; |
| 304 | 304 |
| 305 SensorReading reading; | 305 SensorReading reading; |
| 306 reading.timestamp = ((ticks_now - delta) - base::TimeTicks()).InSecondsF(); | 306 reading.timestamp = ((ticks_now - delta) - base::TimeTicks()).InSecondsF(); |
| 307 | 307 |
| 308 // Discard update events that have non-monotonically increasing timestamp. | 308 // Discard update events that have non-monotonically increasing timestamp. |
| 309 if (last_sensor_reading_.timestamp > reading.timestamp) | 309 if (last_sensor_reading_.timestamp > reading.timestamp) |
| 310 return E_FAIL; | 310 return E_FAIL; |
| 311 | 311 |
| 312 hr = platform_sensor_reader_->SensorReadingChanged(*report, reading); | 312 hr = platform_sensor_reader_->SensorReadingChanged(report, &reading); |
| 313 if (SUCCEEDED(hr)) | 313 if (SUCCEEDED(hr)) |
| 314 last_sensor_reading_ = reading; | 314 last_sensor_reading_ = reading; |
| 315 return hr; | 315 return hr; |
| 316 } | 316 } |
| 317 | 317 |
| 318 private: | 318 private: |
| 319 PlatformSensorReaderWin* const platform_sensor_reader_; | 319 PlatformSensorReaderWin* const platform_sensor_reader_; |
| 320 SensorReading last_sensor_reading_; | 320 SensorReading last_sensor_reading_; |
| 321 | 321 |
| 322 DISALLOW_COPY_AND_ASSIGN(EventListener); | 322 DISALLOW_COPY_AND_ASSIGN(EventListener); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 if (SUCCEEDED(hr)) { | 440 if (SUCCEEDED(hr)) { |
| 441 base::win::ScopedComPtr<IPortableDeviceValues> return_props; | 441 base::win::ScopedComPtr<IPortableDeviceValues> return_props; |
| 442 hr = sensor_->SetProperties(props.Get(), return_props.GetAddressOf()); | 442 hr = sensor_->SetProperties(props.Get(), return_props.GetAddressOf()); |
| 443 return SUCCEEDED(hr); | 443 return SUCCEEDED(hr); |
| 444 } | 444 } |
| 445 } | 445 } |
| 446 return false; | 446 return false; |
| 447 } | 447 } |
| 448 | 448 |
| 449 HRESULT PlatformSensorReaderWin::SensorReadingChanged( | 449 HRESULT PlatformSensorReaderWin::SensorReadingChanged( |
| 450 ISensorDataReport& report, | 450 ISensorDataReport* report, |
| 451 SensorReading& reading) const { | 451 SensorReading* reading) const { |
| 452 if (!client_) | 452 if (!client_) |
| 453 return E_FAIL; | 453 return E_FAIL; |
| 454 | 454 |
| 455 HRESULT hr = init_params_->reader_func.Run(report, reading); | 455 HRESULT hr = init_params_->reader_func.Run(report, reading); |
| 456 if (SUCCEEDED(hr)) | 456 if (SUCCEEDED(hr)) |
| 457 client_->OnReadingUpdated(reading); | 457 client_->OnReadingUpdated(*reading); |
| 458 return hr; | 458 return hr; |
| 459 } | 459 } |
| 460 | 460 |
| 461 void PlatformSensorReaderWin::SensorError() { | 461 void PlatformSensorReaderWin::SensorError() { |
| 462 if (client_) | 462 if (client_) |
| 463 client_->OnSensorError(); | 463 client_->OnSensorError(); |
| 464 } | 464 } |
| 465 | 465 |
| 466 unsigned long PlatformSensorReaderWin::GetMinimalReportingIntervalMs() const { | 466 unsigned long PlatformSensorReaderWin::GetMinimalReportingIntervalMs() const { |
| 467 return init_params_->min_reporting_interval_ms; | 467 return init_params_->min_reporting_interval_ms; |
| 468 } | 468 } |
| 469 | 469 |
| 470 } // namespace device | 470 } // namespace device |
| OLD | NEW |