123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "Hal.h"
- #include <sensorsapi.h>
- #include <sensors.h>
- #include <portabledevicetypes.h>
- #define MEAN_GRAVITY 9.80665
- #define DEFAULT_SENSOR_POLL 100
- using namespace mozilla::hal;
- namespace mozilla {
- namespace hal_impl {
- static RefPtr<ISensor> sAccelerometer;
- class SensorEvent final : public ISensorEvents {
- public:
- SensorEvent() : mCount(0) {
- }
- // IUnknown interface
- STDMETHODIMP_(ULONG) AddRef() {
- return InterlockedIncrement(&mCount);
- }
- STDMETHODIMP_(ULONG) Release() {
- ULONG count = InterlockedDecrement(&mCount);
- if (!count) {
- delete this;
- return 0;
- }
- return count;
- }
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv) {
- if (iid == IID_IUnknown) {
- *ppv = static_cast<IUnknown*>(this);
- } else if (iid == IID_ISensorEvents) {
- *ppv = static_cast<ISensorEvents*>(this);
- } else {
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- // ISensorEvents interface
- STDMETHODIMP OnEvent(ISensor *aSensor, REFGUID aId, IPortableDeviceValues *aData) {
- return S_OK;
- }
- STDMETHODIMP OnLeave(REFSENSOR_ID aId) {
- return S_OK;
- }
- STDMETHODIMP OnStateChanged(ISensor *aSensor, SensorState state) {
- return S_OK;
- }
- STDMETHODIMP OnDataUpdated(ISensor *aSensor, ISensorDataReport *aReport) {
- PROPVARIANT v;
- HRESULT hr;
- InfallibleTArray<float> values;
- // X-axis acceleration in g's
- hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &v);
- if (FAILED(hr)) {
- return hr;
- }
- values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
- // Y-axis acceleration in g's
- hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, &v);
- if (FAILED(hr)) {
- return hr;
- }
- values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
- // Z-axis acceleration in g's
- hr = aReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, &v);
- if (FAILED(hr)) {
- return hr;
- }
- values.AppendElement(float(-v.dblVal * MEAN_GRAVITY));
- hal::SensorData sdata(hal::SENSOR_ACCELERATION,
- PR_Now(),
- values,
- hal::SENSOR_ACCURACY_UNKNOWN);
- hal::NotifySensorChange(sdata);
- return S_OK;
- }
- private:
- ULONG mCount;
- };
- void
- EnableSensorNotifications(SensorType aSensor)
- {
- if (aSensor != SENSOR_ACCELERATION) {
- return;
- }
- if (sAccelerometer) {
- return;
- }
- RefPtr<ISensorManager> manager;
- if (FAILED(CoCreateInstance(CLSID_SensorManager, nullptr,
- CLSCTX_INPROC_SERVER,
- IID_ISensorManager,
- getter_AddRefs(manager)))) {
- return;
- }
- // accelerometer event
- RefPtr<ISensorCollection> collection;
- if (FAILED(manager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D,
- getter_AddRefs(collection)))) {
- return;
- }
- ULONG count = 0;
- collection->GetCount(&count);
- if (!count) {
- return;
- }
- RefPtr<ISensor> sensor;
- collection->GetAt(0, getter_AddRefs(sensor));
- if (!sensor) {
- return;
- }
- // Set report interval to 100ms if possible.
- // Default value depends on drivers.
- RefPtr<IPortableDeviceValues> values;
- if (SUCCEEDED(CoCreateInstance(CLSID_PortableDeviceValues, nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IPortableDeviceValues,
- getter_AddRefs(values)))) {
- if (SUCCEEDED(values->SetUnsignedIntegerValue(
- SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
- DEFAULT_SENSOR_POLL))) {
- RefPtr<IPortableDeviceValues> returns;
- sensor->SetProperties(values, getter_AddRefs(returns));
- }
- }
- RefPtr<SensorEvent> event = new SensorEvent();
- RefPtr<ISensorEvents> sensorEvents;
- if (FAILED(event->QueryInterface(IID_ISensorEvents,
- getter_AddRefs(sensorEvents)))) {
- return;
- }
- if (FAILED(sensor->SetEventSink(sensorEvents))) {
- return;
- }
- sAccelerometer = sensor;
- }
- void
- DisableSensorNotifications(SensorType aSensor)
- {
- if (aSensor == SENSOR_ACCELERATION && sAccelerometer) {
- sAccelerometer->SetEventSink(nullptr);
- sAccelerometer = nullptr;
- }
- }
- } // hal_impl
- } // mozilla
|