Commit 63316560 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

Move global binder overrides before browser thread initialization

The structure that tracks global binder overrides is not thread-safe.
This is fine because these overrides should be static for the life of
the browser. Some tests however configured these overrides after the
browser threads were started which the thread sanitizer complains about.

Bug: 853907
Change-Id: Ibf282aa403be37639261dab66c9c73a99b6fb767
Reviewed-on: https://chromium-review.googlesource.com/1121588Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574008}
parent 65dbbf54
...@@ -93,7 +93,11 @@ class BluetoothHostPairingNoInputTest : public OobeBaseTest { ...@@ -93,7 +93,11 @@ class BluetoothHostPairingNoInputTest : public OobeBaseTest {
static_cast<bluez::FakeBluetoothDeviceClient*>( static_cast<bluez::FakeBluetoothDeviceClient*>(
bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()); bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
} }
~BluetoothHostPairingNoInputTest() override {}
~BluetoothHostPairingNoInputTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
// OobeBaseTest override: // OobeBaseTest override:
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
......
...@@ -57,9 +57,10 @@ class HidDetectionTest : public OobeBaseTest { ...@@ -57,9 +57,10 @@ class HidDetectionTest : public OobeBaseTest {
base::Unretained(fake_input_service_manager_.get()))); base::Unretained(fake_input_service_manager_.get())));
} }
~HidDetectionTest() override {} ~HidDetectionTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
void SetUpOnMainThread() override { OobeBaseTest::SetUpOnMainThread(); } device::mojom::kServiceName);
}
void SetUpInProcessBrowserTestFixture() override { void SetUpInProcessBrowserTestFixture() override {
OobeBaseTest::SetUpInProcessBrowserTestFixture(); OobeBaseTest::SetUpInProcessBrowserTestFixture();
......
...@@ -2358,8 +2358,13 @@ class KioskVirtualKeyboardTestSoundsManagerTestImpl ...@@ -2358,8 +2358,13 @@ class KioskVirtualKeyboardTestSoundsManagerTestImpl
class KioskVirtualKeyboardTest : public KioskTest, class KioskVirtualKeyboardTest : public KioskTest,
public audio::FakeSystemInfo { public audio::FakeSystemInfo {
public: public:
KioskVirtualKeyboardTest() {} KioskVirtualKeyboardTest() {
~KioskVirtualKeyboardTest() override = default; audio::FakeSystemInfo::OverrideGlobalBinderForAudioService(this);
}
~KioskVirtualKeyboardTest() override {
audio::FakeSystemInfo::ClearGlobalBinderForAudioService();
}
protected: protected:
// KioskVirtualKeyboardTest overrides: // KioskVirtualKeyboardTest overrides:
...@@ -2399,7 +2404,6 @@ IN_PROC_BROWSER_TEST_F(KioskVirtualKeyboardTest, RestrictFeatures) { ...@@ -2399,7 +2404,6 @@ IN_PROC_BROWSER_TEST_F(KioskVirtualKeyboardTest, RestrictFeatures) {
mock_audio_manager_ = std::make_unique<media::MockAudioManager>( mock_audio_manager_ = std::make_unique<media::MockAudioManager>(
std::make_unique<media::TestAudioThread>()); std::make_unique<media::TestAudioThread>());
mock_audio_manager_->SetHasInputDevices(true); mock_audio_manager_->SetHasInputDevices(true);
audio::FakeSystemInfo::OverrideGlobalBinderForAudioService(this);
set_test_app_id(kTestVirtualKeyboardKioskApp); set_test_app_id(kTestVirtualKeyboardKioskApp);
set_test_app_version("0.1"); set_test_app_version("0.1");
......
...@@ -19,13 +19,7 @@ namespace chromeos { ...@@ -19,13 +19,7 @@ namespace chromeos {
class HIDDetectionScreenTest : public WizardInProcessBrowserTest { class HIDDetectionScreenTest : public WizardInProcessBrowserTest {
public: public:
HIDDetectionScreenTest() HIDDetectionScreenTest()
: WizardInProcessBrowserTest(OobeScreen::SCREEN_OOBE_HID_DETECTION) {} : WizardInProcessBrowserTest(OobeScreen::SCREEN_OOBE_HID_DETECTION) {
protected:
void SetUpOnMainThread() override {
WizardInProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(WizardController::default_controller());
fake_input_service_manager_ = fake_input_service_manager_ =
std::make_unique<device::FakeInputServiceLinux>(); std::make_unique<device::FakeInputServiceLinux>();
...@@ -33,6 +27,17 @@ class HIDDetectionScreenTest : public WizardInProcessBrowserTest { ...@@ -33,6 +27,17 @@ class HIDDetectionScreenTest : public WizardInProcessBrowserTest {
device::mojom::kServiceName, device::mojom::InputDeviceManager::Name_, device::mojom::kServiceName, device::mojom::InputDeviceManager::Name_,
base::Bind(&device::FakeInputServiceLinux::Bind, base::Bind(&device::FakeInputServiceLinux::Bind,
base::Unretained(fake_input_service_manager_.get()))); base::Unretained(fake_input_service_manager_.get())));
}
~HIDDetectionScreenTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
protected:
void SetUpOnMainThread() override {
WizardInProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(WizardController::default_controller());
hid_detection_screen_ = static_cast<HIDDetectionScreen*>( hid_detection_screen_ = static_cast<HIDDetectionScreen*>(
WizardController::default_controller()->GetScreen( WizardController::default_controller()->GetScreen(
......
...@@ -71,9 +71,7 @@ class MockBatteryMonitor : public device::mojom::BatteryMonitor { ...@@ -71,9 +71,7 @@ class MockBatteryMonitor : public device::mojom::BatteryMonitor {
class BatteryMonitorTest : public ContentBrowserTest { class BatteryMonitorTest : public ContentBrowserTest {
public: public:
BatteryMonitorTest() = default; BatteryMonitorTest() {
void SetUpOnMainThread() override {
mock_battery_monitor_ = std::make_unique<MockBatteryMonitor>(); mock_battery_monitor_ = std::make_unique<MockBatteryMonitor>();
// Because Device Service also runs in this process(browser process), here // Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against // we can directly set our binder to intercept interface requests against
...@@ -84,6 +82,11 @@ class BatteryMonitorTest : public ContentBrowserTest { ...@@ -84,6 +82,11 @@ class BatteryMonitorTest : public ContentBrowserTest {
base::Unretained(mock_battery_monitor_.get()))); base::Unretained(mock_battery_monitor_.get())));
} }
~BatteryMonitorTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
protected: protected:
MockBatteryMonitor* mock_battery_monitor() { MockBatteryMonitor* mock_battery_monitor() {
return mock_battery_monitor_.get(); return mock_battery_monitor_.get();
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/network_session_configurator/common/network_switches.h" #include "components/network_session_configurator/common/network_switches.h"
...@@ -44,10 +43,20 @@ using device::FakeSensorProvider; ...@@ -44,10 +43,20 @@ using device::FakeSensorProvider;
class DeviceSensorBrowserTest : public ContentBrowserTest { class DeviceSensorBrowserTest : public ContentBrowserTest {
public: public:
DeviceSensorBrowserTest() DeviceSensorBrowserTest() {
: io_loop_finished_event_( // Because Device Service also runs in this process (browser process), here
base::WaitableEvent::ResetPolicy::AUTOMATIC, // we can directly set our binder to intercept interface requests against
base::WaitableEvent::InitialState::NOT_SIGNALED) {} // it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
base::BindRepeating(&DeviceSensorBrowserTest::Bind,
base::Unretained(this)));
}
~DeviceSensorBrowserTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
https_embedded_test_server_.reset( https_embedded_test_server_.reset(
...@@ -66,11 +75,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { ...@@ -66,11 +75,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
sensor_provider_->SetGyroscopeData(7, 8, 9); sensor_provider_->SetGyroscopeData(7, 8, 9);
sensor_provider_->SetRelativeOrientationSensorData(1, 2, 3); sensor_provider_->SetRelativeOrientationSensorData(1, 2, 3);
sensor_provider_->SetAbsoluteOrientationSensorData(4, 5, 6); sensor_provider_->SetAbsoluteOrientationSensorData(4, 5, 6);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&DeviceSensorBrowserTest::SetUpOnIOThread,
base::Unretained(this)));
io_loop_finished_event_.Wait();
} }
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
...@@ -79,17 +83,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { ...@@ -79,17 +83,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
command_line->AppendSwitch(switches::kIgnoreCertificateErrors); command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
} }
void SetUpOnIOThread() {
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
// it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
base::Bind(&DeviceSensorBrowserTest::Bind, base::Unretained(this)));
io_loop_finished_event_.Signal();
}
void DelayAndQuit(base::TimeDelta delay) { void DelayAndQuit(base::TimeDelta delay) {
base::PlatformThread::Sleep(delay); base::PlatformThread::Sleep(delay);
base::RunLoop::QuitCurrentWhenIdleDeprecated(); base::RunLoop::QuitCurrentWhenIdleDeprecated();
...@@ -117,8 +110,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest { ...@@ -117,8 +110,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
sensor_provider_->Bind( sensor_provider_->Bind(
device::mojom::SensorProviderRequest(std::move(handle))); device::mojom::SensorProviderRequest(std::move(handle)));
} }
base::WaitableEvent io_loop_finished_event_;
}; };
IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationTest) { IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationTest) {
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -42,15 +41,24 @@ using device::FakeSensorProvider; ...@@ -42,15 +41,24 @@ using device::FakeSensorProvider;
class GenericSensorBrowserTest : public ContentBrowserTest { class GenericSensorBrowserTest : public ContentBrowserTest {
public: public:
GenericSensorBrowserTest() GenericSensorBrowserTest() {
: io_loop_finished_event_(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED) {
scoped_feature_list_.InitWithFeatures( scoped_feature_list_.InitWithFeatures(
{features::kGenericSensor, features::kGenericSensorExtraClasses}, {}); {features::kGenericSensor, features::kGenericSensorExtraClasses}, {});
// Because Device Service also runs in this process (browser process), here
// we can directly set our binder to intercept interface requests against
// it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
base::BindRepeating(
&GenericSensorBrowserTest::BindSensorProviderRequest,
base::Unretained(this)));
} }
~GenericSensorBrowserTest() override {} ~GenericSensorBrowserTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
https_embedded_test_server_.reset( https_embedded_test_server_.reset(
...@@ -62,13 +70,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest { ...@@ -62,13 +70,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
https_embedded_test_server_->ServeFilesFromSourceDirectory( https_embedded_test_server_->ServeFilesFromSourceDirectory(
"content/test/data/generic_sensor"); "content/test/data/generic_sensor");
https_embedded_test_server_->StartAcceptingConnections(); https_embedded_test_server_->StartAcceptingConnections();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&GenericSensorBrowserTest::SetBinderOnIOThread,
base::Unretained(this)));
io_loop_finished_event_.Wait();
} }
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
...@@ -77,19 +78,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest { ...@@ -77,19 +78,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
command_line->AppendSwitch(switches::kIgnoreCertificateErrors); command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
} }
void SetBinderOnIOThread() {
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
// it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
base::BindRepeating(
&GenericSensorBrowserTest::BindSensorProviderRequest,
base::Unretained(this)));
io_loop_finished_event_.Signal();
}
void BindSensorProviderRequest( void BindSensorProviderRequest(
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle, mojo::ScopedMessagePipeHandle handle,
...@@ -115,7 +103,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest { ...@@ -115,7 +103,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
private: private:
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
base::WaitableEvent io_loop_finished_event_;
bool sensor_provider_available_ = true; bool sensor_provider_available_ = true;
std::unique_ptr<FakeSensorProvider> fake_sensor_provider_; std::unique_ptr<FakeSensorProvider> fake_sensor_provider_;
......
...@@ -93,17 +93,18 @@ class MockPowerMonitorMessageBroadcaster : public device::mojom::PowerMonitor { ...@@ -93,17 +93,18 @@ class MockPowerMonitorMessageBroadcaster : public device::mojom::PowerMonitor {
class PowerMonitorTest : public ContentBrowserTest { class PowerMonitorTest : public ContentBrowserTest {
public: public:
PowerMonitorTest() = default; PowerMonitorTest() {
void SetUp() override {
// Because Device Service also runs in this process(browser process), we can // Because Device Service also runs in this process(browser process), we can
// set our binder to intercept requests for PowerMonitor interface to it. // set our binder to intercept requests for PowerMonitor interface to it.
service_manager::ServiceContext::SetGlobalBinderForTesting( service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::PowerMonitor::Name_, device::mojom::kServiceName, device::mojom::PowerMonitor::Name_,
base::Bind(&PowerMonitorTest::BindPowerMonitor, base::Bind(&PowerMonitorTest::BindPowerMonitor,
base::Unretained(this))); base::Unretained(this)));
}
ContentBrowserTest::SetUp(); ~PowerMonitorTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
} }
void BindPowerMonitor(const std::string& interface_name, void BindPowerMonitor(const std::string& interface_name,
......
...@@ -26,9 +26,7 @@ namespace { ...@@ -26,9 +26,7 @@ namespace {
class VibrationTest : public ContentBrowserTest, class VibrationTest : public ContentBrowserTest,
public device::mojom::VibrationManager { public device::mojom::VibrationManager {
public: public:
VibrationTest() : binding_(this){}; VibrationTest() : binding_(this) {
void SetUpOnMainThread() override {
// Because Device Service also runs in this process(browser process), here // Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against // we can directly set our binder to intercept interface requests against
// it. // it.
...@@ -38,6 +36,11 @@ class VibrationTest : public ContentBrowserTest, ...@@ -38,6 +36,11 @@ class VibrationTest : public ContentBrowserTest,
base::Unretained(this))); base::Unretained(this)));
} }
~VibrationTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
void BindVibrationManager( void BindVibrationManager(
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle, mojo::ScopedMessagePipeHandle handle,
......
...@@ -253,17 +253,23 @@ class TestExtensionsAPIClient : public ShellExtensionsAPIClient { ...@@ -253,17 +253,23 @@ class TestExtensionsAPIClient : public ShellExtensionsAPIClient {
class HidApiTest : public ShellApiTest { class HidApiTest : public ShellApiTest {
public: public:
void SetUpOnMainThread() override { HidApiTest() {
ShellApiTest::SetUpOnMainThread(); // Because Device Service also runs in this process (browser process), we
// can set our binder to intercept requests for HidManager interface to it.
fake_hid_manager_ = std::make_unique<FakeHidManager>(); fake_hid_manager_ = std::make_unique<FakeHidManager>();
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
// it.
service_manager::ServiceContext::SetGlobalBinderForTesting( service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::HidManager::Name_, device::mojom::kServiceName, device::mojom::HidManager::Name_,
base::Bind(&FakeHidManager::Bind, base::Bind(&FakeHidManager::Bind,
base::Unretained(fake_hid_manager_.get()))); base::Unretained(fake_hid_manager_.get())));
}
~HidApiTest() override {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
}
void SetUpOnMainThread() override {
ShellApiTest::SetUpOnMainThread();
AddDevice(kTestDeviceGuids[0], 0x18D1, 0x58F0, false, "A"); AddDevice(kTestDeviceGuids[0], 0x18D1, 0x58F0, false, "A");
AddDevice(kTestDeviceGuids[1], 0x18D1, 0x58F0, true, "B"); AddDevice(kTestDeviceGuids[1], 0x18D1, 0x58F0, true, "B");
...@@ -311,23 +317,11 @@ class HidApiTest : public ShellApiTest { ...@@ -311,23 +317,11 @@ class HidApiTest : public ShellApiTest {
std::unique_ptr<FakeHidManager> fake_hid_manager_; std::unique_ptr<FakeHidManager> fake_hid_manager_;
}; };
// Flaky in tsan builds. http://crbug.com/853915 IN_PROC_BROWSER_TEST_F(HidApiTest, HidApp) {
#ifdef THREAD_SANITIZER
#define MAYBE_HidApp DISABLED_HidApp
#else
#define MAYBE_HidApp HidApp
#endif
IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_HidApp) {
ASSERT_TRUE(RunAppTest("api_test/hid/api")) << message_; ASSERT_TRUE(RunAppTest("api_test/hid/api")) << message_;
} }
// Flaky in tsan builds. http://crbug.com/853915 IN_PROC_BROWSER_TEST_F(HidApiTest, OnDeviceAdded) {
#ifdef THREAD_SANITIZER
#define MAYBE_OnDeviceAdded DISABLED_OnDeviceAdded
#else
#define MAYBE_OnDeviceAdded OnDeviceAdded
#endif
IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceAdded) {
ExtensionTestMessageListener load_listener("loaded", false); ExtensionTestMessageListener load_listener("loaded", false);
ExtensionTestMessageListener result_listener("success", false); ExtensionTestMessageListener result_listener("success", false);
result_listener.set_failure_message("failure"); result_listener.set_failure_message("failure");
...@@ -343,13 +337,7 @@ IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceAdded) { ...@@ -343,13 +337,7 @@ IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceAdded) {
EXPECT_EQ("success", result_listener.message()); EXPECT_EQ("success", result_listener.message());
} }
// Flaky in tsan builds. http://crbug.com/853915 IN_PROC_BROWSER_TEST_F(HidApiTest, OnDeviceRemoved) {
#ifdef THREAD_SANITIZER
#define MAYBE_OnDeviceRemoved DISABLED_OnDeviceRemoved
#else
#define MAYBE_OnDeviceRemoved OnDeviceRemoved
#endif
IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceRemoved) {
ExtensionTestMessageListener load_listener("loaded", false); ExtensionTestMessageListener load_listener("loaded", false);
ExtensionTestMessageListener result_listener("success", false); ExtensionTestMessageListener result_listener("success", false);
result_listener.set_failure_message("failure"); result_listener.set_failure_message("failure");
...@@ -366,13 +354,7 @@ IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceRemoved) { ...@@ -366,13 +354,7 @@ IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_OnDeviceRemoved) {
EXPECT_EQ("success", result_listener.message()); EXPECT_EQ("success", result_listener.message());
} }
// Flaky in tsan builds. http://crbug.com/853907 IN_PROC_BROWSER_TEST_F(HidApiTest, GetUserSelectedDevices) {
#ifdef THREAD_SANITIZER
#define MAYBE_GetUserSelectedDevices DISABLED_GetUserSelectedDevices
#else
#define MAYBE_GetUserSelectedDevices GetUserSelectedDevices
#endif
IN_PROC_BROWSER_TEST_F(HidApiTest, MAYBE_GetUserSelectedDevices) {
ExtensionTestMessageListener open_listener("opened_device", false); ExtensionTestMessageListener open_listener("opened_device", false);
TestExtensionsAPIClient test_api_client; TestExtensionsAPIClient test_api_client;
......
...@@ -23,6 +23,27 @@ ...@@ -23,6 +23,27 @@
#include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_context.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
// Disable SIMULATE_SERIAL_PORTS only if all the following are true:
//
// 1. You have an Arduino or compatible board attached to your machine and
// properly appearing as the first virtual serial port ("first" is very loosely
// defined as whichever port shows up in serial.getPorts). We've tested only
// the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these
// boards are based on the Atmel ATmega32u4, rather than the more common
// Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more
// widely.
//
// 2. Your user has permission to read/write the port. For example, this might
// mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of
// Linux, or else that the port's path (e.g., /dev/ttyACM0) has global
// read/write permissions.
//
// 3. You have uploaded a program to the board that does a byte-for-byte echo
// on the virtual serial port at 57600 bps. An example is at
// chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino.
//
#define SIMULATE_SERIAL_PORTS (1)
using testing::_; using testing::_;
using testing::Return; using testing::Return;
...@@ -169,30 +190,30 @@ class FakeSerialIoHandler : public device::mojom::SerialIoHandler { ...@@ -169,30 +190,30 @@ class FakeSerialIoHandler : public device::mojom::SerialIoHandler {
DISALLOW_COPY_AND_ASSIGN(FakeSerialIoHandler); DISALLOW_COPY_AND_ASSIGN(FakeSerialIoHandler);
}; };
void BindSerialDeviceEnumerator(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
const service_manager::BindSourceInfo& source_info) {
mojo::MakeStrongBinding(
std::make_unique<FakeSerialDeviceEnumerator>(),
device::mojom::SerialDeviceEnumeratorRequest(std::move(handle)));
}
void BindSerialIoHandler(const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
const service_manager::BindSourceInfo& source_info) {
mojo::MakeStrongBinding(
std::make_unique<FakeSerialIoHandler>(),
device::mojom::SerialIoHandlerRequest(std::move(handle)));
}
void DropBindRequest(const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
const service_manager::BindSourceInfo& source_info) {}
class SerialApiTest : public ExtensionApiTest { class SerialApiTest : public ExtensionApiTest {
public: public:
SerialApiTest() {} SerialApiTest() {
#if SIMULATE_SERIAL_PORTS
// Because Device Service also runs in this process(browser process), we can
// set our binder to intercept requests for
// SerialDeviceEnumerator/SerialIoHandler interfaces to it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName,
device::mojom::SerialDeviceEnumerator::Name_,
base::BindRepeating(&SerialApiTest::BindSerialDeviceEnumerator,
base::Unretained(this)));
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::SerialIoHandler::Name_,
base::BindRepeating(&SerialApiTest::BindSerialIoHandler));
#endif
}
~SerialApiTest() override {
#if SIMULATE_SERIAL_PORTS
service_manager::ServiceContext::ClearGlobalBindersForTesting(
device::mojom::kServiceName);
#endif
}
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
ExtensionApiTest::SetUpCommandLine(command_line); ExtensionApiTest::SetUpCommandLine(command_line);
...@@ -204,58 +225,39 @@ class SerialApiTest : public ExtensionApiTest { ...@@ -204,58 +225,39 @@ class SerialApiTest : public ExtensionApiTest {
ExtensionApiTest::TearDownOnMainThread(); ExtensionApiTest::TearDownOnMainThread();
} }
void FailEnumeratorRequest() { fail_enumerator_request_ = true; }
protected: protected:
// Because Device Service also runs in this process(browser process), we can void BindSerialDeviceEnumerator(
// set our binder to intercept requests for const std::string& interface_name,
// SerialDeviceEnumerator/SerialIoHandler interfaces to it. mojo::ScopedMessagePipeHandle handle,
void InterceptSerialDeviceEnumerator( const service_manager::BindSourceInfo& source_info) {
const service_manager::BinderRegistryWithArgs< if (fail_enumerator_request_)
const service_manager::BindSourceInfo&>::Binder& binder) { return;
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, mojo::MakeStrongBinding(
device::mojom::SerialDeviceEnumerator::Name_, binder); std::make_unique<FakeSerialDeviceEnumerator>(),
device::mojom::SerialDeviceEnumeratorRequest(std::move(handle)));
} }
void InterceptSerialIoHandler( static void BindSerialIoHandler(
const service_manager::BinderRegistryWithArgs< const std::string& interface_name,
const service_manager::BindSourceInfo&>::Binder& binder) { mojo::ScopedMessagePipeHandle handle,
service_manager::ServiceContext::SetGlobalBinderForTesting( const service_manager::BindSourceInfo& source_info) {
device::mojom::kServiceName, device::mojom::SerialIoHandler::Name_, mojo::MakeStrongBinding(
binder); std::make_unique<FakeSerialIoHandler>(),
device::mojom::SerialIoHandlerRequest(std::move(handle)));
} }
bool fail_enumerator_request_ = false;
}; };
} // namespace } // namespace
// Disable SIMULATE_SERIAL_PORTS only if all the following are true:
//
// 1. You have an Arduino or compatible board attached to your machine and
// properly appearing as the first virtual serial port ("first" is very loosely
// defined as whichever port shows up in serial.getPorts). We've tested only
// the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these
// boards are based on the Atmel ATmega32u4, rather than the more common
// Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more
// widely.
//
// 2. Your user has permission to read/write the port. For example, this might
// mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of
// Linux, or else that the port's path (e.g., /dev/ttyACM0) has global
// read/write permissions.
//
// 3. You have uploaded a program to the board that does a byte-for-byte echo
// on the virtual serial port at 57600 bps. An example is at
// chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino.
//
#define SIMULATE_SERIAL_PORTS (1)
IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) { IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) {
ResultCatcher catcher; ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile()); catcher.RestrictToBrowserContext(browser()->profile());
#if SIMULATE_SERIAL_PORTS
InterceptSerialDeviceEnumerator(base::Bind(&BindSerialDeviceEnumerator));
InterceptSerialIoHandler(base::Bind(&BindSerialIoHandler));
#endif
ASSERT_TRUE(RunExtensionTest("serial/api")) << message_; ASSERT_TRUE(RunExtensionTest("serial/api")) << message_;
} }
...@@ -263,7 +265,6 @@ IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) { ...@@ -263,7 +265,6 @@ IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) {
ResultCatcher catcher; ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile()); catcher.RestrictToBrowserContext(browser()->profile());
InterceptSerialDeviceEnumerator(base::Bind(&BindSerialDeviceEnumerator));
ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_; ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_;
} }
...@@ -271,9 +272,9 @@ IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardwareFail) { ...@@ -271,9 +272,9 @@ IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardwareFail) {
ResultCatcher catcher; ResultCatcher catcher;
catcher.RestrictToBrowserContext(browser()->profile()); catcher.RestrictToBrowserContext(browser()->profile());
// Intercept the request and then drop it, chrome.serial.getDevices() should // chrome.serial.getDevices() should get an empty list when the serial
// get an empty list. // enumerator interface is unavailable.
InterceptSerialDeviceEnumerator(base::Bind(&DropBindRequest)); FailEnumeratorRequest();
ASSERT_TRUE(RunExtensionTest("serial/real_hardware_fail")) << message_; ASSERT_TRUE(RunExtensionTest("serial/real_hardware_fail")) << message_;
} }
......
...@@ -23,6 +23,12 @@ void FakeSystemInfo::OverrideGlobalBinderForAudioService( ...@@ -23,6 +23,12 @@ void FakeSystemInfo::OverrideGlobalBinderForAudioService(
base::Unretained(fake_system_info))); base::Unretained(fake_system_info)));
} }
// static
void FakeSystemInfo::ClearGlobalBinderForAudioService() {
service_manager::ServiceContext::ClearGlobalBindersForTesting(
mojom::kServiceName);
}
void FakeSystemInfo::GetInputStreamParameters( void FakeSystemInfo::GetInputStreamParameters(
const std::string& device_id, const std::string& device_id,
GetInputStreamParametersCallback callback) { GetInputStreamParametersCallback callback) {
......
...@@ -26,9 +26,9 @@ class FakeSystemInfo : public mojom::SystemInfo { ...@@ -26,9 +26,9 @@ class FakeSystemInfo : public mojom::SystemInfo {
FakeSystemInfo(); FakeSystemInfo();
~FakeSystemInfo() override; ~FakeSystemInfo() override;
// See ServiceContext::ClearGlobalBindersForTesting() to clear it if needed.
static void OverrideGlobalBinderForAudioService( static void OverrideGlobalBinderForAudioService(
FakeSystemInfo* fake_system_info); FakeSystemInfo* fake_system_info);
static void ClearGlobalBinderForAudioService();
protected: protected:
// audio::mojom::SystemInfo implementation. // audio::mojom::SystemInfo implementation.
......
...@@ -201,8 +201,7 @@ TEST_F(FakeSystemInfoTest, HasInputDevicesCalledOnGlobalBinderOverride) { ...@@ -201,8 +201,7 @@ TEST_F(FakeSystemInfoTest, HasInputDevicesCalledOnGlobalBinderOverride) {
.WillOnce(testing::Invoke(&wait_loop, &base::RunLoop::Quit)); .WillOnce(testing::Invoke(&wait_loop, &base::RunLoop::Quit));
audio_system()->HasInputDevices(base::BindOnce([](bool) {})); audio_system()->HasInputDevices(base::BindOnce([](bool) {}));
wait_loop.Run(); wait_loop.Run();
service_manager::ServiceContext::ClearGlobalBindersForTesting( FakeSystemInfo::ClearGlobalBinderForAudioService();
mojom::kServiceName);
} }
// Service lifetime tests. // Service lifetime tests.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment