10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file. 458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "data_fetcher_shared_memory.h" 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <GuidDef.h> 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <InitGuid.h> 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <PortableDeviceTypes.h> 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <Sensors.h> 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/logging.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/win/iunknown_impl.h" 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/win/windows_version.h" 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace { 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const double kMeanGravity = 9.80665; 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace content { 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class DataFetcherSharedMemory::SensorEventSink 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public ISensorEvents, public base::win::IUnknownImpl { 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SensorEventSink() {} 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~SensorEventSink() {} 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // IUnknown interface 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ULONG STDMETHODCALLTYPE AddRef() OVERRIDE { 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return IUnknownImpl::AddRef(); 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ULONG STDMETHODCALLTYPE Release() OVERRIDE { 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return IUnknownImpl::Release(); 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual STDMETHODIMP QueryInterface(REFIID riid, void** ppv) OVERRIDE { 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (riid == __uuidof(ISensorEvents)) { 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *ppv = static_cast<ISensorEvents*>(this); 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AddRef(); 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return S_OK; 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return IUnknownImpl::QueryInterface(riid, ppv); 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ISensorEvents interface 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) STDMETHODIMP OnEvent(ISensor* sensor, 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) REFGUID event_id, 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) IPortableDeviceValues* event_data) OVERRIDE { 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return S_OK; 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) OVERRIDE { 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return S_OK; 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) OVERRIDE { 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return S_OK; 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) STDMETHODIMP OnDataUpdated(ISensor* sensor, 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ISensorDataReport* new_data) OVERRIDE { 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (NULL == new_data || NULL == sensor) 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return E_INVALIDARG; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return UpdateSharedMemoryBuffer(sensor, new_data) ? S_OK : E_FAIL; 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)protected: 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual bool UpdateSharedMemoryBuffer( 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ISensor* sensor, ISensorDataReport* new_data) = 0; 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void GetSensorValue(REFPROPERTYKEY property, ISensorDataReport* new_data, 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) double* value, bool* has_value) { 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PROPVARIANT variant_value = {}; 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (SUCCEEDED(new_data->GetSensorValue(property, &variant_value))) { 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (variant_value.vt == VT_R8) 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *value = variant_value.dblVal; 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (variant_value.vt == VT_R4) 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *value = variant_value.fltVal; 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *has_value = true; 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *value = 0; 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *has_value = false; 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SensorEventSink); 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class DataFetcherSharedMemory::SensorEventSinkOrientation 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public DataFetcherSharedMemory::SensorEventSink { 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit SensorEventSinkOrientation( 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DeviceOrientationHardwareBuffer* const buffer) : buffer_(buffer) {} 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~SensorEventSinkOrientation() {} 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)protected: 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual bool UpdateSharedMemoryBuffer( 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ISensor* sensor, ISensorDataReport* new_data) OVERRIDE { 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) double alpha, beta, gamma; 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_alpha, has_beta, has_gamma; 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_TILT_X_DEGREES, new_data, &alpha, 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &has_alpha); 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_TILT_Y_DEGREES, new_data, &beta, 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &has_beta); 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_TILT_Z_DEGREES, new_data, &gamma, 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &has_gamma); 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (buffer_) { 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->seqlock.WriteBegin(); 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.alpha = alpha; 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.hasAlpha = has_alpha; 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.beta = beta; 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.hasBeta = has_beta; 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.gamma = gamma; 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.hasGamma = has_gamma; 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.absolute = true; 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.hasAbsolute = has_alpha || has_beta || has_gamma; 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->data.allAvailableSensorsAreActive = true; 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer_->seqlock.WriteEnd(); 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DeviceOrientationHardwareBuffer* const buffer_; 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SensorEventSinkOrientation); 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class DataFetcherSharedMemory::SensorEventSinkMotion 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public DataFetcherSharedMemory::SensorEventSink { 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit SensorEventSinkMotion(DeviceMotionHardwareBuffer* const buffer) 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : buffer_(buffer) {} 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~SensorEventSinkMotion() {} 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected: 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual bool UpdateSharedMemoryBuffer( 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ISensor* sensor, ISensorDataReport* new_data) OVERRIDE { 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SENSOR_TYPE_ID sensor_type = GUID_NULL; 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!SUCCEEDED(sensor->GetType(&sensor_type))) 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsEqualIID(sensor_type, SENSOR_TYPE_ACCELEROMETER_3D)) { 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) double acceleration_including_gravity_x; 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) double acceleration_including_gravity_y; 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) double acceleration_including_gravity_z; 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool has_acceleration_including_gravity_x; 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool has_acceleration_including_gravity_y; 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool has_acceleration_including_gravity_z; 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, new_data, 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &acceleration_including_gravity_x, 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &has_acceleration_including_gravity_x); 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, new_data, 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &acceleration_including_gravity_y, 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &has_acceleration_including_gravity_y); 16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, new_data, 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &acceleration_including_gravity_z, 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &has_acceleration_including_gravity_z); 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (buffer_) { 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->seqlock.WriteBegin(); 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.accelerationIncludingGravityX = 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) -acceleration_including_gravity_x * kMeanGravity; 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasAccelerationIncludingGravityX = 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_acceleration_including_gravity_x; 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.accelerationIncludingGravityY = 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) -acceleration_including_gravity_y * kMeanGravity; 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasAccelerationIncludingGravityY = 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_acceleration_including_gravity_y; 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.accelerationIncludingGravityZ = 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) -acceleration_including_gravity_z * kMeanGravity; 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasAccelerationIncludingGravityZ = 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_acceleration_including_gravity_z; 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(timvolodine): consider setting this after all 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // sensors have fired. 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.allAvailableSensorsAreActive = true; 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->seqlock.WriteEnd(); 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (IsEqualIID(sensor_type, SENSOR_TYPE_GYROMETER_3D)) { 19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) double alpha, beta, gamma; 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_alpha, has_beta, has_gamma; 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, 19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_data, &alpha, &has_alpha); 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_data, &beta, &has_beta); 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_data, &gamma, &has_gamma); 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (buffer_) { 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->seqlock.WriteBegin(); 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.rotationRateAlpha = alpha; 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasRotationRateAlpha = has_alpha; 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.rotationRateBeta = beta; 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasRotationRateBeta = has_beta; 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.rotationRateGamma = gamma; 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.hasRotationRateGamma = has_gamma; 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->data.allAvailableSensorsAreActive = true; 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) buffer_->seqlock.WriteEnd(); 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DeviceMotionHardwareBuffer* const buffer_; 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SensorEventSinkMotion); 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }; 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DataFetcherSharedMemory::DataFetcherSharedMemory() 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : motion_buffer_(NULL), 22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) orientation_buffer_(NULL) { 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)DataFetcherSharedMemory::~DataFetcherSharedMemory() { 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataFetcherSharedMemory::FetcherType DataFetcherSharedMemory::GetType() const { 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return FETCHER_TYPE_SEPARATE_THREAD; 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) { 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(buffer); 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (consumer_type) { 24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case CONSUMER_TYPE_ORIENTATION: 24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) orientation_buffer_ = 24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<DeviceOrientationHardwareBuffer*>(buffer); 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<SensorEventSink> sink( 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new SensorEventSinkOrientation(orientation_buffer_)); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool inclinometer_available = RegisterForSensor( 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SENSOR_TYPE_INCLINOMETER_3D, sensor_inclinometer_.Receive(), sink); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("InertialSensor.InclinometerWindowsAvailable", 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) inclinometer_available); 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (inclinometer_available) 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // if no sensors are available set buffer to ready, to fire null-events. 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SetBufferAvailableState(consumer_type, true); 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case CONSUMER_TYPE_MOTION: 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer); 26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<SensorEventSink> sink( 26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new SensorEventSinkMotion(motion_buffer_)); 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool accelerometer_available = RegisterForSensor( 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SENSOR_TYPE_ACCELEROMETER_3D, sensor_accelerometer_.Receive(), 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sink); 26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool gyrometer_available = RegisterForSensor( 26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SENSOR_TYPE_GYROMETER_3D, sensor_gyrometer_.Receive(), sink); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("InertialSensor.AccelerometerWindowsAvailable", 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accelerometer_available); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("InertialSensor.GyrometerWindowsAvailable", 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gyrometer_available); 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (accelerometer_available || gyrometer_available) { 2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) motion_buffer_->seqlock.WriteBegin(); 2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) motion_buffer_->data.interval = GetInterval().InMilliseconds(); 2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) motion_buffer_->seqlock.WriteEnd(); 27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // if no sensors are available set buffer to ready, to fire null-events. 27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SetBufferAvailableState(consumer_type, true); 28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break; 28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) default: 28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DisableSensors(consumer_type); 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetBufferAvailableState(consumer_type, false); 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (consumer_type) { 29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case CONSUMER_TYPE_ORIENTATION: 29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) orientation_buffer_ = NULL; 29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case CONSUMER_TYPE_MOTION: 29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) motion_buffer_ = NULL; 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) default: 29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool DataFetcherSharedMemory::RegisterForSensor( 30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) REFSENSOR_TYPE_ID sensor_type, 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ISensor** sensor, 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<SensorEventSink> event_sink) { 30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_WIN7) 30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::win::ScopedComPtr<ISensorManager> sensor_manager; 31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) HRESULT hr = sensor_manager.CreateInstance(CLSID_SensorManager); 31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FAILED(hr) || !sensor_manager) 31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::win::ScopedComPtr<ISensorCollection> sensor_collection; 31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hr = sensor_manager->GetSensorsByType( 31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sensor_type, sensor_collection.Receive()); 31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FAILED(hr) || !sensor_collection) 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ULONG count = 0; 32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hr = sensor_collection->GetCount(&count); 32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FAILED(hr) || !count) 32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hr = sensor_collection->GetAt(0, sensor); 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (FAILED(hr) || !(*sensor)) 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::win::ScopedComPtr<IPortableDeviceValues> device_values; 33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (SUCCEEDED(device_values.CreateInstance(CLSID_PortableDeviceValues))) { 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (SUCCEEDED(device_values->SetUnsignedIntegerValue( 3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, 3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetInterval().InMilliseconds()))) { 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::win::ScopedComPtr<IPortableDeviceValues> return_values; 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (*sensor)->SetProperties(device_values.get(), return_values.Receive()); 33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::win::ScopedComPtr<ISensorEvents> sensor_events; 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hr = event_sink->QueryInterface( 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) __uuidof(ISensorEvents), sensor_events.ReceiveVoid()); 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FAILED(hr) || !sensor_events) 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hr = (*sensor)->SetEventSink(sensor_events); 34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FAILED(hr)) 35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void DataFetcherSharedMemory::DisableSensors(ConsumerType consumer_type) { 356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch(consumer_type) { 357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONSUMER_TYPE_ORIENTATION: 358d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (sensor_inclinometer_) { 359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_inclinometer_->SetEventSink(NULL); 360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_inclinometer_.Release(); 361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONSUMER_TYPE_MOTION: 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (sensor_accelerometer_) { 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_accelerometer_->SetEventSink(NULL); 366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_accelerometer_.Release(); 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (sensor_gyrometer_) { 369d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_gyrometer_->SetEventSink(NULL); 370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sensor_gyrometer_.Release(); 371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) default: 374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NOTREACHED(); 375d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 378d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void DataFetcherSharedMemory::SetBufferAvailableState( 379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ConsumerType consumer_type, bool enabled) { 380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch(consumer_type) { 381d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONSUMER_TYPE_ORIENTATION: 382d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (orientation_buffer_) { 383d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) orientation_buffer_->seqlock.WriteBegin(); 384d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) orientation_buffer_->data.allAvailableSensorsAreActive = enabled; 385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) orientation_buffer_->seqlock.WriteEnd(); 386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONSUMER_TYPE_MOTION: 389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (motion_buffer_) { 390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) motion_buffer_->seqlock.WriteBegin(); 391d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) motion_buffer_->data.allAvailableSensorsAreActive = enabled; 392d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) motion_buffer_->seqlock.WriteEnd(); 393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) default: 396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NOTREACHED(); 397d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace content 401