Chromium Code Reviews| Index: content/browser/device_orientation/data_fetcher_impl_win.cc |
| diff --git a/content/browser/device_orientation/data_fetcher_impl_win.cc b/content/browser/device_orientation/data_fetcher_impl_win.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9b0a060677ab93938e0bf17a0faeec012b089ed5 |
| --- /dev/null |
| +++ b/content/browser/device_orientation/data_fetcher_impl_win.cc |
| @@ -0,0 +1,194 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/device_orientation/data_fetcher_impl_win.h" |
| + |
| +#include <InitGuid.h> |
| +#include <PortableDeviceTypes.h> |
| +#include <Sensors.h> |
| + |
| +#include "base/logging.h" |
| +#include "base/win/iunknown_impl.h" |
| +#include "base/win/windows_version.h" |
| +#include "content/browser/device_orientation/orientation.h" |
| + |
| +namespace { |
| + |
| +// This should match ProviderImpl::kDesiredSamplingIntervalMs. |
| +const int kPeriodInMilliseconds = 100; |
| + |
| +} // namespace |
| + |
| +namespace content { |
| + |
| +class DataFetcherImplWin::SensorEventSink : public ISensorEvents, |
| + public base::win::IUnknownImpl { |
| + public: |
| + explicit SensorEventSink(DataFetcherImplWin* const fetcher) |
| + : fetcher_(fetcher) {} |
| + |
| + virtual ~SensorEventSink() {} |
| + |
| + // IUnknown interface |
| + virtual ULONG STDMETHODCALLTYPE AddRef() OVERRIDE { |
| + return IUnknownImpl::AddRef(); |
| + } |
| + |
| + virtual ULONG STDMETHODCALLTYPE Release() OVERRIDE { |
| + return IUnknownImpl::Release(); |
| + } |
| + |
| + virtual STDMETHODIMP QueryInterface(REFIID riid, void** ppv) OVERRIDE { |
| + if (riid == __uuidof(ISensorEvents)) { |
| + *ppv = static_cast<ISensorEvents*>(this); |
| + AddRef(); |
| + return S_OK; |
| + } |
| + return IUnknownImpl::QueryInterface(riid, ppv); |
| + } |
| + |
| + // ISensorEvents interface |
| + STDMETHODIMP OnEvent(ISensor *sensor, |
|
bulach
2013/04/10 07:59:46
nit: here and 54, 58 and 59, the style is:
"type*
nhu
2013/04/10 09:46:42
Done.
|
| + REFGUID event_id, |
| + IPortableDeviceValues *event_data) OVERRIDE { |
| + return S_OK; |
| + } |
| + |
| + STDMETHODIMP OnDataUpdated(ISensor *sensor, |
| + ISensorDataReport *new_data) OVERRIDE { |
| + if (NULL == new_data || NULL == sensor) |
|
Peter Beverloo
2013/04/10 08:59:51
nit: two spaces after ||
nhu
2013/04/10 09:46:42
Done.
|
| + return E_INVALIDARG; |
| + |
| + PROPVARIANT value = {}; |
| + Orientation* orientation = new Orientation(); |
|
sail
2013/04/09 20:53:53
scoped_refptr
nhu
2013/04/10 09:46:42
Done.
|
| + |
| + if (SUCCEEDED(new_data->GetSensorValue( |
| + SENSOR_DATA_TYPE_TILT_X_DEGREES, &value))) { |
| + orientation->set_beta(value.fltVal); |
| + } |
| + PropVariantClear(&value); |
| + |
| + if (SUCCEEDED(new_data->GetSensorValue( |
| + SENSOR_DATA_TYPE_TILT_Y_DEGREES, &value))) { |
| + orientation->set_gamma(value.fltVal); |
| + } |
| + PropVariantClear(&value); |
| + |
| + if (SUCCEEDED(new_data->GetSensorValue( |
| + SENSOR_DATA_TYPE_TILT_Z_DEGREES, &value))) { |
| + orientation->set_alpha(value.fltVal); |
| + } |
| + PropVariantClear(&value); |
| + |
| + orientation->set_absolute(true); |
| + fetcher_->OnOrientationData(orientation); |
| + |
| + return S_OK; |
| + } |
| + |
| + STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) OVERRIDE { |
| + return S_OK; |
| + } |
| + |
| + STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) OVERRIDE { |
| + return S_OK; |
| + } |
| + |
| + private: |
| + DataFetcherImplWin* const fetcher_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SensorEventSink); |
| +}; |
| + |
| +// Create a DataFetcherImplWin object and return NULL if no valid sensor found. |
| +// static |
| +DataFetcher* DataFetcherImplWin::Create() { |
| + scoped_ptr<DataFetcherImplWin> fetcher(new DataFetcherImplWin); |
| + if (fetcher->Initialize()) |
| + return fetcher.release(); |
| + |
| + LOG(ERROR) << "DataFetcherImplWin::Initialize failed!"; |
| + return NULL; |
| +} |
| + |
| +DataFetcherImplWin::~DataFetcherImplWin() { |
| + if (sensor_.get()) |
|
sail
2013/04/09 20:53:53
I don't think you need the .get() here.
nhu
2013/04/10 09:46:42
Done.
|
| + sensor_->SetEventSink(NULL); |
| +} |
| + |
| +DataFetcherImplWin::DataFetcherImplWin() { |
| +} |
| + |
| +void DataFetcherImplWin::OnOrientationData(Orientation* orientation) { |
| + // This method is called on Windows sensor thread. |
| + base::AutoLock autolock(next_orientation_lock_); |
| + |
| + next_orientation_ = orientation; |
| +} |
| + |
| +const DeviceData* DataFetcherImplWin::GetDeviceData(DeviceData::Type type) { |
| + if (type != DeviceData::kTypeOrientation) |
| + return NULL; |
| + return GetOrientation(); |
| +} |
| + |
| +const Orientation* DataFetcherImplWin::GetOrientation() { |
| + if (next_orientation_.get()) { |
| + base::AutoLock autolock(next_orientation_lock_); |
| + next_orientation_.swap(current_orientation_); |
| + } |
| + if (!current_orientation_.get()) |
| + return new Orientation(); |
| + return current_orientation_.get(); |
| +} |
| + |
| +bool DataFetcherImplWin::Initialize() { |
| + if (base::win::GetVersion() < base::win::VERSION_WIN7) |
| + return false; |
| + |
| + base::win::ScopedComPtr<ISensorManager> sensor_manager; |
| + HRESULT hr = sensor_manager.CreateInstance(CLSID_SensorManager); |
| + if (FAILED(hr) || !sensor_manager) |
| + return false; |
| + |
| + base::win::ScopedComPtr<ISensorCollection> sensor_collection; |
| + hr = sensor_manager->GetSensorsByType( |
| + SENSOR_TYPE_INCLINOMETER_3D, sensor_collection.Receive()); |
|
Peter Beverloo
2013/04/10 08:59:51
nit: four space indent?
nhu
2013/04/10 09:46:42
Done.
|
| + |
| + if (FAILED(hr) || !sensor_collection) |
| + return false; |
| + |
| + ULONG count = 0; |
| + hr = sensor_collection->GetCount(&count); |
| + if (FAILED(hr) || !count) |
| + return false; |
| + |
| + hr = sensor_collection->GetAt(0, sensor_.Receive()); |
| + if (FAILED(hr) || !sensor_) |
| + return false; |
| + |
| + base::win::ScopedComPtr<IPortableDeviceValues> device_values; |
| + if (SUCCEEDED(device_values.CreateInstance(CLSID_PortableDeviceValues))) { |
| + if (SUCCEEDED(device_values->SetUnsignedIntegerValue( |
| + SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, kPeriodInMilliseconds))) { |
| + base::win::ScopedComPtr<IPortableDeviceValues> return_values; |
| + sensor_->SetProperties(device_values.get(), return_values.Receive()); |
| + } |
| + } |
| + |
| + scoped_refptr<SensorEventSink> sensor_event_impl = new SensorEventSink(this); |
|
sail
2013/04/09 20:53:53
use constructor instead of assign? (sensor_event_i
nhu
2013/04/10 09:46:42
Done.
|
| + base::win::ScopedComPtr<ISensorEvents> sensor_events; |
| + hr = sensor_event_impl->QueryInterface( |
| + __uuidof(ISensorEvents), sensor_events.ReceiveVoid()); |
|
bulach
2013/04/10 07:59:46
nit: too much indentation, should be +4 rather tha
nhu
2013/04/10 09:46:42
Done.
|
| + if (FAILED(hr) || !sensor_events) |
| + return false; |
| + |
| + hr = sensor_->SetEventSink(sensor_events); |
| + if (FAILED(hr)) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +} // namespace content |