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_orientation_event_pump.h" 6 7 #include "base/logging.h" 8 #include "base/message_loop/message_loop.h" 9 #include "content/common/device_sensors/device_orientation_hardware_buffer.h" 10 #include "content/public/test/test_utils.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "third_party/WebKit/public/platform/WebDeviceOrientationListener.h" 13 14 namespace content { 15 16 class MockDeviceOrientationListener 17 : public blink::WebDeviceOrientationListener { 18 public: 19 MockDeviceOrientationListener() : did_change_device_orientation_(false) { 20 memset(&data_, 0, sizeof(data_)); 21 } 22 virtual ~MockDeviceOrientationListener() { } 23 24 virtual void didChangeDeviceOrientation( 25 const blink::WebDeviceOrientationData& data) OVERRIDE { 26 memcpy(&data_, &data, sizeof(data)); 27 did_change_device_orientation_ = true; 28 } 29 30 bool did_change_device_orientation() const { 31 return did_change_device_orientation_; 32 } 33 void set_did_change_device_orientation(bool value) { 34 did_change_device_orientation_ = value; 35 } 36 const blink::WebDeviceOrientationData& data() const { 37 return data_; 38 } 39 40 private: 41 bool did_change_device_orientation_; 42 blink::WebDeviceOrientationData data_; 43 44 DISALLOW_COPY_AND_ASSIGN(MockDeviceOrientationListener); 45 }; 46 47 class DeviceOrientationEventPumpForTesting : public DeviceOrientationEventPump { 48 public: 49 DeviceOrientationEventPumpForTesting() 50 : DeviceOrientationEventPump(0) { } 51 virtual ~DeviceOrientationEventPumpForTesting() { } 52 53 void OnDidStart(base::SharedMemoryHandle renderer_handle) { 54 DeviceOrientationEventPump::OnDidStart(renderer_handle); 55 } 56 virtual void SendStartMessage() OVERRIDE { } 57 virtual void SendStopMessage() OVERRIDE { } 58 virtual void FireEvent() OVERRIDE { 59 DeviceOrientationEventPump::FireEvent(); 60 Stop(); 61 base::MessageLoop::current()->QuitWhenIdle(); 62 } 63 64 private: 65 DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpForTesting); 66 }; 67 68 class DeviceOrientationEventPumpTest : public testing::Test { 69 public: 70 DeviceOrientationEventPumpTest() { 71 EXPECT_TRUE(shared_memory_.CreateAndMapAnonymous( 72 sizeof(DeviceOrientationHardwareBuffer))); 73 } 74 75 protected: 76 virtual void SetUp() OVERRIDE { 77 const DeviceOrientationHardwareBuffer* null_buffer = NULL; 78 listener_.reset(new MockDeviceOrientationListener); 79 orientation_pump_.reset(new DeviceOrientationEventPumpForTesting); 80 buffer_ = static_cast<DeviceOrientationHardwareBuffer*>( 81 shared_memory_.memory()); 82 ASSERT_NE(null_buffer, buffer_); 83 memset(buffer_, 0, sizeof(DeviceOrientationHardwareBuffer)); 84 ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(), 85 &handle_)); 86 } 87 88 void InitBuffer() { 89 blink::WebDeviceOrientationData& data = buffer_->data; 90 data.alpha = 1; 91 data.hasAlpha = true; 92 data.beta = 2; 93 data.hasBeta = true; 94 data.gamma = 3; 95 data.hasGamma = true; 96 data.allAvailableSensorsAreActive = true; 97 } 98 99 void InitBufferNoData() { 100 blink::WebDeviceOrientationData& data = buffer_->data; 101 data.allAvailableSensorsAreActive = true; 102 } 103 104 MockDeviceOrientationListener* listener() { return listener_.get(); } 105 DeviceOrientationEventPumpForTesting* orientation_pump() { 106 return orientation_pump_.get(); 107 } 108 base::SharedMemoryHandle handle() { return handle_; } 109 DeviceOrientationHardwareBuffer* buffer() { return buffer_; } 110 111 private: 112 scoped_ptr<MockDeviceOrientationListener> listener_; 113 scoped_ptr<DeviceOrientationEventPumpForTesting> orientation_pump_; 114 base::SharedMemoryHandle handle_; 115 base::SharedMemory shared_memory_; 116 DeviceOrientationHardwareBuffer* buffer_; 117 118 DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest); 119 }; 120 121 TEST_F(DeviceOrientationEventPumpTest, DidStartPolling) { 122 base::MessageLoop loop; 123 124 InitBuffer(); 125 orientation_pump()->Start(listener()); 126 orientation_pump()->OnDidStart(handle()); 127 128 base::MessageLoop::current()->Run(); 129 130 const blink::WebDeviceOrientationData& received_data = listener()->data(); 131 EXPECT_TRUE(listener()->did_change_device_orientation()); 132 EXPECT_TRUE(received_data.allAvailableSensorsAreActive); 133 EXPECT_EQ(1, static_cast<double>(received_data.alpha)); 134 EXPECT_TRUE(received_data.hasAlpha); 135 EXPECT_EQ(2, static_cast<double>(received_data.beta)); 136 EXPECT_TRUE(received_data.hasBeta); 137 EXPECT_EQ(3, static_cast<double>(received_data.gamma)); 138 EXPECT_TRUE(received_data.hasGamma); 139 } 140 141 TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) { 142 base::MessageLoop loop; 143 144 InitBufferNoData(); 145 orientation_pump()->Start(listener()); 146 orientation_pump()->OnDidStart(handle()); 147 148 base::MessageLoop::current()->Run(); 149 150 const blink::WebDeviceOrientationData& received_data = listener()->data(); 151 EXPECT_TRUE(listener()->did_change_device_orientation()); 152 EXPECT_TRUE(received_data.allAvailableSensorsAreActive); 153 EXPECT_FALSE(received_data.hasAlpha); 154 EXPECT_FALSE(received_data.hasBeta); 155 EXPECT_FALSE(received_data.hasGamma); 156 } 157 158 TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) { 159 base::MessageLoop loop; 160 161 InitBuffer(); 162 orientation_pump()->Start(listener()); 163 orientation_pump()->OnDidStart(handle()); 164 165 base::MessageLoop::current()->Run(); 166 167 const blink::WebDeviceOrientationData& received_data = listener()->data(); 168 EXPECT_TRUE(listener()->did_change_device_orientation()); 169 EXPECT_TRUE(received_data.allAvailableSensorsAreActive); 170 EXPECT_EQ(1, static_cast<double>(received_data.alpha)); 171 EXPECT_TRUE(received_data.hasAlpha); 172 EXPECT_EQ(2, static_cast<double>(received_data.beta)); 173 EXPECT_TRUE(received_data.hasBeta); 174 EXPECT_EQ(3, static_cast<double>(received_data.gamma)); 175 EXPECT_TRUE(received_data.hasGamma); 176 177 buffer()->data.alpha = 178 1 + DeviceOrientationEventPump::kOrientationThreshold / 2.0; 179 listener()->set_did_change_device_orientation(false); 180 181 // Reset the pump's listener. 182 orientation_pump()->Start(listener()); 183 184 base::MessageLoop::current()->PostTask(FROM_HERE, 185 base::Bind(&DeviceOrientationEventPumpForTesting::FireEvent, 186 base::Unretained(orientation_pump()))); 187 base::MessageLoop::current()->Run(); 188 189 EXPECT_FALSE(listener()->did_change_device_orientation()); 190 EXPECT_TRUE(received_data.allAvailableSensorsAreActive); 191 EXPECT_EQ(1, static_cast<double>(received_data.alpha)); 192 EXPECT_TRUE(received_data.hasAlpha); 193 EXPECT_EQ(2, static_cast<double>(received_data.beta)); 194 EXPECT_TRUE(received_data.hasBeta); 195 EXPECT_EQ(3, static_cast<double>(received_data.gamma)); 196 EXPECT_TRUE(received_data.hasGamma); 197 198 buffer()->data.alpha = 199 1 + DeviceOrientationEventPump::kOrientationThreshold; 200 listener()->set_did_change_device_orientation(false); 201 202 // Reset the pump's listener. 203 orientation_pump()->Start(listener()); 204 205 base::MessageLoop::current()->PostTask(FROM_HERE, 206 base::Bind(&DeviceOrientationEventPumpForTesting::FireEvent, 207 base::Unretained(orientation_pump()))); 208 base::MessageLoop::current()->Run(); 209 210 EXPECT_TRUE(listener()->did_change_device_orientation()); 211 EXPECT_EQ(1 + DeviceOrientationEventPump::kOrientationThreshold, 212 static_cast<double>(received_data.alpha)); 213 } 214 215 } // namespace content 216