diff --git a/content/browser/device_sensors/device_sensor_browsertest.cc b/content/browser/device_sensors/device_sensor_browsertest.cc index 971fc6c605b2bf..ef16d3810c3445 100644 --- a/content/browser/device_sensors/device_sensor_browsertest.cc +++ b/content/browser/device_sensors/device_sensor_browsertest.cc @@ -17,8 +17,6 @@ #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_javascript_dialog_manager.h" -#include "device/generic_sensor/platform_sensor.h" -#include "device/generic_sensor/platform_sensor_provider.h" #include "device/sensors/data_fetcher_shared_memory.h" #include "device/sensors/device_sensor_service.h" #include "device/sensors/public/cpp/device_motion_hardware_buffer.h" @@ -33,6 +31,14 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { FakeDataFetcher() : sensor_data_available_(true) {} ~FakeDataFetcher() override {} + void SetMotionStartedCallback(base::Closure motion_started_callback) { + motion_started_callback_ = motion_started_callback; + } + + void SetMotionStoppedCallback(base::Closure motion_stopped_callback) { + motion_stopped_callback_ = motion_stopped_callback; + } + void SetOrientationStartedCallback( base::Closure orientation_started_callback) { orientation_started_callback_ = orientation_started_callback; @@ -59,6 +65,15 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { EXPECT_TRUE(buffer); switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: { + device::DeviceMotionHardwareBuffer* motion_buffer = + static_cast(buffer); + if (sensor_data_available_) + UpdateMotion(motion_buffer); + SetMotionBufferReady(motion_buffer); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_started_callback_); + } break; case device::CONSUMER_TYPE_ORIENTATION: { device::DeviceOrientationHardwareBuffer* orientation_buffer = static_cast(buffer); @@ -85,6 +100,10 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { bool Stop(device::ConsumerType consumer_type) override { switch (consumer_type) { + case device::CONSUMER_TYPE_MOTION: + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + motion_stopped_callback_); + break; case device::CONSUMER_TYPE_ORIENTATION: BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, orientation_stopped_callback_); @@ -109,6 +128,12 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { sensor_data_available_ = available; } + void SetMotionBufferReady(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void SetOrientationBufferReady( device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); @@ -116,6 +141,34 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { buffer->seqlock.WriteEnd(); } + void UpdateMotion(device::DeviceMotionHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.acceleration_x = 1; + buffer->data.has_acceleration_x = true; + buffer->data.acceleration_y = 2; + buffer->data.has_acceleration_y = true; + buffer->data.acceleration_z = 3; + buffer->data.has_acceleration_z = true; + + buffer->data.acceleration_including_gravity_x = 4; + buffer->data.has_acceleration_including_gravity_x = true; + buffer->data.acceleration_including_gravity_y = 5; + buffer->data.has_acceleration_including_gravity_y = true; + buffer->data.acceleration_including_gravity_z = 6; + buffer->data.has_acceleration_including_gravity_z = true; + + buffer->data.rotation_rate_alpha = 7; + buffer->data.has_rotation_rate_alpha = true; + buffer->data.rotation_rate_beta = 8; + buffer->data.has_rotation_rate_beta = true; + buffer->data.rotation_rate_gamma = 9; + buffer->data.has_rotation_rate_gamma = true; + + buffer->data.interval = 100; + buffer->data.all_available_sensors_are_active = true; + buffer->seqlock.WriteEnd(); + } + void UpdateOrientation(device::DeviceOrientationHardwareBuffer* buffer) { buffer->seqlock.WriteBegin(); buffer->data.alpha = 1; @@ -143,8 +196,10 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { } // The below callbacks should be run on the UI thread. + base::Closure motion_started_callback_; base::Closure orientation_started_callback_; base::Closure orientation_absolute_started_callback_; + base::Closure motion_stopped_callback_; base::Closure orientation_stopped_callback_; base::Closure orientation_absolute_stopped_callback_; bool sensor_data_available_; @@ -153,187 +208,6 @@ class FakeDataFetcher : public device::DataFetcherSharedMemory { DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); }; -class FakeAccelerometer : public device::PlatformSensor { - public: - FakeAccelerometer(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::ACCELEROMETER, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::ON_CHANGE; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 4; - reading.values[1] = 5; - reading.values[2] = 6; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeAccelerometer() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeAccelerometer); -}; - -class FakeLinearAccelerationSensor : public device::PlatformSensor { - public: - FakeLinearAccelerationSensor(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::LINEAR_ACCELERATION, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::CONTINUOUS; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 1; - reading.values[1] = 2; - reading.values[2] = 3; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeLinearAccelerationSensor() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeLinearAccelerationSensor); -}; - -class FakeGyroscope : public device::PlatformSensor { - public: - FakeGyroscope(mojo::ScopedSharedBufferMapping mapping, - device::PlatformSensorProvider* provider) - : PlatformSensor(device::mojom::SensorType::GYROSCOPE, - std::move(mapping), - provider) {} - - device::mojom::ReportingMode GetReportingMode() override { - return device::mojom::ReportingMode::ON_CHANGE; - } - - bool StartSensor( - const device::PlatformSensorConfiguration& configuration) override { - device::SensorReading reading; - reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - reading.values[0] = 7; - reading.values[1] = 8; - reading.values[2] = 9; - UpdateSensorReading(reading, true); - return true; - } - - void StopSensor() override {} - - protected: - ~FakeGyroscope() override = default; - - bool CheckSensorConfiguration( - const device::PlatformSensorConfiguration& configuration) override { - return true; - } - - device::PlatformSensorConfiguration GetDefaultConfiguration() override { - return device::PlatformSensorConfiguration(60 /* frequency */); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FakeGyroscope); -}; - -class FakeSensorProvider : public device::PlatformSensorProvider { - public: - static FakeSensorProvider* GetInstance() { - return base::Singleton>::get(); - } - FakeSensorProvider() {} - ~FakeSensorProvider() override = default; - - void set_accelerometer_is_available(bool accelerometer_is_available) { - accelerometer_is_available_ = accelerometer_is_available; - } - - void set_linear_acceleration_sensor_is_available( - bool linear_acceleration_sensor_is_available) { - linear_acceleration_sensor_is_available_ = - linear_acceleration_sensor_is_available; - } - - void set_gyroscope_is_available(bool gyroscope_is_available) { - gyroscope_is_available_ = gyroscope_is_available; - } - - protected: - void CreateSensorInternal(device::mojom::SensorType type, - mojo::ScopedSharedBufferMapping mapping, - const CreateSensorCallback& callback) override { - // Create Sensors here. - scoped_refptr sensor; - - switch (type) { - case device::mojom::SensorType::ACCELEROMETER: - if (accelerometer_is_available_) - sensor = new FakeAccelerometer(std::move(mapping), this); - break; - case device::mojom::SensorType::LINEAR_ACCELERATION: - if (linear_acceleration_sensor_is_available_) - sensor = new FakeLinearAccelerationSensor(std::move(mapping), this); - break; - case device::mojom::SensorType::GYROSCOPE: - if (gyroscope_is_available_) - sensor = new FakeGyroscope(std::move(mapping), this); - break; - default: - NOTIMPLEMENTED(); - } - - callback.Run(std::move(sensor)); - } - - bool accelerometer_is_available_ = true; - bool linear_acceleration_sensor_is_available_ = true; - bool gyroscope_is_available_ = true; -}; - class DeviceSensorBrowserTest : public ContentBrowserTest { public: DeviceSensorBrowserTest() @@ -344,6 +218,8 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { void SetUpOnMainThread() override { // Initialize the RunLoops now that the main thread has been created. + motion_started_runloop_.reset(new base::RunLoop()); + motion_stopped_runloop_.reset(new base::RunLoop()); orientation_started_runloop_.reset(new base::RunLoop()); orientation_stopped_runloop_.reset(new base::RunLoop()); orientation_absolute_started_runloop_.reset(new base::RunLoop()); @@ -351,16 +227,20 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { #if defined(OS_ANDROID) // On Android, the DeviceSensorService lives on the UI thread. SetUpFetcher(); -#endif // defined(OS_ANDROID) +#else + // On all other platforms, the DeviceSensorService lives on the IO thread. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&DeviceSensorBrowserTest::SetUpOnIOThread, base::Unretained(this))); io_loop_finished_event_.Wait(); +#endif } void SetUpFetcher() { fetcher_ = new FakeDataFetcher(); + fetcher_->SetMotionStartedCallback(motion_started_runloop_->QuitClosure()); + fetcher_->SetMotionStoppedCallback(motion_stopped_runloop_->QuitClosure()); fetcher_->SetOrientationStartedCallback( orientation_started_runloop_->QuitClosure()); fetcher_->SetOrientationStoppedCallback( @@ -374,19 +254,10 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { } void SetUpOnIOThread() { -#if !defined(OS_ANDROID) - // On non-Android platforms, the DeviceSensorService lives on the IO thread. SetUpFetcher(); -#endif // !defined(OS_ANDROID) - sensor_provider_ = FakeSensorProvider::GetInstance(); - device::PlatformSensorProvider::SetProviderForTesting(sensor_provider_); io_loop_finished_event_.Signal(); } - void TearDown() override { - device::PlatformSensorProvider::SetProviderForTesting(nullptr); - } - void DelayAndQuit(base::TimeDelta delay) { base::PlatformThread::Sleep(delay); base::MessageLoop::current()->QuitWhenIdle(); @@ -405,10 +276,11 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { } FakeDataFetcher* fetcher_; - FakeSensorProvider* sensor_provider_; // NOTE: These can only be initialized once the main thread has been created // and so must be pointers instead of plain objects. + std::unique_ptr motion_started_runloop_; + std::unique_ptr motion_stopped_runloop_; std::unique_ptr orientation_started_runloop_; std::unique_ptr orientation_stopped_runloop_; std::unique_ptr orientation_absolute_started_runloop_; @@ -451,6 +323,8 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionTest) { NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationNullTest) { @@ -485,27 +359,13 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionNullTest) { // The test page registers an event handler for motion events and // expects to get an event with null values, because no sensor data can be // provided. - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); + fetcher_->SetSensorDataAvailable(false); GURL test_url = GetTestUrl("device_sensors", "device_motion_null_test.html"); NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); -} - -IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, - MotionOnlySomeSensorsAreAvailableTest) { - // The test page registers an event handler for motion events and - // expects to get an event with only the gyroscope and linear acceleration - // sensor values, because no accelerometer values can be provided. - sensor_provider_->set_accelerometer_is_available(false); - GURL test_url = - GetTestUrl("device_sensors", - "device_motion_only_some_sensors_are_available_test.html"); - NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); - - EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); } IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) { @@ -515,9 +375,6 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) { // window after the alert is dismissed and the callbacks are invoked which // eventually navigate to #pass. fetcher_->SetSensorDataAvailable(false); - sensor_provider_->set_accelerometer_is_available(false); - sensor_provider_->set_linear_acceleration_sensor_is_available(false); - sensor_provider_->set_gyroscope_is_available(false); TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); GURL test_url = @@ -528,6 +385,8 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) { // delay, crbug.com/360044. WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(500)); + motion_started_runloop_->Run(); + motion_stopped_runloop_->Run(); orientation_started_runloop_->Run(); orientation_stopped_runloop_->Run(); same_tab_observer.Wait(); diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 3d5b36b53d7037..7bf5386c20dc66 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn @@ -458,7 +458,6 @@ target(link_target_type, "renderer") { "//device/base/synchronization", "//device/gamepad/public/cpp:shared_with_blink", "//device/gamepad/public/interfaces", - "//device/generic_sensor/public/cpp", "//device/screen_orientation/public/interfaces", "//device/sensors/public/cpp:full", "//device/sensors/public/interfaces", diff --git a/content/renderer/DEPS b/content/renderer/DEPS index 0c3962abce8259..54e6e7bbe9e464 100644 --- a/content/renderer/DEPS +++ b/content/renderer/DEPS @@ -18,8 +18,6 @@ include_rules = [ "+device/base/synchronization", "+device/gamepad/public/cpp", "+device/gamepad/public/interfaces", - "+device/generic_sensor/public/cpp", - "+device/generic_sensor/public/interfaces", "+device/screen_orientation/public/interfaces", "+device/sensors/public", "+device/usb/public", diff --git a/content/renderer/device_sensors/device_motion_event_pump.cc b/content/renderer/device_sensors/device_motion_event_pump.cc index 240ca24fe9cf4d..94d7f3f7b1e5d8 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.cc +++ b/content/renderer/device_sensors/device_motion_event_pump.cc @@ -2,328 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/device_sensors/device_motion_event_pump.h" +#include "device_motion_event_pump.h" -#include "base/memory/ptr_util.h" -#include "content/public/common/service_names.mojom.h" #include "content/public/renderer/render_thread.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/device/public/interfaces/constants.mojom.h" -#include "services/service_manager/public/cpp/connector.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" -namespace { - -constexpr int kMaxReadAttemptsCount = 10; - -// TODO(juncai): Extracting mojo::ScopedSharedBufferMapping reading -// functionality into a helper class. -// http://crbug.com/727788 -bool TryReadFromBuffer(const device::SensorReadingSharedBuffer* buffer, - device::SensorReading* result) { - const device::OneWriterSeqLock& seqlock = buffer->seqlock.value(); - auto version = seqlock.ReadBegin(); - auto reading_data = buffer->reading; - if (seqlock.ReadRetry(version)) - return false; - *result = reading_data; - return true; -} - -// Updates sensor reading from shared buffer. -bool UpdateSensorReading(const device::SensorReadingSharedBuffer* buffer, - device::SensorReading* result) { - int read_attempts = 0; - while (!TryReadFromBuffer(buffer, result)) { - if (++read_attempts == kMaxReadAttemptsCount) - return false; - } - - return true; -} - -} // namespace - namespace content { DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread) - : PlatformEventObserver(thread), - accelerometer_(this, device::mojom::SensorType::ACCELEROMETER), - linear_acceleration_sensor_( - this, - device::mojom::SensorType::LINEAR_ACCELERATION), - gyroscope_(this, device::mojom::SensorType::GYROSCOPE), - state_(PumpState::STOPPED) {} + : DeviceSensorMojoClientMixin< + DeviceSensorEventPump, + device::mojom::MotionSensor>(thread) {} DeviceMotionEventPump::~DeviceMotionEventPump() { - PlatformEventObserver::StopIfObserving(); -} - -void DeviceMotionEventPump::Start(blink::WebPlatformEventListener* listener) { - DVLOG(2) << "requested start"; - - if (state_ != PumpState::STOPPED) - return; - - DCHECK(!timer_.IsRunning()); - - state_ = PumpState::PENDING_START; - PlatformEventObserver::Start(listener); -} - -void DeviceMotionEventPump::Stop() { - DVLOG(2) << "requested stop"; - - if (state_ == PumpState::STOPPED) - return; - - DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) || - (state_ == PumpState::RUNNING && timer_.IsRunning())); - - if (timer_.IsRunning()) - timer_.Stop(); - - PlatformEventObserver::Stop(); - state_ = PumpState::STOPPED; } -void DeviceMotionEventPump::SendStartMessage() { - auto request = mojo::MakeRequest(&sensor_provider_); - - // When running layout tests, those observers should not listen to the - // actual hardware changes. In order to make that happen, don't connect - // the other end of the mojo pipe to anything. - if (!RenderThreadImpl::current() || - RenderThreadImpl::current()->layout_test_mode()) { - return; - } - - if (!accelerometer_.sensor && !linear_acceleration_sensor_.sensor && - !gyroscope_.sensor) { - RenderThread::Get()->GetConnector()->BindInterface( - device::mojom::kServiceName, std::move(request)); - sensor_provider_.set_connection_error_handler( - base::Bind(&DeviceMotionEventPump::HandleSensorProviderError, - base::Unretained(this))); - GetSensor(&accelerometer_); - GetSensor(&linear_acceleration_sensor_); - GetSensor(&gyroscope_); - } else { - if (accelerometer_.sensor) - accelerometer_.sensor->Resume(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Resume(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Resume(); - - DidStart(); - } +void DeviceMotionEventPump::FireEvent() { + DCHECK(listener()); + device::MotionData data; + if (reader_->GetLatestData(&data) && data.all_available_sensors_are_active) + listener()->DidChangeDeviceMotion(data); } -void DeviceMotionEventPump::SendStopMessage() { - // SendStopMessage() gets called both when the page visibility changes and if - // all device motion event listeners are unregistered. Since removing the - // event listener is more rare than the page visibility changing, - // Sensor::Suspend() is used to optimize this case for not doing extra work. - if (accelerometer_.sensor) - accelerometer_.sensor->Suspend(); - - if (linear_acceleration_sensor_.sensor) - linear_acceleration_sensor_.sensor->Suspend(); - - if (gyroscope_.sensor) - gyroscope_.sensor->Suspend(); +bool DeviceMotionEventPump::InitializeReader(base::SharedMemoryHandle handle) { + if (!reader_) + reader_.reset(new DeviceMotionSharedMemoryReader()); + return reader_->Initialize(handle); } void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) { device::MotionData data = *static_cast(fake_data); - listener()->DidChangeDeviceMotion(data); -} - -DeviceMotionEventPump::SensorEntry::SensorEntry( - DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type) - : event_pump(pump), type(sensor_type), client_binding(this) {} - -DeviceMotionEventPump::SensorEntry::~SensorEntry() {} - -void DeviceMotionEventPump::SensorEntry::RaiseError() { - HandleSensorError(); -} - -void DeviceMotionEventPump::SensorEntry::SensorReadingChanged() { - // Since DeviceMotionEventPump::FireEvent is called in a certain - // frequency, the |shared_buffer| is read frequently, and - // PlatformSensorConfiguration::set_suppress_on_change_events() - // is set to true, so this method is not called and doesn't need - // to be implemented. - NOTREACHED(); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorCreated( - device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request) { - if (!params) { - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); - return; - } - - constexpr size_t kReadBufferSize = sizeof(device::SensorReadingSharedBuffer); - - DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize); - mode = params->mode; - default_config = params->default_configuration; - - DCHECK(sensor.is_bound()); - client_binding.Bind(std::move(client_request)); - - shared_buffer_handle = std::move(params->memory); - DCHECK(!shared_buffer); - shared_buffer = - shared_buffer_handle->MapAtOffset(kReadBufferSize, params->buffer_offset); - - if (!shared_buffer) { - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); - return; - } - - DCHECK_GT(params->minimum_frequency, 0.0); - DCHECK_GE(params->maximum_frequency, params->minimum_frequency); - DCHECK_GE(device::mojom::SensorConfiguration::kMaxAllowedFrequency, - params->maximum_frequency); - - default_config.set_frequency(kDefaultPumpFrequencyHz); - default_config.set_suppress_on_change_events(true); - - sensor->AddConfiguration(default_config, - base::Bind(&SensorEntry::OnSensorAddConfiguration, - base::Unretained(this))); -} - -void DeviceMotionEventPump::SensorEntry::OnSensorAddConfiguration( - bool success) { - if (!success) - HandleSensorError(); - if (event_pump->CanStart()) - event_pump->DidStart(); -} - -void DeviceMotionEventPump::SensorEntry::HandleSensorError() { - sensor.reset(); - shared_buffer_handle.reset(); - shared_buffer.reset(); - client_binding.Close(); -} - -bool DeviceMotionEventPump::SensorEntry::SensorReadingCouldBeRead() { - if (!sensor) - return false; - - const device::SensorReadingSharedBuffer* buffer = - static_cast( - shared_buffer.get()); - if (!UpdateSensorReading(buffer, &reading)) { - HandleSensorError(); - return false; - } - - return true; -} - -void DeviceMotionEventPump::FireEvent() { - device::MotionData data; - // The device orientation spec states that interval should be in milliseconds. - // https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion - data.interval = kDefaultPumpDelayMicroseconds / 1000; - - DCHECK(listener()); - - GetDataFromSharedMemory(&data); listener()->DidChangeDeviceMotion(data); } -void DeviceMotionEventPump::DidStart() { - DVLOG(2) << "did start sensor event pump"; - - if (state_ != PumpState::PENDING_START) - return; - - DCHECK(!timer_.IsRunning()); - - timer_.Start(FROM_HERE, - base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds), - this, &DeviceMotionEventPump::FireEvent); - state_ = PumpState::RUNNING; -} - -bool DeviceMotionEventPump::CanStart() const { - if (accelerometer_.sensor && !accelerometer_.shared_buffer) - return false; - - if (linear_acceleration_sensor_.sensor && - !linear_acceleration_sensor_.shared_buffer) { - return false; - } - - if (gyroscope_.sensor && !gyroscope_.shared_buffer) - return false; - - return true; -} - -void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) { - if (accelerometer_.SensorReadingCouldBeRead()) { - data->acceleration_including_gravity_x = - accelerometer_.reading.values[0].value(); - data->acceleration_including_gravity_y = - accelerometer_.reading.values[1].value(); - data->acceleration_including_gravity_z = - accelerometer_.reading.values[2].value(); - data->has_acceleration_including_gravity_x = true; - data->has_acceleration_including_gravity_y = true; - data->has_acceleration_including_gravity_z = true; - } - - if (linear_acceleration_sensor_.SensorReadingCouldBeRead()) { - data->acceleration_x = - linear_acceleration_sensor_.reading.values[0].value(); - data->acceleration_y = - linear_acceleration_sensor_.reading.values[1].value(); - data->acceleration_z = - linear_acceleration_sensor_.reading.values[2].value(); - data->has_acceleration_x = true; - data->has_acceleration_y = true; - data->has_acceleration_z = true; - } - - if (gyroscope_.SensorReadingCouldBeRead()) { - data->rotation_rate_alpha = gyroscope_.reading.values[0].value(); - data->rotation_rate_beta = gyroscope_.reading.values[1].value(); - data->rotation_rate_gamma = gyroscope_.reading.values[2].value(); - data->has_rotation_rate_alpha = true; - data->has_rotation_rate_beta = true; - data->has_rotation_rate_gamma = true; - } -} - -void DeviceMotionEventPump::GetSensor(SensorEntry* sensor_entry) { - auto request = mojo::MakeRequest(&sensor_entry->sensor); - sensor_provider_->GetSensor(sensor_entry->type, std::move(request), - base::Bind(&SensorEntry::OnSensorCreated, - base::Unretained(sensor_entry))); - sensor_entry->sensor.set_connection_error_handler(base::Bind( - &SensorEntry::HandleSensorError, base::Unretained(sensor_entry))); -} - -void DeviceMotionEventPump::HandleSensorProviderError() { - sensor_provider_.reset(); -} - } // namespace content diff --git a/content/renderer/device_sensors/device_motion_event_pump.h b/content/renderer/device_sensors/device_motion_event_pump.h index 5089aff19a6fe1..5846db199bb8a2 100644 --- a/content/renderer/device_sensors/device_motion_event_pump.h +++ b/content/renderer/device_sensors/device_motion_event_pump.h @@ -6,105 +6,38 @@ #define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_ #include -#include -#include -#include "base/bind.h" -#include "base/bind_helpers.h" #include "base/macros.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "content/public/renderer/platform_event_observer.h" -#include "content/renderer/render_thread_impl.h" -#include "device/generic_sensor/public/cpp/sensor_reading.h" -#include "device/generic_sensor/public/interfaces/sensor.mojom.h" -#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" +#include "content/renderer/device_sensors/device_sensor_event_pump.h" +#include "content/renderer/shared_memory_seqlock_reader.h" #include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" +#include "device/sensors/public/interfaces/motion.mojom.h" + +namespace blink { +class WebDeviceMotionListener; +} namespace content { +typedef SharedMemorySeqLockReader + DeviceMotionSharedMemoryReader; + class CONTENT_EXPORT DeviceMotionEventPump - : NON_EXPORTED_BASE( - public PlatformEventObserver) { + : public DeviceSensorMojoClientMixin< + DeviceSensorEventPump, + device::mojom::MotionSensor> { public: explicit DeviceMotionEventPump(RenderThread* thread); ~DeviceMotionEventPump() override; - // PlatformEventObserver: - void Start(blink::WebPlatformEventListener* listener) override; - void Stop() override; - void SendStartMessage() override; - void SendStopMessage() override; + // PlatformEventObserver. void SendFakeDataForTesting(void* fake_data) override; protected: - // Default rate for firing events. - static constexpr int kDefaultPumpFrequencyHz = 60; - static constexpr int kDefaultPumpDelayMicroseconds = - base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz; - - struct CONTENT_EXPORT SensorEntry : public device::mojom::SensorClient { - SensorEntry(DeviceMotionEventPump* pump, - device::mojom::SensorType sensor_type); - ~SensorEntry() override; - - // device::mojom::SensorClient: - void RaiseError() override; - void SensorReadingChanged() override; - - // Mojo callback for SensorProvider::GetSensor(). - void OnSensorCreated(device::mojom::SensorInitParamsPtr params, - device::mojom::SensorClientRequest client_request); - - // Mojo callback for Sensor::AddConfiguration(). - void OnSensorAddConfiguration(bool success); - - void HandleSensorError(); - - bool SensorReadingCouldBeRead(); - - DeviceMotionEventPump* event_pump; - device::mojom::SensorPtr sensor; - device::mojom::SensorType type; - device::mojom::ReportingMode mode; - device::PlatformSensorConfiguration default_config; - mojo::ScopedSharedBufferHandle shared_buffer_handle; - mojo::ScopedSharedBufferMapping shared_buffer; - device::SensorReading reading; - mojo::Binding client_binding; - }; - - friend struct SensorEntry; - - virtual void FireEvent(); - - void DidStart(); - - SensorEntry accelerometer_; - SensorEntry linear_acceleration_sensor_; - SensorEntry gyroscope_; - - private: - // TODO(juncai): refactor DeviceMotionEventPump to use DeviceSensorEventPump - // when refactoring DeviceOrientation. - // - // The pump is a tri-state automaton with allowed transitions as follows: - // STOPPED -> PENDING_START - // PENDING_START -> RUNNING - // PENDING_START -> STOPPED - // RUNNING -> STOPPED - enum class PumpState { STOPPED, RUNNING, PENDING_START }; - - bool CanStart() const; - void GetDataFromSharedMemory(device::MotionData* data); - void GetSensor(SensorEntry* sensor_entry); - void HandleSensorProviderError(); + void FireEvent() override; + bool InitializeReader(base::SharedMemoryHandle handle) override; - mojo::InterfacePtr sensor_provider_; - PumpState state_; - base::RepeatingTimer timer_; + std::unique_ptr reader_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump); }; diff --git a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc index 00a82fdf839cec..a87462441ecdef 100644 --- a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc +++ b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc @@ -11,32 +11,16 @@ #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "content/public/test/test_utils.h" -#include "device/generic_sensor/public/cpp/sensor_reading.h" -#include "device/generic_sensor/public/interfaces/sensor.mojom.h" -#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h" -#include "device/sensors/public/cpp/motion_data.h" -#include "mojo/public/cpp/bindings/interface_request.h" +#include "device/sensors/public/cpp/device_motion_hardware_buffer.h" #include "mojo/public/cpp/system/buffer.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h" -namespace { - -constexpr uint64_t kReadingBufferSize = - sizeof(device::SensorReadingSharedBuffer); - -constexpr uint64_t kSharedBufferSizeInBytes = - kReadingBufferSize * static_cast(device::mojom::SensorType::LAST); - -} // namespace - namespace content { class MockDeviceMotionListener : public blink::WebDeviceMotionListener { @@ -72,94 +56,22 @@ class MockDeviceMotionListener : public blink::WebDeviceMotionListener { class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { public: DeviceMotionEventPumpForTesting() - : DeviceMotionEventPump(nullptr), stop_on_fire_event_(true) {} + : DeviceMotionEventPump(0), stop_on_fire_event_(true) {} ~DeviceMotionEventPumpForTesting() override {} - // DeviceMotionEventPump: - void SendStartMessage() override { - accelerometer_.mode = device::mojom::ReportingMode::CONTINUOUS; - linear_acceleration_sensor_.mode = device::mojom::ReportingMode::ON_CHANGE; - gyroscope_.mode = device::mojom::ReportingMode::CONTINUOUS; - - shared_memory_ = mojo::SharedBufferHandle::Create(kSharedBufferSizeInBytes); - - accelerometer_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(accelerometer_.type)); - accelerometer_buffer_ = static_cast( - accelerometer_.shared_buffer.get()); - - linear_acceleration_sensor_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, device::SensorReadingSharedBuffer::GetOffset( - linear_acceleration_sensor_.type)); - linear_acceleration_sensor_buffer_ = - static_cast( - linear_acceleration_sensor_.shared_buffer.get()); - - gyroscope_.shared_buffer = shared_memory_->MapAtOffset( - kReadingBufferSize, - device::SensorReadingSharedBuffer::GetOffset(gyroscope_.type)); - gyroscope_buffer_ = static_cast( - gyroscope_.shared_buffer.get()); - } - - void StartFireEvent() { DeviceMotionEventPump::DidStart(); } - - void SetAccelerometerSensorData(bool active, - double d0, - double d1, - double d2) { - if (active) { - mojo::MakeRequest(&accelerometer_.sensor); - accelerometer_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - accelerometer_buffer_->reading.values[0].value() = d0; - accelerometer_buffer_->reading.values[1].value() = d1; - accelerometer_buffer_->reading.values[2].value() = d2; - } else { - accelerometer_.sensor.reset(); - } - } - - void SetLinearAccelerationSensorData(bool active, - double d0, - double d1, - double d2) { - if (active) { - mojo::MakeRequest(&linear_acceleration_sensor_.sensor); - linear_acceleration_sensor_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - linear_acceleration_sensor_buffer_->reading.values[0].value() = d0; - linear_acceleration_sensor_buffer_->reading.values[1].value() = d1; - linear_acceleration_sensor_buffer_->reading.values[2].value() = d2; - } else { - linear_acceleration_sensor_.sensor.reset(); - } - } - - void SetGyroscopeSensorData(bool active, double d0, double d1, double d2) { - if (active) { - mojo::MakeRequest(&gyroscope_.sensor); - gyroscope_buffer_->reading.timestamp = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - gyroscope_buffer_->reading.values[0].value() = d0; - gyroscope_buffer_->reading.values[1].value() = d1; - gyroscope_buffer_->reading.values[2].value() = d2; - } else { - gyroscope_.sensor.reset(); - } - } - void set_stop_on_fire_event(bool stop_on_fire_event) { stop_on_fire_event_ = stop_on_fire_event; } bool stop_on_fire_event() { return stop_on_fire_event_; } - int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; } + int pump_delay_microseconds() const { return pump_delay_microseconds_; } - protected: - // DeviceMotionEventPump: + void DidStart(mojo::ScopedSharedBufferHandle renderer_handle) { + DeviceMotionEventPump::DidStart(std::move(renderer_handle)); + } + void SendStartMessage() override {} + void SendStopMessage() override {} void FireEvent() override { DeviceMotionEventPump::FireEvent(); if (stop_on_fire_event_) { @@ -170,10 +82,6 @@ class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { private: bool stop_on_fire_event_; - mojo::ScopedSharedBufferHandle shared_memory_; - device::SensorReadingSharedBuffer* accelerometer_buffer_; - device::SensorReadingSharedBuffer* linear_acceleration_sensor_buffer_; - device::SensorReadingSharedBuffer* gyroscope_buffer_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); }; @@ -185,102 +93,90 @@ class DeviceMotionEventPumpTest : public testing::Test { protected: void SetUp() override { listener_.reset(new MockDeviceMotionListener); - motion_pump_.reset(new DeviceMotionEventPumpForTesting()); + motion_pump_.reset(new DeviceMotionEventPumpForTesting); + shared_memory_ = mojo::SharedBufferHandle::Create( + sizeof(device::DeviceMotionHardwareBuffer)); + mapping_ = shared_memory_->Map(sizeof(device::DeviceMotionHardwareBuffer)); + ASSERT_TRUE(mapping_); + memset(buffer(), 0, sizeof(device::DeviceMotionHardwareBuffer)); + } + + void InitBuffer(bool allAvailableSensorsActive) { + device::MotionData& data = buffer()->data; + data.acceleration_x = 1; + data.has_acceleration_x = true; + data.acceleration_y = 2; + data.has_acceleration_y = true; + data.acceleration_z = 3; + data.has_acceleration_z = true; + data.all_available_sensors_are_active = allAvailableSensorsActive; } MockDeviceMotionListener* listener() { return listener_.get(); } DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); } + mojo::ScopedSharedBufferHandle handle() { + return shared_memory_->Clone( + mojo::SharedBufferHandle::AccessMode::READ_ONLY); + } + device::DeviceMotionHardwareBuffer* buffer() { + return reinterpret_cast( + mapping_.get()); + } private: base::MessageLoop loop_; std::unique_ptr listener_; std::unique_ptr motion_pump_; + mojo::ScopedSharedBufferHandle shared_memory_; + mojo::ScopedSharedBufferMapping mapping_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); }; -TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { +TEST_F(DeviceMotionEventPumpTest, DidStartPolling) { + InitBuffer(true); + motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); + motion_pump()->DidStart(handle()); base::RunLoop().Run(); - device::MotionData received_data = listener()->data(); + const device::MotionData& received_data = listener()->data(); EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); - EXPECT_TRUE(received_data.has_acceleration_x); - EXPECT_EQ(4, received_data.acceleration_x); + EXPECT_EQ(1, static_cast(received_data.acceleration_x)); + EXPECT_TRUE(received_data.has_acceleration_x); + EXPECT_EQ(2, static_cast(received_data.acceleration_y)); EXPECT_TRUE(received_data.has_acceleration_y); - EXPECT_EQ(5, received_data.acceleration_y); + EXPECT_EQ(3, static_cast(received_data.acceleration_z)); EXPECT_TRUE(received_data.has_acceleration_z); - EXPECT_EQ(6, received_data.acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); + EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); + EXPECT_FALSE(received_data.has_rotation_rate_alpha); + EXPECT_FALSE(received_data.has_rotation_rate_beta); + EXPECT_FALSE(received_data.has_rotation_rate_gamma); } -TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { - motion_pump()->Start(listener()); - motion_pump()->SetAccelerometerSensorData(true /* active */, 1, 2, 3); - motion_pump()->SetLinearAccelerationSensorData(false /* active */, 4, 5, 6); - motion_pump()->SetGyroscopeSensorData(true /* active */, 7, 8, 9); - motion_pump()->StartFireEvent(); - - base::RunLoop().Run(); - - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - EXPECT_TRUE(received_data.has_acceleration_including_gravity_x); - EXPECT_EQ(1, received_data.acceleration_including_gravity_x); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_y); - EXPECT_EQ(2, received_data.acceleration_including_gravity_y); - EXPECT_TRUE(received_data.has_acceleration_including_gravity_z); - EXPECT_EQ(3, received_data.acceleration_including_gravity_z); +TEST_F(DeviceMotionEventPumpTest, DidStartPollingNotAllSensorsActive) { + InitBuffer(false); - EXPECT_FALSE(received_data.has_acceleration_x); - EXPECT_FALSE(received_data.has_acceleration_y); - EXPECT_FALSE(received_data.has_acceleration_z); - - EXPECT_TRUE(received_data.has_rotation_rate_alpha); - EXPECT_EQ(7, received_data.rotation_rate_alpha); - EXPECT_TRUE(received_data.has_rotation_rate_beta); - EXPECT_EQ(8, received_data.rotation_rate_beta); - EXPECT_TRUE(received_data.has_rotation_rate_gamma); - EXPECT_EQ(9, received_data.rotation_rate_gamma); -} - -TEST_F(DeviceMotionEventPumpTest, NoActiveSensors) { motion_pump()->Start(listener()); - motion_pump()->StartFireEvent(); + motion_pump()->DidStart(handle()); base::RunLoop().Run(); - device::MotionData received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); - + const device::MotionData& received_data = listener()->data(); + // No change in device motion because all_available_sensors_are_active is + // false. + EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(received_data.has_acceleration_x); EXPECT_FALSE(received_data.has_acceleration_x); EXPECT_FALSE(received_data.has_acceleration_y); EXPECT_FALSE(received_data.has_acceleration_z); - EXPECT_FALSE(received_data.has_acceleration_including_gravity_x); EXPECT_FALSE(received_data.has_acceleration_including_gravity_y); EXPECT_FALSE(received_data.has_acceleration_including_gravity_z); - EXPECT_FALSE(received_data.has_rotation_rate_alpha); EXPECT_FALSE(received_data.has_rotation_rate_beta); EXPECT_FALSE(received_data.has_rotation_rate_gamma); @@ -293,11 +189,11 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) { EXPECT_GE(60, base::Time::kMicrosecondsPerSecond / motion_pump()->pump_delay_microseconds()); - motion_pump()->Start(listener()); - motion_pump()->SetLinearAccelerationSensorData(true /* active */, 4, 5, 6); + InitBuffer(true); motion_pump()->set_stop_on_fire_event(false); - motion_pump()->StartFireEvent(); + motion_pump()->Start(listener()); + motion_pump()->DidStart(handle()); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 42b77b37fa8d59..383aab478a0511 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn @@ -1530,7 +1530,6 @@ test("content_unittests") { "//device/gamepad", "//device/gamepad:test_helpers", "//device/gamepad/public/cpp:shared_with_blink", - "//device/generic_sensor/public/cpp", "//device/sensors/public/cpp:full", "//device/sensors/public/interfaces", "//gin", diff --git a/content/test/DEPS b/content/test/DEPS index a756522471e1be..74d97976958355 100644 --- a/content/test/DEPS +++ b/content/test/DEPS @@ -12,7 +12,6 @@ include_rules = [ "+content", "+device/bluetooth", # For WebBluetooth tests "+device/gamepad/public/cpp", - "+device/generic_sensor/public/cpp", "+device/sensors/public/cpp", # For loading V8's initial snapshot from external files. "+gin/v8_initializer.h", diff --git a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html b/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html deleted file mode 100644 index b0286e70781e69..00000000000000 --- a/content/test/data/device_sensors/device_motion_only_some_sensors_are_available_test.html +++ /dev/null @@ -1,41 +0,0 @@ - - - DeviceMotion only some sensors are available test - - - -
FAIL
- - diff --git a/content/test/data/device_sensors/device_motion_test.html b/content/test/data/device_sensors/device_motion_test.html index e98aa404acf0c0..11b4e05df1bb0d 100644 --- a/content/test/data/device_sensors/device_motion_test.html +++ b/content/test/data/device_sensors/device_motion_test.html @@ -2,7 +2,6 @@ DeviceMotion test