1// Copyright 2014 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_sensors/data_fetcher_shared_memory_base.h" 6 7#include "base/logging.h" 8#include "base/process/process_handle.h" 9#include "base/synchronization/waitable_event.h" 10#include "base/threading/thread.h" 11#include "content/common/device_sensors/device_light_hardware_buffer.h" 12#include "content/common/device_sensors/device_motion_hardware_buffer.h" 13#include "content/common/device_sensors/device_orientation_hardware_buffer.h" 14#include "testing/gtest/include/gtest/gtest.h" 15 16namespace content { 17 18namespace { 19 20class FakeDataFetcher : public DataFetcherSharedMemoryBase { 21 public: 22 FakeDataFetcher() 23 : start_light_(false, false), 24 start_motion_(false, false), 25 start_orientation_(false, false), 26 stop_light_(false, false), 27 stop_motion_(false, false), 28 stop_orientation_(false, false), 29 updated_light_(false, false), 30 updated_motion_(false, false), 31 updated_orientation_(false, false), 32 light_buffer_(NULL), 33 motion_buffer_(NULL), 34 orientation_buffer_(NULL) {} 35 virtual ~FakeDataFetcher() { } 36 37 bool Init(ConsumerType consumer_type, void* buffer) { 38 EXPECT_TRUE(buffer); 39 40 switch (consumer_type) { 41 case CONSUMER_TYPE_MOTION: 42 motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer); 43 break; 44 case CONSUMER_TYPE_ORIENTATION: 45 orientation_buffer_ = 46 static_cast<DeviceOrientationHardwareBuffer*>(buffer); 47 break; 48 case CONSUMER_TYPE_LIGHT: 49 light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer); 50 break; 51 default: 52 return false; 53 } 54 return true; 55 } 56 57 void UpdateLight() { 58 DeviceLightHardwareBuffer* buffer = GetLightBuffer(); 59 ASSERT_TRUE(buffer); 60 buffer->seqlock.WriteBegin(); 61 buffer->data.value = 100; 62 buffer->seqlock.WriteEnd(); 63 updated_light_.Signal(); 64 } 65 66 void UpdateMotion() { 67 DeviceMotionHardwareBuffer* buffer = GetMotionBuffer(); 68 ASSERT_TRUE(buffer); 69 buffer->seqlock.WriteBegin(); 70 buffer->data.interval = kInertialSensorIntervalMillis; 71 buffer->seqlock.WriteEnd(); 72 updated_motion_.Signal(); 73 } 74 75 void UpdateOrientation() { 76 DeviceOrientationHardwareBuffer* buffer = GetOrientationBuffer(); 77 ASSERT_TRUE(buffer); 78 buffer->seqlock.WriteBegin(); 79 buffer->data.alpha = 1; 80 buffer->seqlock.WriteEnd(); 81 updated_orientation_.Signal(); 82 } 83 84 DeviceLightHardwareBuffer* GetLightBuffer() const { return light_buffer_; } 85 86 DeviceMotionHardwareBuffer* GetMotionBuffer() const { 87 return motion_buffer_; 88 } 89 90 DeviceOrientationHardwareBuffer* GetOrientationBuffer() const { 91 return orientation_buffer_; 92 } 93 94 void WaitForStart(ConsumerType consumer_type) { 95 switch (consumer_type) { 96 case CONSUMER_TYPE_MOTION: 97 start_motion_.Wait(); 98 break; 99 case CONSUMER_TYPE_ORIENTATION: 100 start_orientation_.Wait(); 101 break; 102 case CONSUMER_TYPE_LIGHT: 103 start_light_.Wait(); 104 break; 105 } 106 } 107 108 void WaitForStop(ConsumerType consumer_type) { 109 switch (consumer_type) { 110 case CONSUMER_TYPE_MOTION: 111 stop_motion_.Wait(); 112 break; 113 case CONSUMER_TYPE_ORIENTATION: 114 stop_orientation_.Wait(); 115 break; 116 case CONSUMER_TYPE_LIGHT: 117 stop_light_.Wait(); 118 break; 119 } 120 } 121 122 void WaitForUpdate(ConsumerType consumer_type) { 123 switch (consumer_type) { 124 case CONSUMER_TYPE_MOTION: 125 updated_motion_.Wait(); 126 break; 127 case CONSUMER_TYPE_ORIENTATION: 128 updated_orientation_.Wait(); 129 break; 130 case CONSUMER_TYPE_LIGHT: 131 updated_light_.Wait(); 132 break; 133 } 134 } 135 136 protected: 137 base::WaitableEvent start_light_; 138 base::WaitableEvent start_motion_; 139 base::WaitableEvent start_orientation_; 140 base::WaitableEvent stop_light_; 141 base::WaitableEvent stop_motion_; 142 base::WaitableEvent stop_orientation_; 143 base::WaitableEvent updated_light_; 144 base::WaitableEvent updated_motion_; 145 base::WaitableEvent updated_orientation_; 146 147 private: 148 DeviceLightHardwareBuffer* light_buffer_; 149 DeviceMotionHardwareBuffer* motion_buffer_; 150 DeviceOrientationHardwareBuffer* orientation_buffer_; 151 152 DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); 153}; 154 155class FakeNonPollingDataFetcher : public FakeDataFetcher { 156 public: 157 FakeNonPollingDataFetcher() { } 158 virtual ~FakeNonPollingDataFetcher() { } 159 160 virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE { 161 Init(consumer_type, buffer); 162 switch (consumer_type) { 163 case CONSUMER_TYPE_MOTION: 164 UpdateMotion(); 165 start_motion_.Signal(); 166 break; 167 case CONSUMER_TYPE_ORIENTATION: 168 UpdateOrientation(); 169 start_orientation_.Signal(); 170 break; 171 case CONSUMER_TYPE_LIGHT: 172 UpdateLight(); 173 start_light_.Signal(); 174 break; 175 default: 176 return false; 177 } 178 return true; 179 } 180 181 virtual bool Stop(ConsumerType consumer_type) OVERRIDE { 182 switch (consumer_type) { 183 case CONSUMER_TYPE_MOTION: 184 stop_motion_.Signal(); 185 break; 186 case CONSUMER_TYPE_ORIENTATION: 187 stop_orientation_.Signal(); 188 break; 189 case CONSUMER_TYPE_LIGHT: 190 stop_light_.Signal(); 191 break; 192 default: 193 return false; 194 } 195 return true; 196 } 197 198 virtual void Fetch(unsigned consumer_bitmask) OVERRIDE { 199 FAIL() << "fetch should not be called, " 200 << "because this is a non-polling fetcher"; 201 } 202 203 virtual FetcherType GetType() const OVERRIDE { 204 return FakeDataFetcher::GetType(); 205 } 206 207 private: 208 DISALLOW_COPY_AND_ASSIGN(FakeNonPollingDataFetcher); 209}; 210 211class FakePollingDataFetcher : public FakeDataFetcher { 212 public: 213 FakePollingDataFetcher() { } 214 virtual ~FakePollingDataFetcher() { } 215 216 virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE { 217 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); 218 219 Init(consumer_type, buffer); 220 switch (consumer_type) { 221 case CONSUMER_TYPE_MOTION: 222 start_motion_.Signal(); 223 break; 224 case CONSUMER_TYPE_ORIENTATION: 225 start_orientation_.Signal(); 226 break; 227 case CONSUMER_TYPE_LIGHT: 228 start_light_.Signal(); 229 break; 230 default: 231 return false; 232 } 233 return true; 234 } 235 236 virtual bool Stop(ConsumerType consumer_type) OVERRIDE { 237 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); 238 239 switch (consumer_type) { 240 case CONSUMER_TYPE_MOTION: 241 stop_motion_.Signal(); 242 break; 243 case CONSUMER_TYPE_ORIENTATION: 244 stop_orientation_.Signal(); 245 break; 246 case CONSUMER_TYPE_LIGHT: 247 stop_light_.Signal(); 248 break; 249 default: 250 return false; 251 } 252 return true; 253 } 254 255 virtual void Fetch(unsigned consumer_bitmask) OVERRIDE { 256 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); 257 EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION || 258 consumer_bitmask & CONSUMER_TYPE_MOTION || 259 consumer_bitmask & CONSUMER_TYPE_LIGHT); 260 261 if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION) 262 UpdateOrientation(); 263 if (consumer_bitmask & CONSUMER_TYPE_MOTION) 264 UpdateMotion(); 265 if (consumer_bitmask & CONSUMER_TYPE_LIGHT) 266 UpdateLight(); 267 } 268 269 virtual FetcherType GetType() const OVERRIDE { 270 return FETCHER_TYPE_POLLING_CALLBACK; 271 } 272 273 private: 274 DISALLOW_COPY_AND_ASSIGN(FakePollingDataFetcher); 275}; 276 277class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher { 278 public: 279 FakeZeroDelayPollingDataFetcher() { } 280 virtual ~FakeZeroDelayPollingDataFetcher() { } 281 282 virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE { 283 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); 284 285 Init(consumer_type, buffer); 286 switch (consumer_type) { 287 case CONSUMER_TYPE_MOTION: 288 start_motion_.Signal(); 289 break; 290 case CONSUMER_TYPE_ORIENTATION: 291 start_orientation_.Signal(); 292 break; 293 case CONSUMER_TYPE_LIGHT: 294 start_light_.Signal(); 295 break; 296 default: 297 return false; 298 } 299 return true; 300 } 301 302 virtual bool Stop(ConsumerType consumer_type) OVERRIDE { 303 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); 304 305 switch (consumer_type) { 306 case CONSUMER_TYPE_MOTION: 307 stop_motion_.Signal(); 308 break; 309 case CONSUMER_TYPE_ORIENTATION: 310 stop_orientation_.Signal(); 311 break; 312 case CONSUMER_TYPE_LIGHT: 313 stop_light_.Signal(); 314 break; 315 default: 316 return false; 317 } 318 return true; 319 } 320 321 virtual void Fetch(unsigned consumer_bitmask) OVERRIDE { 322 FAIL() << "fetch should not be called"; 323 } 324 325 virtual FetcherType GetType() const OVERRIDE { 326 return FETCHER_TYPE_SEPARATE_THREAD; 327 } 328 329 bool IsPollingTimerRunningForTesting() const { 330 return FakeDataFetcher::IsPollingTimerRunningForTesting(); 331 } 332 333 private: 334 DISALLOW_COPY_AND_ASSIGN(FakeZeroDelayPollingDataFetcher); 335}; 336 337 338TEST(DataFetcherSharedMemoryBaseTest, DoesStartMotion) { 339 FakeNonPollingDataFetcher fake_data_fetcher; 340 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, 341 fake_data_fetcher.GetType()); 342 343 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION)); 344 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); 345 346 EXPECT_EQ(kInertialSensorIntervalMillis, 347 fake_data_fetcher.GetMotionBuffer()->data.interval); 348 349 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); 350 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); 351} 352 353TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) { 354 FakeNonPollingDataFetcher fake_data_fetcher; 355 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, 356 fake_data_fetcher.GetType()); 357 358 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( 359 CONSUMER_TYPE_ORIENTATION)); 360 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); 361 362 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); 363 364 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); 365 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); 366} 367 368TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) { 369 FakeNonPollingDataFetcher fake_data_fetcher; 370 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, 371 fake_data_fetcher.GetType()); 372 373 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT)); 374 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT); 375 376 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value); 377 378 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT); 379 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT); 380} 381 382TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) { 383 FakePollingDataFetcher fake_data_fetcher; 384 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, 385 fake_data_fetcher.GetType()); 386 387 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION)); 388 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); 389 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION); 390 391 EXPECT_EQ(kInertialSensorIntervalMillis, 392 fake_data_fetcher.GetMotionBuffer()->data.interval); 393 394 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); 395 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); 396} 397 398TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) { 399 FakePollingDataFetcher fake_data_fetcher; 400 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, 401 fake_data_fetcher.GetType()); 402 403 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( 404 CONSUMER_TYPE_ORIENTATION)); 405 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); 406 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION); 407 408 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); 409 410 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); 411 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); 412} 413 414TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) { 415 FakePollingDataFetcher fake_data_fetcher; 416 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, 417 fake_data_fetcher.GetType()); 418 419 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT)); 420 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT); 421 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_LIGHT); 422 423 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value); 424 425 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT); 426 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT); 427} 428 429TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) { 430 FakePollingDataFetcher fake_data_fetcher; 431 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, 432 fake_data_fetcher.GetType()); 433 434 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( 435 CONSUMER_TYPE_ORIENTATION)); 436 base::SharedMemoryHandle handle_orientation = 437 fake_data_fetcher.GetSharedMemoryHandleForProcess( 438 CONSUMER_TYPE_ORIENTATION, base::GetCurrentProcessHandle()); 439 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_orientation)); 440 441 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( 442 CONSUMER_TYPE_MOTION)); 443 base::SharedMemoryHandle handle_motion = 444 fake_data_fetcher.GetSharedMemoryHandleForProcess( 445 CONSUMER_TYPE_MOTION, base::GetCurrentProcessHandle()); 446 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_motion)); 447 448 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); 449 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); 450 451 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION); 452 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION); 453 454 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); 455 EXPECT_EQ(kInertialSensorIntervalMillis, 456 fake_data_fetcher.GetMotionBuffer()->data.interval); 457 458 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); 459 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); 460 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); 461 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); 462} 463 464TEST(DataFetcherSharedMemoryBaseTest, DoesNotPollZeroDelay) { 465 FakeZeroDelayPollingDataFetcher fake_data_fetcher; 466 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_SEPARATE_THREAD, 467 fake_data_fetcher.GetType()); 468 469 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( 470 CONSUMER_TYPE_ORIENTATION)); 471 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); 472 473 EXPECT_FALSE(fake_data_fetcher.IsPollingTimerRunningForTesting()); 474 EXPECT_EQ(0, fake_data_fetcher.GetOrientationBuffer()->data.alpha); 475 476 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); 477 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); 478} 479 480 481} // namespace 482 483} // namespace content 484