OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 <SensorsApi.h> | |
6 #include <Sensors.h> // NOLINT | |
7 | |
8 #include "base/bind.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/run_loop.h" | |
11 #include "base/win/iunknown_impl.h" | |
12 | |
13 #include "device/generic_sensor/platform_sensor_provider_win.h" | |
14 #include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" | |
15 | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 using ::testing::_; | |
20 using ::testing::Invoke; | |
21 using ::testing::IsNull; | |
22 using ::testing::NiceMock; | |
23 using ::testing::NotNull; | |
24 using ::testing::Return; | |
25 | |
26 namespace device { | |
27 using mojom::SensorType; | |
28 | |
29 template <class Interface> | |
30 class MockCOMInterface : public Interface, public base::win::IUnknownImpl { | |
31 public: | |
32 // IUnknown interface | |
33 ULONG STDMETHODCALLTYPE AddRef() override { return IUnknownImpl::AddRef(); } | |
34 ULONG STDMETHODCALLTYPE Release() override { return IUnknownImpl::Release(); } | |
35 | |
36 STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override { | |
37 if (riid == __uuidof(Interface)) { | |
38 *ppv = static_cast<Interface*>(this); | |
39 AddRef(); | |
40 return S_OK; | |
41 } | |
42 return IUnknownImpl::QueryInterface(riid, ppv); | |
43 } | |
44 | |
45 protected: | |
46 ~MockCOMInterface() override = default; | |
47 }; | |
48 | |
49 // Mock class for ISensorManager COM interface. | |
50 class MockISensorManager : public MockCOMInterface<ISensorManager> { | |
51 public: | |
52 // ISensorManager interface | |
53 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
54 GetSensorsByCategory, | |
55 HRESULT(REFSENSOR_CATEGORY_ID category, | |
56 ISensorCollection** sensors_found)); | |
57 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
58 GetSensorsByType, | |
59 HRESULT(REFSENSOR_TYPE_ID sensor_id, | |
60 ISensorCollection** sensors_found)); | |
61 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
62 GetSensorByID, | |
63 HRESULT(REFSENSOR_ID sensor_id, ISensor** sensor)); | |
64 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
65 SetEventSink, | |
66 HRESULT(ISensorManagerEvents* event_sink)); | |
67 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
68 RequestPermissions, | |
69 HRESULT(HWND parent, | |
70 ISensorCollection* sensors, | |
71 BOOL is_modal)); | |
72 | |
73 protected: | |
74 ~MockISensorManager() override = default; | |
75 }; | |
76 | |
77 // Mock class for ISensorCollection COM interface. | |
78 class MockISensorCollection : public MockCOMInterface<ISensorCollection> { | |
79 public: | |
80 // ISensorCollection interface | |
81 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
82 GetAt, | |
83 HRESULT(ULONG index, ISensor** sensor)); | |
84 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
85 GetCount, | |
86 HRESULT(ULONG* count)); | |
87 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Add, HRESULT(ISensor* sensor)); | |
88 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
89 Remove, | |
90 HRESULT(ISensor* sensor)); | |
91 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
92 RemoveByID, | |
93 HRESULT(REFSENSOR_ID sensor_id)); | |
94 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Clear, HRESULT()); | |
95 | |
96 protected: | |
97 ~MockISensorCollection() override = default; | |
98 }; | |
99 | |
100 // Mock class for ISensor COM interface. | |
101 class MockISensor : public MockCOMInterface<ISensor> { | |
102 public: | |
103 // ISensor interface | |
104 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, GetID, HRESULT(SENSOR_ID* id)); | |
105 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
106 GetCategory, | |
107 HRESULT(SENSOR_CATEGORY_ID* category)); | |
108 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
109 GetType, | |
110 HRESULT(SENSOR_TYPE_ID* type)); | |
111 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
112 GetFriendlyName, | |
113 HRESULT(BSTR* name)); | |
114 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
115 GetProperty, | |
116 HRESULT(REFPROPERTYKEY key, | |
117 PROPVARIANT* property)); | |
118 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
119 GetProperties, | |
120 HRESULT(IPortableDeviceKeyCollection* keys, | |
121 IPortableDeviceValues** properties)); | |
122 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
123 GetSupportedDataFields, | |
124 HRESULT(IPortableDeviceKeyCollection** data)); | |
125 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
126 SetProperties, | |
127 HRESULT(IPortableDeviceValues* properties, | |
128 IPortableDeviceValues** results)); | |
129 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
130 SupportsDataField, | |
131 HRESULT(REFPROPERTYKEY key, | |
132 VARIANT_BOOL* is_supported)); | |
133 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
134 GetState, | |
135 HRESULT(SensorState* state)); | |
136 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
137 GetData, | |
138 HRESULT(ISensorDataReport** data_report)); | |
139 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
140 SupportsEvent, | |
141 HRESULT(REFGUID event_guid, | |
142 VARIANT_BOOL* is_supported)); | |
143 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
144 GetEventInterest, | |
145 HRESULT(GUID** values, ULONG* count)); | |
146 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
147 SetEventInterest, | |
148 HRESULT(GUID* values, ULONG count)); | |
149 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
150 SetEventSink, | |
151 HRESULT(ISensorEvents* pEvents)); | |
152 | |
153 protected: | |
154 ~MockISensor() override = default; | |
155 }; | |
156 | |
157 // Mock class for ISensorDataReport COM interface. | |
158 class MockISensorDataReport : public MockCOMInterface<ISensorDataReport> { | |
159 public: | |
160 // ISensorDataReport interface | |
161 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
162 GetTimestamp, | |
163 HRESULT(SYSTEMTIME* timestamp)); | |
164 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
165 GetSensorValue, | |
166 HRESULT(REFPROPERTYKEY key, PROPVARIANT* value)); | |
167 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, | |
168 GetSensorValues, | |
169 HRESULT(IPortableDeviceKeyCollection* keys, | |
170 IPortableDeviceValues** values)); | |
171 | |
172 protected: | |
173 ~MockISensorDataReport() override = default; | |
174 }; | |
175 | |
176 // Class that provides test harness support for generic sensor adaptation for | |
177 // Windows platform. Testing is mainly done by mocking main COM interfaces that | |
178 // are used to communicate with Sensors API. | |
179 // MockISensorManager - mocks ISensorManager and responsible for fetching | |
180 // list of supported sensors. | |
181 // MockISensorCollection - mocks collection of ISensor objects. | |
182 // MockISensor - mocks ISensor intrface. | |
183 // MockISensorDataReport - mocks IDataReport interface that is used to deliver | |
184 // data in OnDataUpdated event. | |
185 class PlatformSensorAndProviderTestWin : public ::testing::Test { | |
186 public: | |
187 void SetUp() override { | |
188 message_loop_.reset(new base::MessageLoopForIO); | |
189 m_sensor_ = new NiceMock<MockISensor>(); | |
190 m_sensor_collection_ = new NiceMock<MockISensorCollection>(); | |
191 m_sensor_manager_ = new NiceMock<MockISensorManager>(); | |
192 base::win::ScopedComPtr<ISensorManager> manager; | |
193 m_sensor_manager_->QueryInterface(__uuidof(ISensorManager), | |
194 manager.ReceiveVoid()); | |
195 | |
196 // Overrides default ISensorManager with mocked interface. | |
197 PlatformSensorProviderWin::GetInstance()->SetSensorManagerForTesing( | |
198 manager); | |
199 } | |
200 | |
201 void TearDown() override { | |
202 base::win::ScopedComPtr<ISensorManager> null_manager; | |
203 PlatformSensorProviderWin::GetInstance()->SetSensorManagerForTesing( | |
204 null_manager); | |
205 } | |
206 | |
207 protected: | |
208 void SensorCreated(scoped_refptr<PlatformSensor> sensor) { | |
209 m_platform_sensor_ = sensor; | |
210 run_loop_->Quit(); | |
211 } | |
212 | |
213 // Sensor creation is asynchronous, therefore inner loop is used to wait for | |
214 // PlatformSensorProvider::CreateSensorCallback completion. | |
215 scoped_refptr<PlatformSensor> CreateSensor(mojom::SensorType type) { | |
216 run_loop_ = std::make_unique<base::RunLoop>(); | |
217 PlatformSensorProviderWin::GetInstance()->CreateSensor( | |
218 type, base::Bind(&PlatformSensorAndProviderTestWin::SensorCreated, | |
219 base::Unretained(this))); | |
220 run_loop_->Run(); | |
221 scoped_refptr<PlatformSensor> sensor; | |
222 sensor.swap(m_platform_sensor_); | |
223 run_loop_ = nullptr; | |
224 return sensor; | |
225 } | |
226 | |
227 // Sets sensor with REFSENSOR_TYPE_ID |sensor| to be supported by mocked | |
228 // ISensorMager and it will be present in ISensorCollection. | |
229 void SetSupportedSensor(REFSENSOR_TYPE_ID sensor) { | |
230 EXPECT_CALL(*m_sensor_manager_, GetSensorsByType(sensor, _)).Times(1); | |
231 EXPECT_CALL(*m_sensor_collection_, GetCount(_)).Times(1); | |
232 EXPECT_CALL(*m_sensor_collection_, GetAt(0, _)).Times(1); | |
233 | |
234 // Returns mock ISensorCollection. | |
235 ON_CALL(*m_sensor_manager_, GetSensorsByType(sensor, _)) | |
236 .WillByDefault(Invoke( | |
237 [this](REFSENSOR_TYPE_ID type, ISensorCollection** collection) { | |
238 m_sensor_collection_->QueryInterface( | |
239 __uuidof(ISensorCollection), | |
240 reinterpret_cast<void**>(collection)); | |
241 return S_OK; | |
242 })); | |
243 | |
244 // Returns number of ISensor objects in ISensorCollection, at the moment | |
245 // only one ISensor interface instance is suported. | |
246 ON_CALL(*m_sensor_collection_, GetCount(_)) | |
247 .WillByDefault(Invoke([](ULONG* count) { | |
248 *count = 1; | |
249 return S_OK; | |
250 })); | |
251 | |
252 // Returns ISensor interface instance at index 0. | |
253 ON_CALL(*m_sensor_collection_, GetAt(0, _)) | |
254 .WillByDefault(Invoke([this](ULONG index, ISensor** sensor) { | |
255 m_sensor_->QueryInterface(__uuidof(ISensor), | |
256 reinterpret_cast<void**>(sensor)); | |
257 return S_OK; | |
258 })); | |
259 | |
260 // Handles |SetEventSink| call that is used to subscribe to sensor events | |
261 // through ISensorEvents interface. ISensorEvents is stored and attached to | |
262 // |sensor_events_| that is used later to generate fake error, state and | |
263 // data change events. | |
264 ON_CALL(*m_sensor_, SetEventSink(NotNull())) | |
265 .WillByDefault(Invoke([this](ISensorEvents* events) { | |
266 events->AddRef(); | |
267 sensor_events_.Attach(events); | |
268 return S_OK; | |
269 })); | |
270 | |
271 // When |SetEventSink| is called with nullptr, it means that client is no | |
272 // longer interested in sensor events and ISensorEvents can be released. | |
273 ON_CALL(*m_sensor_, SetEventSink(IsNull())) | |
274 .WillByDefault(Invoke([this](ISensorEvents* events) { | |
275 sensor_events_.Release(); | |
276 return S_OK; | |
277 })); | |
278 } | |
279 | |
280 // Sets minimal reporting frequency for the mock sensor. | |
281 void SetSupportedReportingFrequency(double frequency) { | |
282 ON_CALL(*m_sensor_, GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL, _)) | |
283 .WillByDefault( | |
284 Invoke([frequency](REFPROPERTYKEY key, PROPVARIANT* pProperty) { | |
285 pProperty->vt = VT_UI4; | |
286 pProperty->ulVal = | |
287 (1 / frequency) * base::Time::kMillisecondsPerSecond; | |
288 return S_OK; | |
289 })); | |
290 } | |
291 | |
292 // Generates OnLeave event, e.g. when sensor is disconnected. | |
293 void GenerateLeaveEvent() { | |
294 if (!sensor_events_) | |
295 return; | |
296 sensor_events_->OnLeave(SENSOR_ID()); | |
297 } | |
298 | |
299 // Generates OnStateChangedLeave event. | |
300 void GenerateStateChangeEvent(SensorState state) { | |
301 if (!sensor_events_) | |
302 return; | |
303 sensor_events_->OnStateChanged(m_sensor_.get(), state); | |
304 } | |
305 | |
306 // Generates OnDataUpdated event and creates ISensorDataReport with fake | |
307 // |value| for property with |key|. | |
308 void GenerateDataUpdatedEvent(REFPROPERTYKEY key, double value) { | |
309 if (!sensor_events_) | |
310 return; | |
311 | |
312 auto mock_report = new NiceMock<MockISensorDataReport>(); | |
313 | |
314 EXPECT_CALL(*mock_report, GetTimestamp(_)).Times(1); | |
315 EXPECT_CALL(*mock_report, GetSensorValue(_, _)).Times(1); | |
316 | |
317 ON_CALL(*mock_report, GetTimestamp(_)) | |
318 .WillByDefault(Invoke([](SYSTEMTIME* timestamp) { | |
319 GetSystemTime(timestamp); | |
320 return S_OK; | |
321 })); | |
322 | |
323 ON_CALL(*mock_report, GetSensorValue(key, _)) | |
324 .WillByDefault(Invoke([value](REFPROPERTYKEY, PROPVARIANT* variant) { | |
325 variant->vt = VT_R8; | |
326 variant->dblVal = value; | |
327 return S_OK; | |
328 })); | |
329 | |
330 base::win::ScopedComPtr<ISensorDataReport> data_report; | |
331 mock_report->QueryInterface(__uuidof(ISensorDataReport), | |
332 data_report.ReceiveVoid()); | |
333 | |
334 sensor_events_->OnDataUpdated(m_sensor_.get(), data_report.get()); | |
335 } | |
336 | |
337 scoped_refptr<MockISensorManager> m_sensor_manager_; | |
338 scoped_refptr<MockISensorCollection> m_sensor_collection_; | |
339 scoped_refptr<MockISensor> m_sensor_; | |
340 base::win::ScopedComPtr<ISensorEvents> sensor_events_; | |
341 std::unique_ptr<base::MessageLoop> message_loop_; | |
342 scoped_refptr<PlatformSensor> m_platform_sensor_; | |
343 // Inner run loop used to wait for async sensor creation callback. | |
344 std::unique_ptr<base::RunLoop> run_loop_; | |
345 }; | |
346 | |
347 // Mock for PlatformSensor's client interface that is used to deliver | |
348 // error and data changes notifications. | |
349 class MockPlatformSensorClient : public PlatformSensor::Client { | |
350 public: | |
351 MockPlatformSensorClient() = default; | |
352 explicit MockPlatformSensorClient(scoped_refptr<PlatformSensor> sensor) | |
353 : sensor_(sensor) { | |
354 if (sensor_) | |
355 sensor_->AddClient(this); | |
356 | |
357 ON_CALL(*this, IsNotificationSuspended()).WillByDefault(Return(false)); | |
358 } | |
359 | |
360 ~MockPlatformSensorClient() override { | |
361 if (sensor_) | |
362 sensor_->RemoveClient(this); | |
363 } | |
364 | |
365 // PlatformSensor::Client interface. | |
366 MOCK_METHOD0(OnSensorReadingChanged, void()); | |
367 MOCK_METHOD0(OnSensorError, void()); | |
368 MOCK_METHOD0(IsNotificationSuspended, bool()); | |
369 | |
370 private: | |
371 scoped_refptr<PlatformSensor> sensor_; | |
372 }; | |
373 | |
374 // Tests that PlatformSensorManager returns null sensor when sensor | |
375 // is not implemented. | |
376 TEST_F(PlatformSensorAndProviderTestWin, SensorIsNotImplemented) { | |
377 EXPECT_CALL(*m_sensor_manager_, | |
378 GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D, _)) | |
379 .Times(0); | |
380 EXPECT_FALSE(CreateSensor(SensorType::ACCELEROMETER)); | |
381 } | |
382 | |
383 // Tests that PlatformSensorManager returns null sensor when sensor | |
384 // is implemented, but not supported by the hardware. | |
385 TEST_F(PlatformSensorAndProviderTestWin, SensorIsNotSupported) { | |
386 EXPECT_CALL(*m_sensor_manager_, | |
387 GetSensorsByType(SENSOR_TYPE_AMBIENT_LIGHT, _)) | |
388 .Times(1); | |
389 ON_CALL(*m_sensor_manager_, GetSensorsByType(SENSOR_TYPE_AMBIENT_LIGHT, _)) | |
390 .WillByDefault(Invoke([](REFSENSOR_TYPE_ID, ISensorCollection** result) { | |
Reilly Grant (use Gerrit)
2016/10/27 00:59:19
Here and also elsewhere such as above in SetSuppor
shalamov
2016/10/27 13:51:07
Done.
| |
391 *result = nullptr; | |
392 return E_FAIL; | |
393 })); | |
394 EXPECT_FALSE(CreateSensor(SensorType::AMBIENT_LIGHT)); | |
395 } | |
396 | |
397 // Tests that PlatformSensorManager returns correct sensor when sensor | |
398 // is supported by the hardware. | |
399 TEST_F(PlatformSensorAndProviderTestWin, SensorIsSupported) { | |
400 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
401 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
402 EXPECT_TRUE(sensor); | |
403 EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor->GetType()); | |
404 } | |
405 | |
406 // Tests that PlatformSensor::StartListening fails when provided reporting | |
407 // frequency is above hardware capabilities. | |
408 TEST_F(PlatformSensorAndProviderTestWin, StartFails) { | |
409 SetSupportedReportingFrequency(1); | |
410 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
411 | |
412 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
413 EXPECT_TRUE(sensor); | |
414 | |
415 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
416 PlatformSensorConfiguration configuration(10); | |
417 EXPECT_FALSE(sensor->StartListening(client.get(), configuration)); | |
418 } | |
419 | |
420 // Tests that PlatformSensor::StartListening succeeds and notification about | |
421 // modified sensor reading is sent to the PlatformSensor::Client interface. | |
422 TEST_F(PlatformSensorAndProviderTestWin, SensorStarted) { | |
423 SetSupportedReportingFrequency(10); | |
424 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
425 | |
426 EXPECT_CALL(*m_sensor_, SetEventSink(NotNull())).Times(1); | |
427 EXPECT_CALL(*m_sensor_, SetEventSink(IsNull())).Times(1); | |
428 EXPECT_CALL(*m_sensor_, SetProperties(NotNull(), _)).Times(1); | |
429 | |
430 ON_CALL(*m_sensor_, SetProperties(_, _)) | |
431 .WillByDefault(Invoke( | |
432 [](IPortableDeviceValues* props, IPortableDeviceValues** result) { | |
433 ULONG value = 0; | |
434 HRESULT hr = props->GetUnsignedIntegerValue( | |
435 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, &value); | |
436 EXPECT_THAT(SUCCEEDED(hr), true); | |
Reilly Grant (use Gerrit)
2016/10/27 00:59:19
Comparisons to true can be fishy. Use EXPECT_TRUE(
shalamov
2016/10/27 13:51:07
Done.
| |
437 // 10Hz is 100msec | |
438 EXPECT_THAT(value, 100); | |
439 return hr; | |
440 })); | |
441 | |
442 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
443 EXPECT_TRUE(sensor); | |
444 | |
445 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
446 PlatformSensorConfiguration configuration(10); | |
447 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
448 | |
449 EXPECT_CALL(*client, OnSensorReadingChanged()).Times(1); | |
450 GenerateDataUpdatedEvent(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, 3.14); | |
451 base::RunLoop().RunUntilIdle(); | |
452 EXPECT_TRUE(sensor->StopListening(client.get(), configuration)); | |
453 } | |
454 | |
455 // Tests that OnSensorError is called when sensor is disconnected. | |
456 TEST_F(PlatformSensorAndProviderTestWin, SensorRemoved) { | |
457 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
458 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
459 EXPECT_TRUE(sensor); | |
460 | |
461 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
462 PlatformSensorConfiguration configuration(10); | |
463 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
464 EXPECT_CALL(*client, OnSensorError()).Times(1); | |
465 | |
466 GenerateLeaveEvent(); | |
467 base::RunLoop().RunUntilIdle(); | |
468 } | |
469 | |
470 // Tests that OnSensorError is called when sensor is in an error state. | |
471 TEST_F(PlatformSensorAndProviderTestWin, SensorStateChangedToError) { | |
472 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
473 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
474 EXPECT_TRUE(sensor); | |
475 | |
476 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
477 PlatformSensorConfiguration configuration(10); | |
478 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
479 EXPECT_CALL(*client, OnSensorError()).Times(1); | |
480 | |
481 GenerateStateChangeEvent(SENSOR_STATE_ERROR); | |
482 base::RunLoop().RunUntilIdle(); | |
483 } | |
484 | |
485 } // namespace device | |
OLD | NEW |