blob: 193df6c0aef18a0eee30faa3b1fef5cc6ed06caa [file] [log] [blame]
// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/browser/chromeos/login/login_wizard.h"
#include "chrome/browser/chromeos/login/screens/base_screen.h"
#include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
#include "chrome/browser/chromeos/login/screens/hid_detection_view.h"
#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/constants/chromeos_switches.h"
#include "services/device/public/cpp/hid/fake_input_service_linux.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/device/public/mojom/input_service.mojom.h"
#include "services/service_manager/public/cpp/service_binding.h"
namespace chromeos {
class HIDDetectionScreenTest : public InProcessBrowserTest {
public:
HIDDetectionScreenTest() {
fake_input_service_manager_ =
std::make_unique<device::FakeInputServiceLinux>();
service_manager::ServiceBinding::OverrideInterfaceBinderForTesting(
device::mojom::kServiceName,
base::Bind(&device::FakeInputServiceLinux::Bind,
base::Unretained(fake_input_service_manager_.get())));
}
~HIDDetectionScreenTest() override {
service_manager::ServiceBinding::ClearInterfaceBinderOverrideForTesting<
device::mojom::InputDeviceManager>(device::mojom::kServiceName);
}
// InProcessBrowserTest:
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
command_line->AppendArg(switches::kLoginManager);
}
void SetUpOnMainThread() override {
ShowLoginWizard(OobeScreen::SCREEN_OOBE_HID_DETECTION);
ASSERT_TRUE(WizardController::default_controller());
hid_detection_screen_ = static_cast<HIDDetectionScreen*>(
WizardController::default_controller()->GetScreen(
OobeScreen::SCREEN_OOBE_HID_DETECTION));
ASSERT_TRUE(hid_detection_screen_);
ASSERT_EQ(WizardController::default_controller()->current_screen(),
hid_detection_screen_);
ASSERT_TRUE(hid_detection_screen_->view_);
hid_detection_screen()->SetAdapterInitialPoweredForTesting(false);
}
HIDDetectionScreen* hid_detection_screen() { return hid_detection_screen_; }
HIDDetectionScreenHandler* handler() {
return static_cast<HIDDetectionScreenHandler*>(
hid_detection_screen()->view_);
}
scoped_refptr<device::BluetoothAdapter> adapter() {
return hid_detection_screen_->GetAdapterForTesting();
}
void AddDeviceToService(bool is_mouse, device::mojom::InputDeviceType type) {
auto device = device::mojom::InputDeviceInfo::New();
device->id = is_mouse ? "mouse" : "keyboard";
device->subsystem = device::mojom::InputDeviceSubsystem::SUBSYSTEM_INPUT;
device->type = type;
device->is_mouse = is_mouse;
device->is_keyboard = !is_mouse;
fake_input_service_manager_->AddDevice(std::move(device));
base::RunLoop().RunUntilIdle();
}
void RemoveDeviceFromService(bool is_mouse) {
std::string id = is_mouse ? "mouse" : "keyboard";
fake_input_service_manager_->RemoveDevice(std::move(id));
base::RunLoop().RunUntilIdle();
}
private:
HIDDetectionScreen* hid_detection_screen_;
std::unique_ptr<device::FakeInputServiceLinux> fake_input_service_manager_;
DISALLOW_COPY_AND_ASSIGN(HIDDetectionScreenTest);
};
IN_PROC_BROWSER_TEST_F(HIDDetectionScreenTest, MouseKeyboardStates) {
// NOTE: State strings match those in hid_detection_screen.cc.
// No devices added yet
EXPECT_EQ("searching", handler()->mouse_state_for_test());
EXPECT_EQ("searching", handler()->keyboard_state_for_test());
EXPECT_FALSE(handler()->continue_button_enabled_for_test());
// Generic connection types. Unlike the pointing device, which may be a tablet
// or touchscreen, the keyboard only reports usb and bluetooth states.
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_SERIO);
EXPECT_TRUE(handler()->continue_button_enabled_for_test());
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_SERIO);
EXPECT_EQ("connected", handler()->mouse_state_for_test());
EXPECT_EQ("usb", handler()->keyboard_state_for_test());
EXPECT_TRUE(handler()->continue_button_enabled_for_test());
// Remove generic devices, add usb devices.
RemoveDeviceFromService(true);
RemoveDeviceFromService(false);
EXPECT_FALSE(handler()->continue_button_enabled_for_test());
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_USB);
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_USB);
EXPECT_EQ("usb", handler()->mouse_state_for_test());
EXPECT_EQ("usb", handler()->keyboard_state_for_test());
EXPECT_TRUE(handler()->continue_button_enabled_for_test());
// Remove usb devices, add bluetooth devices.
RemoveDeviceFromService(true);
RemoveDeviceFromService(false);
EXPECT_FALSE(handler()->continue_button_enabled_for_test());
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_BLUETOOTH);
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_BLUETOOTH);
EXPECT_EQ("paired", handler()->mouse_state_for_test());
EXPECT_EQ("paired", handler()->keyboard_state_for_test());
EXPECT_TRUE(handler()->continue_button_enabled_for_test());
}
// Test that if there is any Bluetooth device connected on HID screen, the
// Bluetooth adapter should not be disabled after advancing to the next screen.
IN_PROC_BROWSER_TEST_F(HIDDetectionScreenTest, BluetoothDeviceConnected) {
OobeScreenWaiter(OobeScreen::SCREEN_OOBE_HID_DETECTION).Wait();
EXPECT_TRUE(adapter()->IsPowered());
// Add a pair of USB mouse/keyboard so that |pointing_device_connect_type_|
// and |keyboard_device_connect_type_| are
// device::mojom::InputDeviceType::TYPE_USB.
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_USB);
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_USB);
// Add another pair of Bluetooth mouse/keyboard.
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_BLUETOOTH);
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_BLUETOOTH);
// Simulate the user's click on "Continue" button.
hid_detection_screen()->OnContinueButtonClicked();
OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait();
// The adapter should not be powered off at this moment.
EXPECT_TRUE(adapter()->IsPowered());
}
// Test that if there is no Bluetooth device connected on HID screen, the
// Bluetooth adapter should be disabled after advancing to the next screen.
IN_PROC_BROWSER_TEST_F(HIDDetectionScreenTest, NoBluetoothDeviceConnected) {
OobeScreenWaiter(OobeScreen::SCREEN_OOBE_HID_DETECTION).Wait();
EXPECT_TRUE(adapter()->IsPowered());
AddDeviceToService(true, device::mojom::InputDeviceType::TYPE_USB);
AddDeviceToService(false, device::mojom::InputDeviceType::TYPE_USB);
// Simulate the user's click on "Continue" button.
hid_detection_screen()->OnContinueButtonClicked();
OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait();
// The adapter should be powered off at this moment.
EXPECT_FALSE(adapter()->IsPowered());
}
} // namespace chromeos