| 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..d08ed446ad623f4c8e577cc7fd97fdf01f14f559
|
| --- /dev/null
|
| +++ b/content/browser/device_orientation/data_fetcher_impl_win.cc
|
| @@ -0,0 +1,193 @@
|
| +// 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,
|
| + REFGUID event_id,
|
| + IPortableDeviceValues* event_data) OVERRIDE {
|
| + return S_OK;
|
| + }
|
| +
|
| + STDMETHODIMP OnDataUpdated(ISensor* sensor,
|
| + ISensorDataReport* new_data) OVERRIDE {
|
| + if (NULL == new_data || NULL == sensor)
|
| + return E_INVALIDARG;
|
| +
|
| + PROPVARIANT value = {};
|
| + scoped_refptr<Orientation> orientation = new Orientation();
|
| +
|
| + 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.get());
|
| +
|
| + 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_)
|
| + 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());
|
| +
|
| + 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));
|
| + base::win::ScopedComPtr<ISensorEvents> sensor_events;
|
| + hr = sensor_event_impl->QueryInterface(
|
| + __uuidof(ISensorEvents), sensor_events.ReceiveVoid());
|
| + if (FAILED(hr) || !sensor_events)
|
| + return false;
|
| +
|
| + hr = sensor_->SetEventSink(sensor_events);
|
| + if (FAILED(hr))
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace content
|
|
|