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 RefPtr
<ISensor
> sAccelerometer
;
21 class SensorEvent final
: public ISensorEvents
{
23 SensorEvent() : mCount(0) {}
27 STDMETHODIMP_(ULONG
) AddRef() { return InterlockedIncrement(&mCount
); }
29 STDMETHODIMP_(ULONG
) Release() {
30 ULONG count
= InterlockedDecrement(&mCount
);
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);
50 // ISensorEvents interface
52 STDMETHODIMP
OnEvent(ISensor
* aSensor
, REFGUID aId
,
53 IPortableDeviceValues
* aData
) {
57 STDMETHODIMP
OnLeave(REFSENSOR_ID aId
) { return S_OK
; }
59 STDMETHODIMP
OnStateChanged(ISensor
* aSensor
, SensorState state
) {
63 STDMETHODIMP
OnDataUpdated(ISensor
* aSensor
, ISensorDataReport
* aReport
) {
66 nsTArray
<float> values
;
68 // X-axis acceleration in g's
69 hr
= aReport
->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G
, &v
);
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
);
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
);
87 values
.AppendElement(float(-v
.dblVal
* MEAN_GRAVITY
));
89 hal::SensorData
sdata(hal::SENSOR_ACCELERATION
, PR_Now(), values
);
90 hal::NotifySensorChange(sdata
);
99 void EnableSensorNotifications(SensorType aSensor
) {
100 if (aSensor
!= SENSOR_ACCELERATION
) {
104 if (sAccelerometer
) {
108 RefPtr
<ISensorManager
> manager
;
109 if (FAILED(CoCreateInstance(CLSID_SensorManager
, nullptr,
110 CLSCTX_INPROC_SERVER
, IID_ISensorManager
,
111 getter_AddRefs(manager
)))) {
115 // accelerometer event
117 RefPtr
<ISensorCollection
> collection
;
118 if (FAILED(manager
->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D
,
119 getter_AddRefs(collection
)))) {
124 collection
->GetCount(&count
);
129 RefPtr
<ISensor
> sensor
;
130 collection
->GetAt(0, getter_AddRefs(sensor
));
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
)))) {
155 if (FAILED(sensor
->SetEventSink(sensorEvents
))) {
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