device_inertial_sensor_browsertest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 "base/command_line.h" 6#include "base/synchronization/waitable_event.h" 7#include "base/threading/platform_thread.h" 8#include "content/browser/device_sensors/data_fetcher_shared_memory.h" 9#include "content/browser/device_sensors/device_inertial_sensor_service.h" 10#include "content/common/device_sensors/device_motion_hardware_buffer.h" 11#include "content/common/device_sensors/device_orientation_hardware_buffer.h" 12#include "content/public/browser/browser_thread.h" 13#include "content/public/browser/web_contents.h" 14#include "content/public/common/content_switches.h" 15#include "content/public/test/content_browser_test.h" 16#include "content/public/test/content_browser_test_utils.h" 17#include "content/public/test/test_navigation_observer.h" 18#include "content/public/test/test_utils.h" 19#include "content/shell/browser/shell.h" 20#include "content/shell/browser/shell_javascript_dialog_manager.h" 21 22namespace content { 23 24namespace { 25 26class FakeDataFetcher : public DataFetcherSharedMemory { 27 public: 28 FakeDataFetcher() 29 : started_orientation_(false, false), 30 stopped_orientation_(false, false), 31 started_motion_(false, false), 32 stopped_motion_(false, false), 33 sensor_data_available_(true) { 34 } 35 virtual ~FakeDataFetcher() { } 36 37 virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE { 38 EXPECT_TRUE(buffer); 39 40 switch (consumer_type) { 41 case CONSUMER_TYPE_MOTION: 42 { 43 DeviceMotionHardwareBuffer* motion_buffer = 44 static_cast<DeviceMotionHardwareBuffer*>(buffer); 45 if (sensor_data_available_) 46 UpdateMotion(motion_buffer); 47 SetMotionBufferReady(motion_buffer); 48 started_motion_.Signal(); 49 } 50 break; 51 case CONSUMER_TYPE_ORIENTATION: 52 { 53 DeviceOrientationHardwareBuffer* orientation_buffer = 54 static_cast<DeviceOrientationHardwareBuffer*>(buffer); 55 if (sensor_data_available_) 56 UpdateOrientation(orientation_buffer); 57 SetOrientationBufferReady(orientation_buffer); 58 started_orientation_.Signal(); 59 } 60 break; 61 default: 62 return false; 63 } 64 return true; 65 } 66 67 virtual bool Stop(ConsumerType consumer_type) OVERRIDE { 68 switch (consumer_type) { 69 case CONSUMER_TYPE_MOTION: 70 stopped_motion_.Signal(); 71 break; 72 case CONSUMER_TYPE_ORIENTATION: 73 stopped_orientation_.Signal(); 74 break; 75 default: 76 return false; 77 } 78 return true; 79 } 80 81 virtual void Fetch(unsigned consumer_bitmask) OVERRIDE { 82 FAIL() << "fetch should not be called"; 83 } 84 85 virtual FetcherType GetType() const OVERRIDE { 86 return FETCHER_TYPE_DEFAULT; 87 } 88 89 void SetSensorDataAvailable(bool available) { 90 sensor_data_available_ = available; 91 } 92 93 void SetMotionBufferReady(DeviceMotionHardwareBuffer* buffer) { 94 buffer->seqlock.WriteBegin(); 95 buffer->data.allAvailableSensorsAreActive = true; 96 buffer->seqlock.WriteEnd(); 97 } 98 99 void SetOrientationBufferReady(DeviceOrientationHardwareBuffer* buffer) { 100 buffer->seqlock.WriteBegin(); 101 buffer->data.allAvailableSensorsAreActive = true; 102 buffer->seqlock.WriteEnd(); 103 } 104 105 void UpdateMotion(DeviceMotionHardwareBuffer* buffer) { 106 buffer->seqlock.WriteBegin(); 107 buffer->data.accelerationX = 1; 108 buffer->data.hasAccelerationX = true; 109 buffer->data.accelerationY = 2; 110 buffer->data.hasAccelerationY = true; 111 buffer->data.accelerationZ = 3; 112 buffer->data.hasAccelerationZ = true; 113 114 buffer->data.accelerationIncludingGravityX = 4; 115 buffer->data.hasAccelerationIncludingGravityX = true; 116 buffer->data.accelerationIncludingGravityY = 5; 117 buffer->data.hasAccelerationIncludingGravityY = true; 118 buffer->data.accelerationIncludingGravityZ = 6; 119 buffer->data.hasAccelerationIncludingGravityZ = true; 120 121 buffer->data.rotationRateAlpha = 7; 122 buffer->data.hasRotationRateAlpha = true; 123 buffer->data.rotationRateBeta = 8; 124 buffer->data.hasRotationRateBeta = true; 125 buffer->data.rotationRateGamma = 9; 126 buffer->data.hasRotationRateGamma = true; 127 128 buffer->data.interval = 100; 129 buffer->data.allAvailableSensorsAreActive = true; 130 buffer->seqlock.WriteEnd(); 131 } 132 133 void UpdateOrientation(DeviceOrientationHardwareBuffer* buffer) { 134 buffer->seqlock.WriteBegin(); 135 buffer->data.alpha = 1; 136 buffer->data.hasAlpha = true; 137 buffer->data.beta = 2; 138 buffer->data.hasBeta = true; 139 buffer->data.gamma = 3; 140 buffer->data.hasGamma = true; 141 buffer->data.allAvailableSensorsAreActive = true; 142 buffer->seqlock.WriteEnd(); 143 } 144 145 base::WaitableEvent started_orientation_; 146 base::WaitableEvent stopped_orientation_; 147 base::WaitableEvent started_motion_; 148 base::WaitableEvent stopped_motion_; 149 bool sensor_data_available_; 150 151 private: 152 DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); 153}; 154 155 156class DeviceInertialSensorBrowserTest : public ContentBrowserTest { 157 public: 158 DeviceInertialSensorBrowserTest() 159 : fetcher_(NULL), 160 io_loop_finished_event_(false, false) { 161 } 162 163 virtual void SetUpOnMainThread() OVERRIDE { 164 BrowserThread::PostTask( 165 BrowserThread::IO, FROM_HERE, 166 base::Bind(&DeviceInertialSensorBrowserTest::SetUpOnIOThread, this)); 167 io_loop_finished_event_.Wait(); 168 } 169 170 void SetUpOnIOThread() { 171 fetcher_ = new FakeDataFetcher(); 172 DeviceInertialSensorService::GetInstance()-> 173 SetDataFetcherForTesting(fetcher_); 174 io_loop_finished_event_.Signal(); 175 } 176 177 void DelayAndQuit(base::TimeDelta delay) { 178 base::PlatformThread::Sleep(delay); 179 base::MessageLoop::current()->QuitWhenIdle(); 180 } 181 182 void WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta delay) { 183 ShellJavaScriptDialogManager* dialog_manager= 184 static_cast<ShellJavaScriptDialogManager*>( 185 shell()->GetJavaScriptDialogManager()); 186 187 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner(); 188 dialog_manager->set_dialog_request_callback( 189 base::Bind(&DeviceInertialSensorBrowserTest::DelayAndQuit, this, 190 delay)); 191 runner->Run(); 192 } 193 194 FakeDataFetcher* fetcher_; 195 196 private: 197 base::WaitableEvent io_loop_finished_event_; 198}; 199 200 201IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, OrientationTest) { 202 // The test page will register an event handler for orientation events, 203 // expects to get an event with fake values, then removes the event 204 // handler and navigates to #pass. 205 GURL test_url = GetTestUrl( 206 "device_orientation", "device_orientation_test.html"); 207 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); 208 209 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); 210 fetcher_->started_orientation_.Wait(); 211 fetcher_->stopped_orientation_.Wait(); 212} 213 214IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, MotionTest) { 215 // The test page will register an event handler for motion events, 216 // expects to get an event with fake values, then removes the event 217 // handler and navigates to #pass. 218 GURL test_url = GetTestUrl( 219 "device_orientation", "device_motion_test.html"); 220 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); 221 222 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); 223 fetcher_->started_motion_.Wait(); 224 fetcher_->stopped_motion_.Wait(); 225} 226 227// Flaking in the android try bot. See http://crbug.com/360578. 228#if defined(OS_ANDROID) 229#define MAYBE_OrientationNullTestWithAlert DISABLED_OrientationNullTestWithAlert 230#else 231#define MAYBE_OrientationNullTestWithAlert OrientationNullTestWithAlert 232#endif 233IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, 234 MAYBE_OrientationNullTestWithAlert) { 235 // The test page will register an event handler for orientation events, 236 // expects to get an event with null values. The test raises a modal alert 237 // dialog with a delay to test that the one-off null-event still propagates 238 // to window after the alert is dismissed and the callback is invoked which 239 // navigates to #pass. 240 fetcher_->SetSensorDataAvailable(false); 241 TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); 242 243 GURL test_url = GetTestUrl( 244 "device_orientation", "device_orientation_null_test_with_alert.html"); 245 shell()->LoadURL(test_url); 246 247 // TODO(timvolodine): investigate if it is possible to test this without 248 // delay, crbug.com/360044. 249 WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(1000)); 250 251 fetcher_->started_orientation_.Wait(); 252 fetcher_->stopped_orientation_.Wait(); 253 same_tab_observer.Wait(); 254 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); 255} 256 257// Flaking in the android try bot. See http://crbug.com/360578. 258#if defined(OS_ANDROID) 259#define MAYBE_MotionNullTestWithAlert DISABLED_MotionNullTestWithAlert 260#else 261#define MAYBE_MotionNullTestWithAlert MotionNullTestWithAlert 262#endif 263IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, 264 MAYBE_MotionNullTestWithAlert) { 265 // The test page will register an event handler for motion events, 266 // expects to get an event with null values. The test raises a modal alert 267 // dialog with a delay to test that the one-off null-event still propagates 268 // to window after the alert is dismissed and the callback is invoked which 269 // navigates to #pass. 270 fetcher_->SetSensorDataAvailable(false); 271 TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); 272 273 GURL test_url = GetTestUrl( 274 "device_orientation", "device_motion_null_test_with_alert.html"); 275 shell()->LoadURL(test_url); 276 277 // TODO(timvolodine): investigate if it is possible to test this without 278 // delay, crbug.com/360044. 279 WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(1000)); 280 281 fetcher_->started_motion_.Wait(); 282 fetcher_->stopped_motion_.Wait(); 283 same_tab_observer.Wait(); 284 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); 285} 286 287} // namespace 288 289} // namespace content 290