Bug 1890277: part 1) Add CSP parser tests for `require-trusted-types-for`. r=tschuster
[gecko.git] / hal / windows / WindowsSensor.cpp
blob73bd8bc57cc33c74ebf300f4c6e17a0ff9d8b008
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "Hal.h"
7 #include <sensorsapi.h>
8 #include <sensors.h>
9 #include <portabledevicetypes.h>
11 #define MEAN_GRAVITY 9.80665
12 #define DEFAULT_SENSOR_POLL 100
14 using namespace mozilla::hal;
16 namespace mozilla {
17 namespace hal_impl {
19 static RefPtr<ISensor> sAccelerometer;
21 class SensorEvent final : public ISensorEvents {
22 public:
23 SensorEvent() : mCount(0) {}
25 // IUnknown interface
27 STDMETHODIMP_(ULONG) AddRef() { return InterlockedIncrement(&mCount); }
29 STDMETHODIMP_(ULONG) Release() {
30 ULONG count = InterlockedDecrement(&mCount);
31 if (!count) {
32 delete this;
33 return 0;
35 return count;
38 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) {
39 if (iid == IID_IUnknown) {
40 *ppv = static_cast<IUnknown*>(this);
41 } else if (iid == IID_ISensorEvents) {
42 *ppv = static_cast<ISensorEvents*>(this);
43 } else {
44 return E_NOINTERFACE;
46 AddRef();
47 return S_OK;
50 // ISensorEvents interface
52 STDMETHODIMP OnEvent(ISensor* aSensor, REFGUID aId,
53 IPortableDeviceValues* aData) {
54 return S_OK;
57 STDMETHODIMP OnLeave(REFSENSOR_ID aId) { return S_OK; }
59 STDMETHODIMP OnStateChanged(ISensor* aSensor, SensorState state) {
60 return S_OK;
63 STDMETHODIMP OnDataUpdated(ISensor* aSensor, ISensorDataReport* aReport) {
64 PROPVARIANT v;
65 HRESULT hr;
66 nsTArray<float> values;
68 // X-axis acceleration in g's
69 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &v);
70 if (FAILED(hr)) {
71 return hr;
73 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
75 // Y-axis acceleration in g's
76 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, &v);
77 if (FAILED(hr)) {
78 return hr;
80 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
82 // Z-axis acceleration in g's
83 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, &v);
84 if (FAILED(hr)) {
85 return hr;
87 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
89 hal::SensorData sdata(hal::SENSOR_ACCELERATION, PR_Now(), values);
90 hal::NotifySensorChange(sdata);
92 return S_OK;
95 private:
96 ULONG mCount;
99 void EnableSensorNotifications(SensorType aSensor) {
100 if (aSensor != SENSOR_ACCELERATION) {
101 return;
104 if (sAccelerometer) {
105 return;
108 RefPtr<ISensorManager> manager;
109 if (FAILED(CoCreateInstance(CLSID_SensorManager, nullptr,
110 CLSCTX_INPROC_SERVER, IID_ISensorManager,
111 getter_AddRefs(manager)))) {
112 return;
115 // accelerometer event
117 RefPtr<ISensorCollection> collection;
118 if (FAILED(manager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D,
119 getter_AddRefs(collection)))) {
120 return;
123 ULONG count = 0;
124 collection->GetCount(&count);
125 if (!count) {
126 return;
129 RefPtr<ISensor> sensor;
130 collection->GetAt(0, getter_AddRefs(sensor));
131 if (!sensor) {
132 return;
135 // Set report interval to 100ms if possible.
136 // Default value depends on drivers.
137 RefPtr<IPortableDeviceValues> values;
138 if (SUCCEEDED(CoCreateInstance(
139 CLSID_PortableDeviceValues, nullptr, CLSCTX_INPROC_SERVER,
140 IID_IPortableDeviceValues, getter_AddRefs(values)))) {
141 if (SUCCEEDED(values->SetUnsignedIntegerValue(
142 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, DEFAULT_SENSOR_POLL))) {
143 RefPtr<IPortableDeviceValues> returns;
144 sensor->SetProperties(values, getter_AddRefs(returns));
148 RefPtr<SensorEvent> event = new SensorEvent();
149 RefPtr<ISensorEvents> sensorEvents;
150 if (FAILED(event->QueryInterface(IID_ISensorEvents,
151 getter_AddRefs(sensorEvents)))) {
152 return;
155 if (FAILED(sensor->SetEventSink(sensorEvents))) {
156 return;
159 sAccelerometer = sensor;
162 void DisableSensorNotifications(SensorType aSensor) {
163 if (aSensor == SENSOR_ACCELERATION && sAccelerometer) {
164 sAccelerometer->SetEventSink(nullptr);
165 sAccelerometer = nullptr;
169 } // namespace hal_impl
170 } // namespace mozilla