backoug Bug 1034294 - Fix SharedBufferManagerParent r=jgilbert
[gecko.git] / hal / windows / WindowsSensor.cpp
blobd727565b2bbf0b9a4d68ae0a31e3bf4c2e52991b
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 nsRefPtr<ISensor> sAccelerometer;
21 class SensorEvent MOZ_FINAL : public ISensorEvents {
22 public:
23 SensorEvent() : mCount(0) {
26 // IUnknown interface
28 STDMETHODIMP_(ULONG) AddRef() {
29 return InterlockedIncrement(&mCount);
32 STDMETHODIMP_(ULONG) Release() {
33 ULONG count = InterlockedDecrement(&mCount);
34 if (!count) {
35 delete this;
36 return 0;
38 return count;
41 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) {
42 if (iid == IID_IUnknown) {
43 *ppv = static_cast<IUnknown*>(this);
44 } else if (iid == IID_ISensorEvents) {
45 *ppv = static_cast<ISensorEvents*>(this);
46 } else {
47 return E_NOINTERFACE;
49 AddRef();
50 return S_OK;
53 // ISensorEvents interface
55 STDMETHODIMP OnEvent(ISensor *aSensor, REFGUID aId, IPortableDeviceValues *aData) {
56 return S_OK;
59 STDMETHODIMP OnLeave(REFSENSOR_ID aId) {
60 return S_OK;
63 STDMETHODIMP OnStateChanged(ISensor *aSensor, SensorState state) {
64 return S_OK;
67 STDMETHODIMP OnDataUpdated(ISensor *aSensor, ISensorDataReport *aReport) {
68 PROPVARIANT v;
69 HRESULT hr;
70 InfallibleTArray<float> values;
72 // X-axis acceleration in g's
73 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &v);
74 if (FAILED(hr)) {
75 return hr;
77 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
79 // Y-axis acceleration in g's
80 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, &v);
81 if (FAILED(hr)) {
82 return hr;
84 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
86 // Z-axis acceleration in g's
87 hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, &v);
88 if (FAILED(hr)) {
89 return hr;
91 values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
93 hal::SensorData sdata(hal::SENSOR_ACCELERATION,
94 PR_Now(),
95 values,
96 hal::SENSOR_ACCURACY_UNKNOWN);
97 hal::NotifySensorChange(sdata);
99 return S_OK;
102 private:
103 ULONG mCount;
106 void
107 EnableSensorNotifications(SensorType aSensor)
109 if (aSensor != SENSOR_ACCELERATION) {
110 return;
113 if (sAccelerometer) {
114 return;
117 nsRefPtr<ISensorManager> manager;
118 if (FAILED(CoCreateInstance(CLSID_SensorManager, nullptr,
119 CLSCTX_INPROC_SERVER,
120 IID_ISensorManager,
121 getter_AddRefs(manager)))) {
122 return;
125 // accelerometer event
127 nsRefPtr<ISensorCollection> collection;
128 if (FAILED(manager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D,
129 getter_AddRefs(collection)))) {
130 return;
133 ULONG count = 0;
134 collection->GetCount(&count);
135 if (!count) {
136 return;
139 nsRefPtr<ISensor> sensor;
140 collection->GetAt(0, getter_AddRefs(sensor));
141 if (!sensor) {
142 return;
145 // Set report interval to 100ms if possible.
146 // Default value depends on drivers.
147 nsRefPtr<IPortableDeviceValues> values;
148 if (SUCCEEDED(CoCreateInstance(CLSID_PortableDeviceValues, nullptr,
149 CLSCTX_INPROC_SERVER,
150 IID_IPortableDeviceValues,
151 getter_AddRefs(values)))) {
152 if (SUCCEEDED(values->SetUnsignedIntegerValue(
153 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
154 DEFAULT_SENSOR_POLL))) {
155 nsRefPtr<IPortableDeviceValues> returns;
156 sensor->SetProperties(values, getter_AddRefs(returns));
160 nsRefPtr<SensorEvent> event = new SensorEvent();
161 nsRefPtr<ISensorEvents> sensorEvents;
162 if (FAILED(event->QueryInterface(IID_ISensorEvents,
163 getter_AddRefs(sensorEvents)))) {
164 return;
167 if (FAILED(sensor->SetEventSink(sensorEvents))) {
168 return;
171 sAccelerometer = sensor;
174 void
175 DisableSensorNotifications(SensorType aSensor)
177 if (aSensor == SENSOR_ACCELERATION && sAccelerometer) {
178 sAccelerometer->SetEventSink(nullptr);
179 sAccelerometer = nullptr;
183 } // hal_impl
184 } // mozilla