blob: 2fd04181e8af1e96d88dbd0b6bb2eef2bef52e2f [file] [log] [blame]
// Copyright 2017 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 "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h"
#include <memory>
#include <vector>
#include "ash/display/display_configuration_controller.h"
#include "ash/shell.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/test/base/chrome_ash_test_base.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
#include "ui/display/display_observer.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/test/touch_device_manager_test_api.h"
#include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/events/devices/device_data_manager_test_api.h"
#include "ui/events/devices/touchscreen_device.h"
namespace chromeos {
namespace {
class TestCrosDisplayConfig : public ash::mojom::CrosDisplayConfigController {
public:
TestCrosDisplayConfig() : binding_(this) {}
ash::mojom::CrosDisplayConfigControllerPtr CreateInterfacePtrAndBind() {
ash::mojom::CrosDisplayConfigControllerPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
// ash::mojom::CrosDisplayConfigController:
void AddObserver(ash::mojom::CrosDisplayConfigObserverAssociatedPtrInfo
observer) override {}
void GetDisplayLayoutInfo(GetDisplayLayoutInfoCallback callback) override {}
void SetDisplayLayoutInfo(ash::mojom::DisplayLayoutInfoPtr info,
SetDisplayLayoutInfoCallback callback) override {}
void GetDisplayUnitInfoList(
bool single_unified,
GetDisplayUnitInfoListCallback callback) override {}
void SetDisplayProperties(const std::string& id,
ash::mojom::DisplayConfigPropertiesPtr properties,
ash::mojom::DisplayConfigSource source,
SetDisplayPropertiesCallback callback) override {
if (properties->set_primary) {
int64_t display_id;
base::StringToInt64(id, &display_id);
ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
display_id);
}
std::move(callback).Run(ash::mojom::DisplayConfigResult::kSuccess);
}
void SetUnifiedDesktopEnabled(bool enabled) override {}
void OverscanCalibration(const std::string& display_id,
ash::mojom::DisplayConfigOperation op,
const base::Optional<gfx::Insets>& delta,
OverscanCalibrationCallback callback) override {}
void TouchCalibration(const std::string& display_id,
ash::mojom::DisplayConfigOperation op,
ash::mojom::TouchCalibrationPtr calibration,
TouchCalibrationCallback callback) override {}
private:
mojo::Binding<ash::mojom::CrosDisplayConfigController> binding_;
DISALLOW_COPY_AND_ASSIGN(TestCrosDisplayConfig);
};
class OobeDisplayChooserTest : public ChromeAshTestBase {
public:
OobeDisplayChooserTest() : ChromeAshTestBase() {}
int64_t GetPrimaryDisplay() {
return display::Screen::GetScreen()->GetPrimaryDisplay().id();
}
// ChromeAshTestBase:
void SetUp() override {
ChromeAshTestBase::SetUp();
cros_display_config_ = std::make_unique<TestCrosDisplayConfig>();
display_chooser_ = std::make_unique<OobeDisplayChooser>();
display_chooser_->set_cros_display_config_ptr_for_test(
cros_display_config_->CreateInterfacePtrAndBind());
ui::DeviceDataManagerTestApi().OnDeviceListsComplete();
}
OobeDisplayChooser* display_chooser() { return display_chooser_.get(); }
private:
std::unique_ptr<TestCrosDisplayConfig> cros_display_config_;
std::unique_ptr<OobeDisplayChooser> display_chooser_;
DISALLOW_COPY_AND_ASSIGN(OobeDisplayChooserTest);
};
const uint16_t kWhitelistedId = 0x266e;
} // namespace
TEST_F(OobeDisplayChooserTest, PreferTouchAsPrimary) {
// Setup 2 displays, second one is intended to be a touch display
std::vector<display::ManagedDisplayInfo> display_info;
display_info.push_back(
display::ManagedDisplayInfo::CreateFromSpecWithID("0+0-3000x2000", 1));
display_info.push_back(
display::ManagedDisplayInfo::CreateFromSpecWithID("3000+0-800x600", 2));
display_manager()->OnNativeDisplaysChanged(display_info);
base::RunLoop().RunUntilIdle();
// Make sure the non-touch display is primary
ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(1);
// Setup corresponding TouchscreenDevice object
ui::TouchscreenDevice touchscreen =
ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_USB,
"Touchscreen", gfx::Size(800, 600), 1);
touchscreen.vendor_id = kWhitelistedId;
ui::DeviceDataManagerTestApi().SetTouchscreenDevices({touchscreen});
base::RunLoop().RunUntilIdle();
// Associate touchscreen device with display
display::test::TouchDeviceManagerTestApi(
display_manager()->touch_device_manager())
.Associate(&display_info[1], touchscreen);
display_manager()->OnNativeDisplaysChanged(display_info);
base::RunLoop().RunUntilIdle();
// For mus we have to explicitly tell the InputDeviceClient the
// TouchscreenDevices. Normally InputDeviceClient is told of the
// TouchscreenDevices by way of implementing
// ws::mojom::InputDeviceObserverMojo. In unit tests InputDeviceClient is not
// wired to the window server (the window server isn't running).
touchscreen.target_display_id = display_info[1].id();
ui::DeviceDataManagerTestApi().SetTouchscreenDevices({touchscreen}, true);
EXPECT_EQ(1, GetPrimaryDisplay());
display_chooser()->TryToPlaceUiOnTouchDisplay();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, GetPrimaryDisplay());
}
TEST_F(OobeDisplayChooserTest, DontSwitchFromTouch) {
// Setup 2 displays, second one is intended to be a touch display
std::vector<display::ManagedDisplayInfo> display_info;
display_info.push_back(
display::ManagedDisplayInfo::CreateFromSpecWithID("0+0-3000x2000", 1));
display_info.push_back(
display::ManagedDisplayInfo::CreateFromSpecWithID("3000+0-800x600", 2));
display_info[0].set_touch_support(display::Display::TouchSupport::AVAILABLE);
display_manager()->OnNativeDisplaysChanged(display_info);
base::RunLoop().RunUntilIdle();
// Make sure the non-touch display is primary
ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(1);
// Setup corresponding TouchscreenDevice object
ui::TouchscreenDevice touchscreen =
ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_USB,
"Touchscreen", gfx::Size(800, 600), 1);
touchscreen.vendor_id = kWhitelistedId;
ui::DeviceDataManagerTestApi().SetTouchscreenDevices({touchscreen});
base::RunLoop().RunUntilIdle();
// Associate touchscreen device with display
display::test::TouchDeviceManagerTestApi(
display_manager()->touch_device_manager())
.Associate(&display_info[1], touchscreen);
display_manager()->OnNativeDisplaysChanged(display_info);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, GetPrimaryDisplay());
display_chooser()->TryToPlaceUiOnTouchDisplay();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, GetPrimaryDisplay());
}
} // namespace chromeos