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 "device_motion_event_pump.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/message_loop/message_loop.h" 10 #include "content/common/device_sensors/device_motion_hardware_buffer.h" 11 #include "content/public/test/test_utils.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "third_party/WebKit/public/platform/WebDeviceMotionListener.h" 14 15 namespace content { 16 17 class MockDeviceMotionListener : public blink::WebDeviceMotionListener { 18 public: 19 MockDeviceMotionListener() : did_change_device_motion_(false) { 20 memset(&data_, 0, sizeof(data_)); 21 } 22 virtual ~MockDeviceMotionListener() { } 23 24 virtual void didChangeDeviceMotion( 25 const blink::WebDeviceMotionData& data) OVERRIDE { 26 memcpy(&data_, &data, sizeof(data)); 27 did_change_device_motion_ = true; 28 } 29 30 bool did_change_device_motion() const { 31 return did_change_device_motion_; 32 } 33 const blink::WebDeviceMotionData& data() const { 34 return data_; 35 } 36 37 private: 38 bool did_change_device_motion_; 39 blink::WebDeviceMotionData data_; 40 41 DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionListener); 42 }; 43 44 class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { 45 public: 46 DeviceMotionEventPumpForTesting() 47 : DeviceMotionEventPump(0) { } 48 virtual ~DeviceMotionEventPumpForTesting() { } 49 50 void OnDidStart(base::SharedMemoryHandle renderer_handle) { 51 DeviceMotionEventPump::OnDidStart(renderer_handle); 52 } 53 virtual void SendStartMessage() OVERRIDE { } 54 virtual void SendStopMessage() OVERRIDE { } 55 virtual void FireEvent() OVERRIDE { 56 DeviceMotionEventPump::FireEvent(); 57 Stop(); 58 base::MessageLoop::current()->QuitWhenIdle(); 59 } 60 61 private: 62 DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); 63 }; 64 65 class DeviceMotionEventPumpTest : public testing::Test { 66 public: 67 DeviceMotionEventPumpTest() { 68 EXPECT_TRUE(shared_memory_.CreateAndMapAnonymous( 69 sizeof(DeviceMotionHardwareBuffer))); 70 } 71 72 protected: 73 virtual void SetUp() OVERRIDE { 74 const DeviceMotionHardwareBuffer* null_buffer = NULL; 75 listener_.reset(new MockDeviceMotionListener); 76 motion_pump_.reset(new DeviceMotionEventPumpForTesting); 77 buffer_ = static_cast<DeviceMotionHardwareBuffer*>(shared_memory_.memory()); 78 ASSERT_NE(null_buffer, buffer_); 79 memset(buffer_, 0, sizeof(DeviceMotionHardwareBuffer)); 80 ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(), 81 &handle_)); 82 } 83 84 void InitBuffer(bool allAvailableSensorsActive) { 85 blink::WebDeviceMotionData& data = buffer_->data; 86 data.accelerationX = 1; 87 data.hasAccelerationX = true; 88 data.accelerationY = 2; 89 data.hasAccelerationY = true; 90 data.accelerationZ = 3; 91 data.hasAccelerationZ = true; 92 data.allAvailableSensorsAreActive = allAvailableSensorsActive; 93 } 94 95 MockDeviceMotionListener* listener() { return listener_.get(); } 96 DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); } 97 base::SharedMemoryHandle handle() { return handle_; } 98 99 private: 100 scoped_ptr<MockDeviceMotionListener> listener_; 101 scoped_ptr<DeviceMotionEventPumpForTesting> motion_pump_; 102 base::SharedMemoryHandle handle_; 103 base::SharedMemory shared_memory_; 104 DeviceMotionHardwareBuffer* buffer_; 105 106 DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); 107 }; 108 109 TEST_F(DeviceMotionEventPumpTest, DidStartPolling) { 110 base::MessageLoopForUI loop; 111 112 InitBuffer(true); 113 114 motion_pump()->Start(listener()); 115 motion_pump()->OnDidStart(handle()); 116 117 base::MessageLoop::current()->Run(); 118 119 const blink::WebDeviceMotionData& received_data = listener()->data(); 120 EXPECT_TRUE(listener()->did_change_device_motion()); 121 EXPECT_TRUE(received_data.hasAccelerationX); 122 EXPECT_EQ(1, static_cast<double>(received_data.accelerationX)); 123 EXPECT_TRUE(received_data.hasAccelerationX); 124 EXPECT_EQ(2, static_cast<double>(received_data.accelerationY)); 125 EXPECT_TRUE(received_data.hasAccelerationY); 126 EXPECT_EQ(3, static_cast<double>(received_data.accelerationZ)); 127 EXPECT_TRUE(received_data.hasAccelerationZ); 128 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityX); 129 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityY); 130 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityZ); 131 EXPECT_FALSE(received_data.hasRotationRateAlpha); 132 EXPECT_FALSE(received_data.hasRotationRateBeta); 133 EXPECT_FALSE(received_data.hasRotationRateGamma); 134 } 135 136 TEST_F(DeviceMotionEventPumpTest, DidStartPollingNotAllSensorsActive) { 137 base::MessageLoopForUI loop; 138 139 InitBuffer(false); 140 141 motion_pump()->Start(listener()); 142 motion_pump()->OnDidStart(handle()); 143 144 base::MessageLoop::current()->Run(); 145 146 const blink::WebDeviceMotionData& received_data = listener()->data(); 147 // No change in device motion because allAvailableSensorsAreActive is false. 148 EXPECT_FALSE(listener()->did_change_device_motion()); 149 EXPECT_FALSE(received_data.hasAccelerationX); 150 EXPECT_FALSE(received_data.hasAccelerationX); 151 EXPECT_FALSE(received_data.hasAccelerationY); 152 EXPECT_FALSE(received_data.hasAccelerationZ); 153 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityX); 154 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityY); 155 EXPECT_FALSE(received_data.hasAccelerationIncludingGravityZ); 156 EXPECT_FALSE(received_data.hasRotationRateAlpha); 157 EXPECT_FALSE(received_data.hasRotationRateBeta); 158 EXPECT_FALSE(received_data.hasRotationRateGamma); 159 } 160 161 } // namespace content 162