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/. */
7 #include <sensorsapi.h>
9 #include <portabledevicetypes.h>
11 #define MEAN_GRAVITY 9.80665
12 #define DEFAULT_SENSOR_POLL 100
14 using namespace mozilla::hal
;
19 static nsRefPtr
<ISensor
> sAccelerometer
;
21 class SensorEvent MOZ_FINAL
: public ISensorEvents
{
23 SensorEvent() : mCount(0) {
28 STDMETHODIMP_(ULONG
) AddRef() {
29 return InterlockedIncrement(&mCount
);
32 STDMETHODIMP_(ULONG
) Release() {
33 ULONG count
= InterlockedDecrement(&mCount
);
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);
53 // ISensorEvents interface
55 STDMETHODIMP
OnEvent(ISensor
*aSensor
, REFGUID aId
, IPortableDeviceValues
*aData
) {
59 STDMETHODIMP
OnLeave(REFSENSOR_ID aId
) {
63 STDMETHODIMP
OnStateChanged(ISensor
*aSensor
, SensorState state
) {
67 STDMETHODIMP
OnDataUpdated(ISensor
*aSensor
, ISensorDataReport
*aReport
) {
70 InfallibleTArray
<float> values
;
72 // X-axis acceleration in g's
73 hr
= aReport
->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G
, &v
);
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
);
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
);
91 values
.AppendElement(float(-v
.dblVal
* MEAN_GRAVITY
));
93 hal::SensorData
sdata(hal::SENSOR_ACCELERATION
,
96 hal::SENSOR_ACCURACY_UNKNOWN
);
97 hal::NotifySensorChange(sdata
);
107 EnableSensorNotifications(SensorType aSensor
)
109 if (aSensor
!= SENSOR_ACCELERATION
) {
113 if (sAccelerometer
) {
117 nsRefPtr
<ISensorManager
> manager
;
118 if (FAILED(CoCreateInstance(CLSID_SensorManager
, NULL
, CLSCTX_INPROC_SERVER
,
119 IID_ISensorManager
, getter_AddRefs(manager
)))) {
123 // accelerometer event
125 nsRefPtr
<ISensorCollection
> collection
;
126 if (FAILED(manager
->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D
,
127 getter_AddRefs(collection
)))) {
132 collection
->GetCount(&count
);
137 nsRefPtr
<ISensor
> sensor
;
138 collection
->GetAt(0, getter_AddRefs(sensor
));
143 // Set report interval to 100ms if possible.
144 // Default value depends on drivers.
145 nsRefPtr
<IPortableDeviceValues
> values
;
146 if (SUCCEEDED(CoCreateInstance(CLSID_PortableDeviceValues
, NULL
,
147 CLSCTX_INPROC_SERVER
,
148 IID_IPortableDeviceValues
,
149 getter_AddRefs(values
)))) {
150 if (SUCCEEDED(values
->SetUnsignedIntegerValue(
151 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL
,
152 DEFAULT_SENSOR_POLL
))) {
153 nsRefPtr
<IPortableDeviceValues
> returns
;
154 sensor
->SetProperties(values
, getter_AddRefs(returns
));
158 nsRefPtr
<SensorEvent
> event
= new SensorEvent();
159 nsRefPtr
<ISensorEvents
> sensorEvents
;
160 if (FAILED(event
->QueryInterface(IID_ISensorEvents
,
161 getter_AddRefs(sensorEvents
)))) {
165 if (FAILED(sensor
->SetEventSink(sensorEvents
))) {
169 sAccelerometer
= sensor
;
173 DisableSensorNotifications(SensorType aSensor
)
175 if (aSensor
== SENSOR_ACCELERATION
&& sAccelerometer
) {
176 sAccelerometer
->SetEventSink(NULL
);
177 sAccelerometer
= nullptr;