OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/device_orientation/data_fetcher_impl_win.h" | |
6 | |
7 #include <InitGuid.h> | |
8 #include <PortableDeviceTypes.h> | |
9 #include <Sensors.h> | |
10 | |
11 #include "base/logging.h" | |
12 #include "content/browser/device_orientation/orientation.h" | |
13 | |
14 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.
| |
15 | |
16 namespace { | |
17 | |
18 // This should match ProviderImpl::kDesiredSamplingIntervalMs. | |
19 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
| |
20 | |
21 } // namespace | |
22 | |
23 namespace content { | |
24 | |
25 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.
| |
26 public: | |
27 explicit SensorEventSink(DataFetcherImplWin* const fetcher) | |
28 : fetcher_(fetcher), | |
29 ref_count_(0) {} | |
30 | |
31 virtual ~SensorEventSink() {} | |
32 | |
33 // IUnknown interface | |
34 STDMETHODIMP_(ULONG) AddRef() { | |
sail
2013/04/09 14:43:58
virtual STDMETHODIMP AddRef() OVERRIDE
Same below
nhu
2013/04/09 18:13:16
Done.
| |
35 return InterlockedIncrement(&ref_count_); | |
36 } | |
37 | |
38 STDMETHODIMP_(ULONG) Release() { | |
39 ULONG count = InterlockedDecrement(&ref_count_); | |
40 if (count == 0) { | |
41 delete this; | |
42 return 0; | |
43 } | |
44 return count; | |
45 } | |
46 | |
47 STDMETHODIMP QueryInterface(REFIID requested_interface_id, | |
48 void** return_value) { | |
49 if (return_value == NULL) | |
50 return E_POINTER; | |
51 if (requested_interface_id == __uuidof(IUnknown)) { | |
52 *return_value = static_cast<IUnknown*>(this); | |
53 } 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.
| |
54 *return_value = static_cast<ISensorEvents*>(this); | |
55 } else { | |
56 *return_value = NULL; | |
57 return E_NOINTERFACE; | |
58 } | |
59 AddRef(); | |
60 return S_OK; | |
61 } | |
62 | |
63 // ISensorEvents interface | |
64 STDMETHODIMP OnEvent(ISensor *sensor, | |
65 REFGUID event_id, | |
66 IPortableDeviceValues *event_data) { | |
67 return S_OK; | |
68 } | |
69 | |
70 STDMETHODIMP OnDataUpdated(ISensor *sensor, ISensorDataReport *new_data) { | |
71 if (NULL == new_data || NULL == sensor) | |
72 return E_INVALIDARG; | |
73 | |
74 PROPVARIANT value = {}; | |
75 bool can_provide_alpha = false; | |
76 bool can_provide_beta = false; | |
77 bool can_provide_gamma = false; | |
78 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.
| |
79 if (SUCCEEDED(new_data->GetSensorValue( | |
80 SENSOR_DATA_TYPE_TILT_X_DEGREES, &value))) { | |
81 beta = value.fltVal; | |
82 can_provide_beta = true; | |
83 } | |
84 PropVariantClear(&value); | |
85 if (SUCCEEDED(new_data->GetSensorValue( | |
86 SENSOR_DATA_TYPE_TILT_Y_DEGREES, &value))) { | |
87 gamma = value.fltVal; | |
88 can_provide_gamma = true; | |
89 } | |
90 PropVariantClear(&value); | |
91 if (SUCCEEDED(new_data->GetSensorValue( | |
92 SENSOR_DATA_TYPE_TILT_Z_DEGREES, &value))) { | |
93 alpha = value.fltVal; | |
94 can_provide_alpha = true; | |
95 } | |
Peter Beverloo
2013/04/09 15:34:15
nit: indentation.
nhu
2013/04/09 18:13:16
Done.
| |
96 PropVariantClear(&value); | |
97 | |
98 fetcher_->OnOrientationData(can_provide_alpha, alpha, | |
99 can_provide_beta, beta, | |
100 can_provide_gamma, gamma); | |
101 | |
102 return S_OK; | |
103 } | |
104 | |
105 STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) { | |
106 return S_OK; | |
107 } | |
108 | |
109 STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) { | |
110 return S_OK; | |
111 } | |
112 | |
113 private: | |
114 long ref_count_ ; | |
115 DataFetcherImplWin* const fetcher_; | |
sail
2013/04/09 14:43:58
DISALLOW_COPY_... here
nhu
2013/04/09 18:13:16
Done.
| |
116 }; | |
117 | |
118 // Create a DataFetcherImplWin object and return NULL if no valid sensor found. | |
119 DataFetcher* DataFetcherImplWin::Create() { | |
sail
2013/04/09 14:43:58
"// static" above this line
nhu
2013/04/09 18:13:16
Done.
| |
120 scoped_ptr<DataFetcherImplWin> fetcher(new DataFetcherImplWin); | |
121 return fetcher->Init() ? fetcher.release() : NULL; | |
122 } | |
123 | |
124 DataFetcherImplWin::~DataFetcherImplWin() { | |
125 if (sensor_.get()) | |
126 sensor_->SetEventSink(NULL); | |
127 } | |
128 | |
129 DataFetcherImplWin::DataFetcherImplWin() { | |
130 } | |
131 | |
132 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.
| |
133 double alpha, | |
134 bool can_provide_beta, | |
135 double beta, | |
136 bool can_provide_gamma, | |
137 double gamma) { | |
138 base::AutoLock autolock(last_orientation_lock_); | |
139 Orientation* orientation = new Orientation(); | |
140 if (can_provide_alpha) | |
141 orientation->set_alpha(alpha); | |
142 if (can_provide_beta) | |
143 orientation->set_beta(beta); | |
144 if (can_provide_gamma) | |
145 orientation->set_gamma(gamma); | |
146 last_orientation_ = orientation; | |
147 } | |
148 | |
149 const DeviceData* DataFetcherImplWin::GetDeviceData(DeviceData::Type type) { | |
150 if (type != DeviceData::kTypeOrientation) | |
151 return NULL; | |
152 return GetOrientation(); | |
153 } | |
154 | |
155 const Orientation* DataFetcherImplWin::GetOrientation() { | |
156 base::AutoLock autolock(last_orientation_lock_); | |
157 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.
| |
158 if (last_orientation_.get()) { | |
159 if (last_orientation_->can_provide_alpha()) | |
160 orientation->set_alpha(last_orientation_->alpha()); | |
161 if (last_orientation_->can_provide_beta()) | |
162 orientation->set_beta(last_orientation_->beta()); | |
163 if (last_orientation_->can_provide_gamma()) | |
164 orientation->set_gamma(last_orientation_->gamma()); | |
165 orientation->set_absolute(true); | |
166 } | |
167 return orientation; | |
168 } | |
169 | |
170 bool DataFetcherImplWin::Init() { | |
sail
2013/04/09 14:43:58
No abbreviations
nhu
2013/04/09 18:13:16
Done.
| |
171 ScopedComPtr<ISensorManager> sensor_manager; | |
172 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.
| |
173 NULL, | |
174 CLSCTX_INPROC_SERVER, | |
175 __uuidof(ISensorManager), | |
176 sensor_manager.ReceiveVoid()))) | |
177 return false; | |
178 | |
179 ScopedComPtr<ISensorCollection> sensor_collection; | |
180 if (FAILED(sensor_manager->GetSensorsByType( | |
181 SENSOR_TYPE_INCLINOMETER_3D, sensor_collection.Receive()))) | |
182 return false; | |
183 | |
184 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
| |
185 return false; | |
186 | |
187 ScopedComPtr<IPortableDeviceValues> device_values; | |
188 if (SUCCEEDED(CoCreateInstance(CLSID_PortableDeviceValues, | |
189 NULL, | |
190 CLSCTX_INPROC_SERVER, | |
191 __uuidof(IPortableDeviceValues), | |
192 device_values.ReceiveVoid()))) { | |
193 if (SUCCEEDED(device_values->SetUnsignedIntegerValue( | |
194 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, kPeriodInMilliseconds))) { | |
195 ScopedComPtr<IPortableDeviceValues> return_values; | |
196 sensor_->SetProperties(device_values.get(), return_values.Receive()); | |
197 } | |
198 } | |
199 | |
200 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
| |
201 ScopedComPtr<ISensorEvents> sensor_events; | |
202 if (FAILED(sensor_event_class->QueryInterface( | |
203 __uuidof(ISensorEvents), sensor_events.ReceiveVoid()))) | |
204 return false; | |
205 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.
| |
206 return false; | |
207 | |
208 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.
| |
209 } | |
210 | |
211 } // namespace content | |
OLD | NEW |