Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: content/browser/device_orientation/data_fetcher_impl_win.cc

Issue 13433002: Implement DeviceOrientation API on Windows (Closed) Base URL: ssh://nhu@powerbuilder.sh.intel.com/home/www-data/git-repos/perc/chromium.git@sensor
Patch Set: Fixup according to bulach's comments (#3) Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..b34bebd8d57c39dbebf1f98f9be2dc20375fef65
--- /dev/null
+++ b/content/browser/device_orientation/data_fetcher_impl_win.cc
@@ -0,0 +1,211 @@
+// 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 "content/browser/device_orientation/orientation.h"
+
+using base::win::ScopedComPtr;
sail 2013/04/09 14:43:58 I think you should avoid this.
nhu 2013/04/09 18:13:16 Done.
+
+namespace {
+
+// This should match ProviderImpl::kDesiredSamplingIntervalMs.
+const int kPeriodInMilliseconds = 100;
Peter Beverloo 2013/04/09 15:34:15 We're trying to move to updating Device Orientatio
nhu 2013/04/09 18:13:16 I have no device at hand now. I could do some test
nhu 2013/04/10 16:51:01 I did a brief performance evaluation today. The da
Peter Beverloo 2013/04/12 15:52:10 That's very, very useful, thank you! Tim Volodine
+
+} // namespace
+
+namespace content {
+
+class DataFetcherImplWin::SensorEventSink : public ISensorEvents {
sail 2013/04/09 14:43:58 inherit from base::win::IUnknownImpl
nhu 2013/04/09 18:13:16 Done.
+ public:
+ explicit SensorEventSink(DataFetcherImplWin* const fetcher)
+ : fetcher_(fetcher),
+ ref_count_(0) {}
+
+ virtual ~SensorEventSink() {}
+
+ // IUnknown interface
+ STDMETHODIMP_(ULONG) AddRef() {
sail 2013/04/09 14:43:58 virtual STDMETHODIMP AddRef() OVERRIDE Same below
nhu 2013/04/09 18:13:16 Done.
+ return InterlockedIncrement(&ref_count_);
+ }
+
+ STDMETHODIMP_(ULONG) Release() {
+ ULONG count = InterlockedDecrement(&ref_count_);
+ if (count == 0) {
+ delete this;
+ return 0;
+ }
+ return count;
+ }
+
+ STDMETHODIMP QueryInterface(REFIID requested_interface_id,
+ void** return_value) {
+ if (return_value == NULL)
+ return E_POINTER;
+ if (requested_interface_id == __uuidof(IUnknown)) {
+ *return_value = static_cast<IUnknown*>(this);
+ } else if (requested_interface_id == __uuidof(ISensorEvents)) {
sail 2013/04/09 14:43:58 only handle this and call super class for others
nhu 2013/04/09 18:13:16 Done.
+ *return_value = static_cast<ISensorEvents*>(this);
+ } else {
+ *return_value = NULL;
+ return E_NOINTERFACE;
+ }
+ AddRef();
+ return S_OK;
+ }
+
+ // ISensorEvents interface
+ STDMETHODIMP OnEvent(ISensor *sensor,
+ REFGUID event_id,
+ IPortableDeviceValues *event_data) {
+ return S_OK;
+ }
+
+ STDMETHODIMP OnDataUpdated(ISensor *sensor, ISensorDataReport *new_data) {
+ if (NULL == new_data || NULL == sensor)
+ return E_INVALIDARG;
+
+ PROPVARIANT value = {};
+ bool can_provide_alpha = false;
+ bool can_provide_beta = false;
+ bool can_provide_gamma = false;
+ double alpha, beta, gamma;
sail 2013/04/09 14:59:14 One line per variable declaration. Actually it wou
nhu 2013/04/09 18:13:16 It's a good suggestion. Done.
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_X_DEGREES, &value))) {
+ beta = value.fltVal;
+ can_provide_beta = true;
+ }
+ PropVariantClear(&value);
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_Y_DEGREES, &value))) {
+ gamma = value.fltVal;
+ can_provide_gamma = true;
+ }
+ PropVariantClear(&value);
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_Z_DEGREES, &value))) {
+ alpha = value.fltVal;
+ can_provide_alpha = true;
+ }
Peter Beverloo 2013/04/09 15:34:15 nit: indentation.
nhu 2013/04/09 18:13:16 Done.
+ PropVariantClear(&value);
+
+ fetcher_->OnOrientationData(can_provide_alpha, alpha,
+ can_provide_beta, beta,
+ can_provide_gamma, gamma);
+
+ return S_OK;
+ }
+
+ STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) {
+ return S_OK;
+ }
+
+ STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) {
+ return S_OK;
+ }
+
+ private:
+ long ref_count_ ;
+ DataFetcherImplWin* const fetcher_;
sail 2013/04/09 14:43:58 DISALLOW_COPY_... here
nhu 2013/04/09 18:13:16 Done.
+};
+
+// Create a DataFetcherImplWin object and return NULL if no valid sensor found.
+DataFetcher* DataFetcherImplWin::Create() {
sail 2013/04/09 14:43:58 "// static" above this line
nhu 2013/04/09 18:13:16 Done.
+ scoped_ptr<DataFetcherImplWin> fetcher(new DataFetcherImplWin);
+ return fetcher->Init() ? fetcher.release() : NULL;
+}
+
+DataFetcherImplWin::~DataFetcherImplWin() {
+ if (sensor_.get())
+ sensor_->SetEventSink(NULL);
+}
+
+DataFetcherImplWin::DataFetcherImplWin() {
+}
+
+void DataFetcherImplWin::OnOrientationData(bool can_provide_alpha,
sail 2013/04/09 14:59:14 Comment about what thread this may be called on.
nhu 2013/04/09 18:13:16 Done.
+ double alpha,
+ bool can_provide_beta,
+ double beta,
+ bool can_provide_gamma,
+ double gamma) {
+ base::AutoLock autolock(last_orientation_lock_);
+ Orientation* orientation = new Orientation();
+ if (can_provide_alpha)
+ orientation->set_alpha(alpha);
+ if (can_provide_beta)
+ orientation->set_beta(beta);
+ if (can_provide_gamma)
+ orientation->set_gamma(gamma);
+ last_orientation_ = orientation;
+}
+
+const DeviceData* DataFetcherImplWin::GetDeviceData(DeviceData::Type type) {
+ if (type != DeviceData::kTypeOrientation)
+ return NULL;
+ return GetOrientation();
+}
+
+const Orientation* DataFetcherImplWin::GetOrientation() {
+ base::AutoLock autolock(last_orientation_lock_);
+ Orientation* orientation = new Orientation();
sail 2013/04/09 14:59:14 Instead of instantiating a new object every 100ms
nhu 2013/04/09 18:13:16 I've adopt the Android's implementation.
+ if (last_orientation_.get()) {
+ if (last_orientation_->can_provide_alpha())
+ orientation->set_alpha(last_orientation_->alpha());
+ if (last_orientation_->can_provide_beta())
+ orientation->set_beta(last_orientation_->beta());
+ if (last_orientation_->can_provide_gamma())
+ orientation->set_gamma(last_orientation_->gamma());
+ orientation->set_absolute(true);
+ }
+ return orientation;
+}
+
+bool DataFetcherImplWin::Init() {
sail 2013/04/09 14:43:58 No abbreviations
nhu 2013/04/09 18:13:16 Done.
+ ScopedComPtr<ISensorManager> sensor_manager;
+ if (FAILED(::CoCreateInstance(CLSID_SensorManager,
sail 2013/04/09 14:43:58 I think this requires Windows7 and above. Can you
sail 2013/04/09 14:43:58 Use sensor_manager.CreateInstance() Same below.
sail 2013/04/09 14:59:56 Ohh. Does using portabledeviceguids make this work
nhu 2013/04/09 18:13:16 Done.
nhu 2013/04/09 18:13:16 The Minimum supported version of sensor framework
nhu 2013/04/09 18:13:16 Done.
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(ISensorManager),
+ sensor_manager.ReceiveVoid())))
+ return false;
+
+ ScopedComPtr<ISensorCollection> sensor_collection;
+ if (FAILED(sensor_manager->GetSensorsByType(
+ SENSOR_TYPE_INCLINOMETER_3D, sensor_collection.Receive())))
+ return false;
+
+ if (FAILED(sensor_collection->GetAt(0, sensor_.Receive())))
sail 2013/04/09 14:43:58 Is it ok to do this without checking the count fir
nhu 2013/04/09 18:13:16 I agree that it's better to add the count checking
+ return false;
+
+ ScopedComPtr<IPortableDeviceValues> device_values;
+ if (SUCCEEDED(CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(IPortableDeviceValues),
+ device_values.ReceiveVoid()))) {
+ if (SUCCEEDED(device_values->SetUnsignedIntegerValue(
+ SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, kPeriodInMilliseconds))) {
+ ScopedComPtr<IPortableDeviceValues> return_values;
+ sensor_->SetProperties(device_values.get(), return_values.Receive());
+ }
+ }
+
+ SensorEventSink* sensor_event_class = new SensorEventSink(this);
sail 2013/04/09 14:43:58 scoped_refptr<SensorEventSink> sensor_event_class
nhu 2013/04/09 18:13:16 I am not sure that if scoped_refptr could use with
+ ScopedComPtr<ISensorEvents> sensor_events;
+ if (FAILED(sensor_event_class->QueryInterface(
+ __uuidof(ISensorEvents), sensor_events.ReceiveVoid())))
+ return false;
+ if (FAILED(sensor_->SetEventSink(sensor_events.get())))
sail 2013/04/09 14:43:58 don't need the .get() ?
Peter Beverloo 2013/04/09 15:34:15 nit: maybe a newline for readability?
nhu 2013/04/09 18:13:16 Done.
nhu 2013/04/09 18:13:16 Done.
+ return false;
+
+ return sensor_.get() != NULL;
Peter Beverloo 2013/04/09 15:34:15 sensor_ should be set on line 184 and is being use
nhu 2013/04/09 18:13:16 You are right. Done.
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698