Chromium Code Reviews| 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 | |
|
Lei Zhang
2016/10/29 05:10:41
nit: no blank lines between all the non-system inc
shalamov
2016/10/31 13:12:57
Done.
| |
| 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 sensor_ = new NiceMock<MockISensor>(); | |
| 190 sensor_collection_ = new NiceMock<MockISensorCollection>(); | |
| 191 sensor_manager_ = new NiceMock<MockISensorManager>(); | |
| 192 base::win::ScopedComPtr<ISensorManager> manager; | |
| 193 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 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>(); | |
|
Lei Zhang
2016/10/29 05:10:41
Use nullptr like line 223?
shalamov
2016/10/31 13:12:57
It is inner loop that is used at line 220. I canno
| |
| 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(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 // Returns mock ISensorCollection. | |
| 231 EXPECT_CALL(*sensor_manager_, GetSensorsByType(sensor, _)) | |
| 232 .WillOnce(Invoke( | |
| 233 [this](REFSENSOR_TYPE_ID type, ISensorCollection** collection) { | |
| 234 sensor_collection_->QueryInterface( | |
| 235 __uuidof(ISensorCollection), | |
| 236 reinterpret_cast<void**>(collection)); | |
| 237 return S_OK; | |
| 238 })); | |
| 239 | |
| 240 // Returns number of ISensor objects in ISensorCollection, at the moment | |
| 241 // only one ISensor interface instance is suported. | |
| 242 EXPECT_CALL(*sensor_collection_, GetCount(_)) | |
| 243 .WillOnce(Invoke([](ULONG* count) { | |
| 244 *count = 1; | |
| 245 return S_OK; | |
| 246 })); | |
| 247 | |
| 248 // Returns ISensor interface instance at index 0. | |
| 249 EXPECT_CALL(*sensor_collection_, GetAt(0, _)) | |
| 250 .WillOnce(Invoke([this](ULONG index, ISensor** sensor) { | |
| 251 sensor_->QueryInterface(__uuidof(ISensor), | |
| 252 reinterpret_cast<void**>(sensor)); | |
| 253 return S_OK; | |
| 254 })); | |
| 255 | |
| 256 // Handles |SetEventSink| call that is used to subscribe to sensor events | |
| 257 // through ISensorEvents interface. ISensorEvents is stored and attached to | |
| 258 // |sensor_events_| that is used later to generate fake error, state and | |
| 259 // data change events. | |
| 260 ON_CALL(*sensor_, SetEventSink(NotNull())) | |
| 261 .WillByDefault(Invoke([this](ISensorEvents* events) { | |
| 262 events->AddRef(); | |
| 263 sensor_events_.Attach(events); | |
| 264 return S_OK; | |
| 265 })); | |
| 266 | |
| 267 // When |SetEventSink| is called with nullptr, it means that client is no | |
| 268 // longer interested in sensor events and ISensorEvents can be released. | |
| 269 ON_CALL(*sensor_, SetEventSink(IsNull())) | |
| 270 .WillByDefault(Invoke([this](ISensorEvents* events) { | |
| 271 sensor_events_.Release(); | |
| 272 return S_OK; | |
| 273 })); | |
| 274 } | |
| 275 | |
| 276 // Sets minimal reporting frequency for the mock sensor. | |
| 277 void SetSupportedReportingFrequency(double frequency) { | |
| 278 ON_CALL(*sensor_, GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL, _)) | |
| 279 .WillByDefault( | |
| 280 Invoke([frequency](REFPROPERTYKEY key, PROPVARIANT* pProperty) { | |
| 281 pProperty->vt = VT_UI4; | |
| 282 pProperty->ulVal = | |
| 283 (1 / frequency) * base::Time::kMillisecondsPerSecond; | |
| 284 return S_OK; | |
| 285 })); | |
| 286 } | |
| 287 | |
| 288 // Generates OnLeave event, e.g. when sensor is disconnected. | |
| 289 void GenerateLeaveEvent() { | |
| 290 if (!sensor_events_) | |
| 291 return; | |
| 292 sensor_events_->OnLeave(SENSOR_ID()); | |
| 293 } | |
| 294 | |
| 295 // Generates OnStateChangedLeave event. | |
| 296 void GenerateStateChangeEvent(SensorState state) { | |
| 297 if (!sensor_events_) | |
| 298 return; | |
| 299 sensor_events_->OnStateChanged(sensor_.get(), state); | |
| 300 } | |
| 301 | |
| 302 // Generates OnDataUpdated event and creates ISensorDataReport with fake | |
| 303 // |value| for property with |key|. | |
| 304 void GenerateDataUpdatedEvent(REFPROPERTYKEY key, double value) { | |
| 305 if (!sensor_events_) | |
| 306 return; | |
| 307 | |
| 308 auto mock_report = new NiceMock<MockISensorDataReport>(); | |
|
Lei Zhang
2016/10/29 05:10:41
And who frees |mock_report| ?
Lei Zhang
2016/10/29 05:10:41
auto*
shalamov
2016/10/31 13:12:57
MockISensorDataReport is derived from IUnknownImpl
shalamov
2016/10/31 13:12:57
Done.
Lei Zhang
2016/10/31 18:22:16
So it's self releasing? Please add a comment, beca
shalamov
2016/11/01 11:00:02
Added comments.
| |
| 309 | |
| 310 EXPECT_CALL(*mock_report, GetTimestamp(_)) | |
| 311 .WillOnce(Invoke([](SYSTEMTIME* timestamp) { | |
| 312 GetSystemTime(timestamp); | |
| 313 return S_OK; | |
| 314 })); | |
| 315 | |
| 316 EXPECT_CALL(*mock_report, GetSensorValue(key, _)) | |
| 317 .WillOnce(Invoke([value](REFPROPERTYKEY, PROPVARIANT* variant) { | |
| 318 variant->vt = VT_R8; | |
| 319 variant->dblVal = value; | |
| 320 return S_OK; | |
| 321 })); | |
| 322 | |
| 323 base::win::ScopedComPtr<ISensorDataReport> data_report; | |
| 324 mock_report->QueryInterface(__uuidof(ISensorDataReport), | |
| 325 data_report.ReceiveVoid()); | |
| 326 | |
| 327 sensor_events_->OnDataUpdated(sensor_.get(), data_report.get()); | |
| 328 } | |
| 329 | |
| 330 scoped_refptr<MockISensorManager> sensor_manager_; | |
| 331 scoped_refptr<MockISensorCollection> sensor_collection_; | |
| 332 scoped_refptr<MockISensor> sensor_; | |
| 333 base::win::ScopedComPtr<ISensorEvents> sensor_events_; | |
| 334 std::unique_ptr<base::MessageLoop> message_loop_; | |
|
Lei Zhang
2016/10/29 05:10:41
Can this just be a base::MessageLoopForIO? (not an
shalamov
2016/10/31 13:12:57
Done.
| |
| 335 scoped_refptr<PlatformSensor> platform_sensor_; | |
| 336 // Inner run loop used to wait for async sensor creation callback. | |
| 337 std::unique_ptr<base::RunLoop> run_loop_; | |
| 338 }; | |
| 339 | |
| 340 // Mock for PlatformSensor's client interface that is used to deliver | |
| 341 // error and data changes notifications. | |
| 342 class MockPlatformSensorClient : public PlatformSensor::Client { | |
| 343 public: | |
| 344 MockPlatformSensorClient() = default; | |
| 345 explicit MockPlatformSensorClient(scoped_refptr<PlatformSensor> sensor) | |
| 346 : sensor_(sensor) { | |
| 347 if (sensor_) | |
| 348 sensor_->AddClient(this); | |
| 349 | |
| 350 ON_CALL(*this, IsNotificationSuspended()).WillByDefault(Return(false)); | |
| 351 } | |
| 352 | |
| 353 ~MockPlatformSensorClient() override { | |
| 354 if (sensor_) | |
| 355 sensor_->RemoveClient(this); | |
| 356 } | |
| 357 | |
| 358 // PlatformSensor::Client interface. | |
| 359 MOCK_METHOD0(OnSensorReadingChanged, void()); | |
| 360 MOCK_METHOD0(OnSensorError, void()); | |
| 361 MOCK_METHOD0(IsNotificationSuspended, bool()); | |
| 362 | |
| 363 private: | |
| 364 scoped_refptr<PlatformSensor> sensor_; | |
| 365 }; | |
| 366 | |
| 367 // Tests that PlatformSensorManager returns null sensor when sensor | |
| 368 // is not implemented. | |
| 369 TEST_F(PlatformSensorAndProviderTestWin, SensorIsNotImplemented) { | |
| 370 EXPECT_CALL(*sensor_manager_, | |
| 371 GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D, _)) | |
| 372 .Times(0); | |
| 373 EXPECT_FALSE(CreateSensor(SensorType::ACCELEROMETER)); | |
| 374 } | |
| 375 | |
| 376 // Tests that PlatformSensorManager returns null sensor when sensor | |
| 377 // is implemented, but not supported by the hardware. | |
| 378 TEST_F(PlatformSensorAndProviderTestWin, SensorIsNotSupported) { | |
| 379 EXPECT_CALL(*sensor_manager_, GetSensorsByType(SENSOR_TYPE_AMBIENT_LIGHT, _)) | |
| 380 .WillOnce(Invoke([](REFSENSOR_TYPE_ID, ISensorCollection** result) { | |
| 381 *result = nullptr; | |
| 382 return E_FAIL; | |
| 383 })); | |
| 384 | |
| 385 EXPECT_FALSE(CreateSensor(SensorType::AMBIENT_LIGHT)); | |
| 386 } | |
| 387 | |
| 388 // Tests that PlatformSensorManager returns correct sensor when sensor | |
| 389 // is supported by the hardware. | |
| 390 TEST_F(PlatformSensorAndProviderTestWin, SensorIsSupported) { | |
| 391 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
| 392 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
| 393 EXPECT_TRUE(sensor); | |
| 394 EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor->GetType()); | |
| 395 } | |
| 396 | |
| 397 // Tests that PlatformSensor::StartListening fails when provided reporting | |
| 398 // frequency is above hardware capabilities. | |
| 399 TEST_F(PlatformSensorAndProviderTestWin, StartFails) { | |
| 400 SetSupportedReportingFrequency(1); | |
| 401 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
| 402 | |
| 403 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
| 404 EXPECT_TRUE(sensor); | |
| 405 | |
| 406 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
|
Lei Zhang
2016/10/29 05:10:41
We're using base::MakeUnique for now.
shalamov
2016/10/31 13:12:57
Done.
| |
| 407 PlatformSensorConfiguration configuration(10); | |
| 408 EXPECT_FALSE(sensor->StartListening(client.get(), configuration)); | |
| 409 } | |
| 410 | |
| 411 // Tests that PlatformSensor::StartListening succeeds and notification about | |
| 412 // modified sensor reading is sent to the PlatformSensor::Client interface. | |
| 413 TEST_F(PlatformSensorAndProviderTestWin, SensorStarted) { | |
| 414 SetSupportedReportingFrequency(10); | |
| 415 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
| 416 | |
| 417 EXPECT_CALL(*sensor_, SetEventSink(NotNull())).Times(1); | |
| 418 EXPECT_CALL(*sensor_, SetEventSink(IsNull())).Times(1); | |
| 419 EXPECT_CALL(*sensor_, SetProperties(NotNull(), _)) | |
| 420 .WillOnce(Invoke( | |
| 421 [](IPortableDeviceValues* props, IPortableDeviceValues** result) { | |
| 422 ULONG value = 0; | |
| 423 HRESULT hr = props->GetUnsignedIntegerValue( | |
| 424 SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, &value); | |
| 425 EXPECT_TRUE(SUCCEEDED(hr)); | |
| 426 // 10Hz is 100msec | |
| 427 EXPECT_THAT(value, 100); | |
| 428 return hr; | |
| 429 })); | |
| 430 | |
| 431 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
| 432 EXPECT_TRUE(sensor); | |
| 433 | |
| 434 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
| 435 PlatformSensorConfiguration configuration(10); | |
| 436 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
| 437 | |
| 438 EXPECT_CALL(*client, OnSensorReadingChanged()).Times(1); | |
| 439 GenerateDataUpdatedEvent(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, 3.14); | |
| 440 base::RunLoop().RunUntilIdle(); | |
| 441 EXPECT_TRUE(sensor->StopListening(client.get(), configuration)); | |
| 442 } | |
| 443 | |
| 444 // Tests that OnSensorError is called when sensor is disconnected. | |
| 445 TEST_F(PlatformSensorAndProviderTestWin, SensorRemoved) { | |
| 446 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
| 447 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
| 448 EXPECT_TRUE(sensor); | |
| 449 | |
| 450 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
| 451 PlatformSensorConfiguration configuration(10); | |
| 452 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
| 453 EXPECT_CALL(*client, OnSensorError()).Times(1); | |
| 454 | |
| 455 GenerateLeaveEvent(); | |
| 456 base::RunLoop().RunUntilIdle(); | |
| 457 } | |
| 458 | |
| 459 // Tests that OnSensorError is called when sensor is in an error state. | |
| 460 TEST_F(PlatformSensorAndProviderTestWin, SensorStateChangedToError) { | |
| 461 SetSupportedSensor(SENSOR_TYPE_AMBIENT_LIGHT); | |
| 462 auto sensor = CreateSensor(SensorType::AMBIENT_LIGHT); | |
| 463 EXPECT_TRUE(sensor); | |
| 464 | |
| 465 auto client = std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor); | |
| 466 PlatformSensorConfiguration configuration(10); | |
| 467 EXPECT_TRUE(sensor->StartListening(client.get(), configuration)); | |
| 468 EXPECT_CALL(*client, OnSensorError()).Times(1); | |
| 469 | |
| 470 GenerateStateChangeEvent(SENSOR_STATE_ERROR); | |
| 471 base::RunLoop().RunUntilIdle(); | |
| 472 } | |
| 473 | |
| 474 } // namespace device | |
| OLD | NEW |