1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137

ash / system / input_device_settings / input_device_duplicate_id_finder_unittest.cc [blame]

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/input_device_settings/input_device_duplicate_id_finder.h"

#include <memory>

#include "ash/test/ash_test_base.h"
#include "ui/events/devices/device_data_manager_test_api.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/devices/keyboard_device.h"
#include "ui/events/devices/touchpad_device.h"

namespace ash {

namespace {

const ui::InputDevice CreateInputDevice(int id,
                                        uint16_t vendor,
                                        uint16_t product) {
  return ui::InputDevice(id, ui::INPUT_DEVICE_INTERNAL, "kDeviceName", "",
                         base::FilePath(), vendor, product, 0);
}

class TestObserver : public InputDeviceDuplicateIdFinder::Observer {
 public:
  // InputDeviceDuplicateIdFinder::Observer:
  void OnDuplicateDevicesUpdated() override { num_times_updated_++; }

  int num_times_updated() { return num_times_updated_; }

 private:
  int num_times_updated_ = 0;
};

}  // namespace

class InputDeviceDuplicateIdFinderTest : public AshTestBase {
 public:
  InputDeviceDuplicateIdFinderTest() = default;
  InputDeviceDuplicateIdFinderTest(const InputDeviceDuplicateIdFinderTest&) =
      delete;
  InputDeviceDuplicateIdFinderTest& operator=(
      const InputDeviceDuplicateIdFinderTest&) = delete;
  ~InputDeviceDuplicateIdFinderTest() override = default;

  // testing::Test:
  void SetUp() override {
    AshTestBase::SetUp();
    // Duplicate ID finder should be created after the test base is setup.
    duplicate_id_finder_ = std::make_unique<InputDeviceDuplicateIdFinder>();
    observer_ = std::make_unique<TestObserver>();
    duplicate_id_finder_->AddObserver(observer_.get());
  }

  void TearDown() override {
    duplicate_id_finder_->RemoveObserver(observer_.get());
    observer_.reset();
    duplicate_id_finder_.reset();
    AshTestBase::TearDown();
  }

 protected:
  std::unique_ptr<InputDeviceDuplicateIdFinder> duplicate_id_finder_;
  std::unique_ptr<TestObserver> observer_;
};

TEST_F(InputDeviceDuplicateIdFinderTest, DuplicateIdFinding) {
  auto duplicate_1_1 = CreateInputDevice(0, 0x1234, 0x4321);
  auto duplicate_1_2 = CreateInputDevice(1, 0x1234, 0x4321);
  auto duplicate_1_3 = CreateInputDevice(2, 0x1234, 0x4321);

  auto duplicate_2_1 = CreateInputDevice(3, 0x1234, 0x1234);
  auto duplicate_2_2 = CreateInputDevice(4, 0x1234, 0x1234);
  auto duplicate_2_3 = CreateInputDevice(5, 0x1234, 0x1234);

  auto duplicate_3_1 = CreateInputDevice(6, 0x4321, 0x5678);
  auto duplicate_3_2 = CreateInputDevice(7, 0x4321, 0x5678);
  auto duplicate_3_3 = CreateInputDevice(8, 0x4321, 0x5678);

  ui::DeviceDataManagerTestApi().SetMouseDevices(
      {duplicate_1_1, duplicate_2_1, duplicate_3_1});
  EXPECT_EQ(1, observer_->num_times_updated());
  ui::DeviceDataManagerTestApi().SetGraphicsTabletDevices(
      {duplicate_1_2, duplicate_2_2, duplicate_3_2});
  EXPECT_EQ(2, observer_->num_times_updated());
  ui::DeviceDataManagerTestApi().SetUncategorizedDevices({duplicate_1_3});
  EXPECT_EQ(3, observer_->num_times_updated());
  ui::DeviceDataManagerTestApi().SetKeyboardDevices(
      {ui::KeyboardDevice(duplicate_2_3)});
  EXPECT_EQ(4, observer_->num_times_updated());
  ui::DeviceDataManagerTestApi().SetTouchpadDevices(
      {ui::TouchpadDevice(duplicate_3_3)});
  EXPECT_EQ(5, observer_->num_times_updated());

  {
    auto* duplicate_group =
        duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_1_1.id);
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_1_2.id));
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_1_3.id));
    ASSERT_NE(nullptr, duplicate_group);
    EXPECT_TRUE(duplicate_group->contains(duplicate_1_1.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_1_2.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_1_3.id));
  }

  {
    auto* duplicate_group =
        duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_2_1.id);
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_2_2.id));
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_2_3.id));
    ASSERT_NE(nullptr, duplicate_group);
    EXPECT_TRUE(duplicate_group->contains(duplicate_2_1.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_2_2.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_2_3.id));
  }

  {
    auto* duplicate_group =
        duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_3_1.id);
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_3_2.id));
    EXPECT_EQ(duplicate_group,
              duplicate_id_finder_->GetDuplicateDeviceIds(duplicate_3_3.id));
    ASSERT_NE(nullptr, duplicate_group);
    EXPECT_TRUE(duplicate_group->contains(duplicate_3_1.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_3_2.id));
    EXPECT_TRUE(duplicate_group->contains(duplicate_3_3.id));
  }
}

}  // namespace ash