hid_detection_manager_impl_unittest.cc 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/hid_detection/hid_detection_manager_impl.h"
  5. #include "ash/components/hid_detection/bluetooth_hid_detector.h"
  6. #include "ash/components/hid_detection/fake_bluetooth_hid_detector.h"
  7. #include "ash/components/hid_detection/hid_detection_utils.h"
  8. #include "ash/constants/ash_features.h"
  9. #include "base/test/bind.h"
  10. #include "base/test/metrics/histogram_tester.h"
  11. #include "base/test/scoped_feature_list.h"
  12. #include "base/test/task_environment.h"
  13. #include "services/device/public/cpp/hid/fake_input_service_linux.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. namespace ash::hid_detection {
  16. namespace {
  17. using BluetoothHidMetadata = BluetoothHidDetector::BluetoothHidMetadata;
  18. using BluetoothHidType = BluetoothHidDetector::BluetoothHidType;
  19. using InputMetadata = HidDetectionManager::InputMetadata;
  20. using InputState = HidDetectionManager::InputState;
  21. using InputDeviceType = device::mojom::InputDeviceType;
  22. using InputDevicesStatus = BluetoothHidDetector::InputDevicesStatus;
  23. const char kTestHidName[] = "testName";
  24. const char kTestPinCode[] = "123456";
  25. enum TestHidType {
  26. kMouse,
  27. kTouchpad,
  28. kKeyboard,
  29. kTouchscreen,
  30. kTablet,
  31. };
  32. class FakeHidDetectionManagerDelegate : public HidDetectionManager::Delegate {
  33. public:
  34. ~FakeHidDetectionManagerDelegate() override = default;
  35. size_t num_hid_detection_status_changed_calls() const {
  36. return num_hid_detection_status_changed_calls_;
  37. }
  38. const absl::optional<HidDetectionManager::HidDetectionStatus>&
  39. last_hid_detection_status() const {
  40. return last_hid_detection_status_;
  41. }
  42. private:
  43. // HidDetectionManager::Delegate:
  44. void OnHidDetectionStatusChanged(
  45. HidDetectionManager::HidDetectionStatus status) override {
  46. ++num_hid_detection_status_changed_calls_;
  47. last_hid_detection_status_ = std::move(status);
  48. }
  49. size_t num_hid_detection_status_changed_calls_ = 0u;
  50. absl::optional<HidDetectionManager::HidDetectionStatus>
  51. last_hid_detection_status_;
  52. };
  53. } // namespace
  54. class HidDetectionManagerImplTest : public testing::Test {
  55. protected:
  56. HidDetectionManagerImplTest() = default;
  57. HidDetectionManagerImplTest(const HidDetectionManagerImplTest&) = delete;
  58. HidDetectionManagerImplTest& operator=(const HidDetectionManagerImplTest&) =
  59. delete;
  60. ~HidDetectionManagerImplTest() override = default;
  61. // testing::Test:
  62. void SetUp() override {
  63. scoped_feature_list_.InitAndEnableFeature(
  64. ash::features::kOobeHidDetectionRevamp);
  65. auto fake_bluetooth_hid_detector =
  66. std::make_unique<FakeBluetoothHidDetector>();
  67. fake_bluetooth_hid_detector_ = fake_bluetooth_hid_detector.get();
  68. hid_detection_manager_ = std::make_unique<HidDetectionManagerImpl>(
  69. /*device_service=*/nullptr);
  70. hid_detection_manager_->SetBluetoothHidDetectorForTest(
  71. std::move(fake_bluetooth_hid_detector));
  72. HidDetectionManagerImpl::SetInputDeviceManagerBinderForTest(
  73. base::BindRepeating(&device::FakeInputServiceLinux::Bind,
  74. base::Unretained(&fake_input_service_)));
  75. }
  76. void TearDown() override {
  77. HidDetectionManagerImpl::SetInputDeviceManagerBinderForTest(
  78. base::NullCallback());
  79. }
  80. absl::optional<bool> GetIsHidDetectionRequired() {
  81. absl::optional<bool> result;
  82. hid_detection_manager_->GetIsHidDetectionRequired(
  83. base::BindLambdaForTesting(
  84. [&result](bool is_required) { result = is_required; }));
  85. base::RunLoop().RunUntilIdle();
  86. return result;
  87. }
  88. void StartHidDetection() {
  89. EXPECT_FALSE(
  90. fake_bluetooth_hid_detector_->is_bluetooth_hid_detection_active());
  91. hid_detection_manager_->StartHidDetection(&delegate_);
  92. base::RunLoop().RunUntilIdle();
  93. EXPECT_TRUE(
  94. fake_bluetooth_hid_detector_->is_bluetooth_hid_detection_active());
  95. }
  96. void StopHidDetection(bool should_be_using_bluetooth) {
  97. EXPECT_TRUE(
  98. fake_bluetooth_hid_detector_->is_bluetooth_hid_detection_active());
  99. hid_detection_manager_->StopHidDetection();
  100. base::RunLoop().RunUntilIdle();
  101. EXPECT_FALSE(
  102. fake_bluetooth_hid_detector_->is_bluetooth_hid_detection_active());
  103. EXPECT_EQ(should_be_using_bluetooth,
  104. fake_bluetooth_hid_detector_->is_using_bluetooth());
  105. }
  106. size_t GetNumHidDetectionStatusChangedCalls() {
  107. return delegate_.num_hid_detection_status_changed_calls();
  108. }
  109. const absl::optional<HidDetectionManager::HidDetectionStatus>&
  110. GetLastHidDetectionStatus() {
  111. return delegate_.last_hid_detection_status();
  112. }
  113. void AddDevice(TestHidType hid_type,
  114. InputDeviceType device_type,
  115. std::string* id_out = nullptr,
  116. const char* name = NULL) {
  117. AddDevice(std::vector{hid_type}, device_type, id_out, name);
  118. }
  119. void AddDevice(const std::vector<TestHidType>& hid_types,
  120. InputDeviceType device_type,
  121. std::string* id_out = nullptr,
  122. const char* name = NULL) {
  123. auto device = device::mojom::InputDeviceInfo::New();
  124. device->id = num_devices_created_++;
  125. if (id_out)
  126. *id_out = device->id;
  127. device->name = name == NULL ? device->id : name;
  128. device->subsystem = device::mojom::InputDeviceSubsystem::SUBSYSTEM_INPUT;
  129. device->type = device_type;
  130. for (const auto& hid_type : hid_types) {
  131. switch (hid_type) {
  132. case kMouse:
  133. device->is_mouse = true;
  134. break;
  135. case kTouchpad:
  136. device->is_touchpad = true;
  137. break;
  138. case kKeyboard:
  139. device->is_keyboard = true;
  140. break;
  141. case kTouchscreen:
  142. device->is_touchscreen = true;
  143. break;
  144. case kTablet:
  145. device->is_tablet = true;
  146. break;
  147. }
  148. }
  149. fake_input_service_.AddDevice(std::move(device));
  150. base::RunLoop().RunUntilIdle();
  151. }
  152. void RemoveDevice(const std::string& id) {
  153. fake_input_service_.RemoveDevice(id);
  154. base::RunLoop().RunUntilIdle();
  155. }
  156. void SimulatePairingStarted(
  157. BluetoothHidDetector::BluetoothHidMetadata pairing_device) {
  158. fake_bluetooth_hid_detector_->SimulatePairingStarted(
  159. std::move(pairing_device));
  160. base::RunLoop().RunUntilIdle();
  161. }
  162. void SimulatePairingCodeRequired(
  163. const BluetoothHidPairingState& pairing_state) {
  164. fake_bluetooth_hid_detector_->SetPairingState(BluetoothHidPairingState{
  165. pairing_state.code, pairing_state.num_keys_entered});
  166. base::RunLoop().RunUntilIdle();
  167. }
  168. void SimulatePairingSessionEnded() {
  169. fake_bluetooth_hid_detector_->SimulatePairingSessionEnded();
  170. base::RunLoop().RunUntilIdle();
  171. }
  172. void AssertHidDetectionStatus(
  173. InputMetadata pointer_metadata,
  174. InputMetadata keyboard_metadata,
  175. bool touchscreen_detected,
  176. const absl::optional<BluetoothHidPairingState>& pairing_state) {
  177. EXPECT_EQ(pointer_metadata.state,
  178. GetLastHidDetectionStatus()->pointer_metadata.state);
  179. EXPECT_EQ(pointer_metadata.detected_hid_name,
  180. GetLastHidDetectionStatus()->pointer_metadata.detected_hid_name);
  181. EXPECT_EQ(keyboard_metadata.state,
  182. GetLastHidDetectionStatus()->keyboard_metadata.state);
  183. EXPECT_EQ(keyboard_metadata.detected_hid_name,
  184. GetLastHidDetectionStatus()->keyboard_metadata.detected_hid_name);
  185. EXPECT_EQ(touchscreen_detected,
  186. GetLastHidDetectionStatus()->touchscreen_detected);
  187. EXPECT_EQ(pairing_state.has_value(),
  188. GetLastHidDetectionStatus()->pairing_state.has_value());
  189. if (pairing_state.has_value()) {
  190. EXPECT_EQ(pairing_state->code,
  191. GetLastHidDetectionStatus()->pairing_state->code);
  192. EXPECT_EQ(pairing_state->num_keys_entered,
  193. GetLastHidDetectionStatus()->pairing_state->num_keys_entered);
  194. }
  195. }
  196. void AssertInputDevicesStatus(InputDevicesStatus input_devices_status) {
  197. EXPECT_EQ(input_devices_status.pointer_is_missing,
  198. fake_bluetooth_hid_detector_->input_devices_status()
  199. .pointer_is_missing);
  200. EXPECT_EQ(input_devices_status.keyboard_is_missing,
  201. fake_bluetooth_hid_detector_->input_devices_status()
  202. .keyboard_is_missing);
  203. }
  204. void AssertInitialHidsMissingCount(HidsMissing hids_missing, int count) {
  205. histogram_tester_.ExpectBucketCount(
  206. "OOBE.HidDetectionScreen.InitialHidsMissing", hids_missing, count);
  207. histogram_tester_.ExpectTotalCount(
  208. "OOBE.HidDetectionScreen.InitialHidsMissing", count);
  209. }
  210. void AssertHidConnectedCount(HidType hid_type, int count, int total_count) {
  211. histogram_tester_.ExpectBucketCount("OOBE.HidDetectionScreen.HidConnected",
  212. hid_type, count);
  213. histogram_tester_.ExpectTotalCount("OOBE.HidDetectionScreen.HidConnected",
  214. total_count);
  215. }
  216. void AssertHidDisconnectedCount(HidType hid_type,
  217. int count,
  218. int total_count) {
  219. histogram_tester_.ExpectBucketCount(
  220. "OOBE.HidDetectionScreen.HidDisconnected", hid_type, count);
  221. histogram_tester_.ExpectTotalCount(
  222. "OOBE.HidDetectionScreen.HidDisconnected", total_count);
  223. }
  224. size_t GetNumSetInputDevicesStatusCalls() {
  225. return fake_bluetooth_hid_detector_->num_set_input_devices_status_calls();
  226. }
  227. private:
  228. base::test::TaskEnvironment task_environment_;
  229. base::test::ScopedFeatureList scoped_feature_list_;
  230. base::HistogramTester histogram_tester_;
  231. device::FakeInputServiceLinux fake_input_service_;
  232. size_t num_devices_created_ = 0;
  233. FakeHidDetectionManagerDelegate delegate_;
  234. FakeBluetoothHidDetector* fake_bluetooth_hid_detector_ = nullptr;
  235. std::unique_ptr<hid_detection::HidDetectionManagerImpl>
  236. hid_detection_manager_;
  237. };
  238. TEST_F(HidDetectionManagerImplTest,
  239. GetIsHidDetectionRequired_NoDevicesConnected) {
  240. AssertInitialHidsMissingCount(HidsMissing::kPointerAndKeyboard, /*count=*/0);
  241. absl::optional<bool> is_hid_detection_required = GetIsHidDetectionRequired();
  242. ASSERT_TRUE(is_hid_detection_required.has_value());
  243. ASSERT_TRUE(is_hid_detection_required.value());
  244. AssertInitialHidsMissingCount(HidsMissing::kPointerAndKeyboard, /*count=*/1);
  245. }
  246. TEST_F(HidDetectionManagerImplTest,
  247. GetIsHidDetectionRequired_OnlyPointerConnected) {
  248. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_USB);
  249. AssertInitialHidsMissingCount(HidsMissing::kKeyboard, /*count=*/0);
  250. absl::optional<bool> is_hid_detection_required = GetIsHidDetectionRequired();
  251. ASSERT_TRUE(is_hid_detection_required.has_value());
  252. ASSERT_TRUE(is_hid_detection_required.value());
  253. AssertInitialHidsMissingCount(HidsMissing::kKeyboard, /*count=*/1);
  254. }
  255. TEST_F(HidDetectionManagerImplTest,
  256. GetIsHidDetectionRequired_OnlyKeyboardConnected) {
  257. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_USB);
  258. AssertInitialHidsMissingCount(HidsMissing::kPointer, /*count=*/0);
  259. absl::optional<bool> is_hid_detection_required = GetIsHidDetectionRequired();
  260. ASSERT_TRUE(is_hid_detection_required.has_value());
  261. ASSERT_TRUE(is_hid_detection_required.value());
  262. AssertInitialHidsMissingCount(HidsMissing::kPointer, /*count=*/1);
  263. }
  264. TEST_F(HidDetectionManagerImplTest,
  265. GetIsHidDetectionRequired_PointerAndKeyboardConnected) {
  266. AddDevice(TestHidType::kTouchpad, InputDeviceType::TYPE_USB);
  267. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_USB);
  268. AssertInitialHidsMissingCount(HidsMissing::kPointer, /*count=*/0);
  269. absl::optional<bool> is_hid_detection_required = GetIsHidDetectionRequired();
  270. ASSERT_TRUE(is_hid_detection_required.has_value());
  271. ASSERT_FALSE(is_hid_detection_required.value());
  272. AssertInitialHidsMissingCount(HidsMissing::kNone, /*count=*/1);
  273. }
  274. TEST_F(HidDetectionManagerImplTest, StartDetection_TouchscreenPreConnected) {
  275. AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO);
  276. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  277. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0,
  278. /*total_count=*/0);
  279. StartHidDetection();
  280. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  281. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  282. AssertHidDetectionStatus(
  283. /*pointer_metadata=*/{InputState::kSearching,
  284. /*detected_hid_name=*/""},
  285. /*keyboard_metadata=*/
  286. {InputState::kSearching, /*detected_hid_name=*/""},
  287. /*touchscreen_detected=*/true,
  288. /*pairing_state=*/absl::nullopt);
  289. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  290. AssertInputDevicesStatus(
  291. {.pointer_is_missing = true, .keyboard_is_missing = true});
  292. StopHidDetection(/*should_be_using_bluetooth=*/false);
  293. }
  294. TEST_F(HidDetectionManagerImplTest, StartDetection_PointerPreConnected) {
  295. std::string device_id;
  296. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_SERIO, &device_id);
  297. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  298. StartHidDetection();
  299. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  300. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  301. AssertHidDetectionStatus(
  302. /*pointer_metadata=*/{InputState::kConnected, device_id},
  303. /*keyboard_metadata=*/
  304. {InputState::kSearching, /*detected_hid_name=*/""},
  305. /*touchscreen_detected=*/false,
  306. /*pairing_state=*/absl::nullopt);
  307. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  308. AssertInputDevicesStatus(
  309. {.pointer_is_missing = false, .keyboard_is_missing = true});
  310. StopHidDetection(/*should_be_using_bluetooth=*/false);
  311. }
  312. TEST_F(HidDetectionManagerImplTest, StartDetection_KeyboardPreConnected) {
  313. std::string device_id;
  314. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_SERIO, &device_id);
  315. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  316. StartHidDetection();
  317. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  318. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  319. AssertHidDetectionStatus(
  320. /*pointer_metadata=*/{InputState::kSearching,
  321. /*detected_hid_name=*/""},
  322. /*keyboard_metadata=*/{InputState::kConnected, device_id},
  323. /*touchscreen_detected=*/false,
  324. /*pairing_state=*/absl::nullopt);
  325. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  326. AssertInputDevicesStatus(
  327. {.pointer_is_missing = true, .keyboard_is_missing = false});
  328. StopHidDetection(/*should_be_using_bluetooth=*/false);
  329. }
  330. TEST_F(HidDetectionManagerImplTest,
  331. StartDetection_NonHidConnectedDisconnected) {
  332. StartHidDetection();
  333. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  334. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  335. AssertHidDetectionStatus(
  336. /*pointer_metadata=*/{InputState::kSearching,
  337. /*detected_hid_name=*/""},
  338. /*keyboard_metadata=*/
  339. {InputState::kSearching, /*detected_hid_name=*/""},
  340. /*touchscreen_detected=*/false,
  341. /*pairing_state=*/absl::nullopt);
  342. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  343. AssertInputDevicesStatus(
  344. {.pointer_is_missing = true, .keyboard_is_missing = true});
  345. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0,
  346. /*total_count=*/0);
  347. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/0,
  348. /*total_count=*/0);
  349. // Add a device without a HID type. This should not inform the delegate
  350. // and no state changed.
  351. std::vector<TestHidType> hid_types{};
  352. std::string device_id;
  353. AddDevice(hid_types, InputDeviceType::TYPE_USB, &device_id);
  354. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  355. AssertHidDetectionStatus(
  356. /*pointer_metadata=*/{InputState::kSearching,
  357. /*detected_hid_name=*/""},
  358. /*keyboard_metadata=*/
  359. {InputState::kSearching, /*detected_hid_name=*/""},
  360. /*touchscreen_detected=*/false,
  361. /*pairing_state=*/absl::nullopt);
  362. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  363. AssertInputDevicesStatus(
  364. {.pointer_is_missing = true, .keyboard_is_missing = true});
  365. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0,
  366. /*total_count=*/0);
  367. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/0,
  368. /*total_count=*/0);
  369. RemoveDevice(device_id);
  370. StopHidDetection(/*should_be_using_bluetooth=*/false);
  371. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  372. AssertHidDetectionStatus(
  373. /*pointer_metadata=*/{InputState::kSearching,
  374. /*detected_hid_name=*/""},
  375. /*keyboard_metadata=*/
  376. {InputState::kSearching, /*detected_hid_name=*/""},
  377. /*touchscreen_detected=*/false,
  378. /*pairing_state=*/absl::nullopt);
  379. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  380. AssertInputDevicesStatus(
  381. {.pointer_is_missing = true, .keyboard_is_missing = true});
  382. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/0,
  383. /*total_count=*/0);
  384. }
  385. TEST_F(HidDetectionManagerImplTest,
  386. StartDetection_TouchscreenConnectedDisconnected) {
  387. StartHidDetection();
  388. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  389. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  390. AssertHidDetectionStatus(
  391. /*pointer_metadata=*/{InputState::kSearching,
  392. /*detected_hid_name=*/""},
  393. /*keyboard_metadata=*/
  394. {InputState::kSearching, /*detected_hid_name=*/""},
  395. /*touchscreen_detected=*/false,
  396. /*pairing_state=*/absl::nullopt);
  397. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  398. AssertInputDevicesStatus(
  399. {.pointer_is_missing = true, .keyboard_is_missing = true});
  400. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0,
  401. /*total_count=*/0);
  402. std::string touchscreen_id1;
  403. AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO,
  404. &touchscreen_id1);
  405. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  406. AssertHidDetectionStatus(
  407. /*pointer_metadata=*/{InputState::kSearching,
  408. /*detected_hid_name=*/""},
  409. /*keyboard_metadata=*/
  410. {InputState::kSearching, /*detected_hid_name=*/""},
  411. /*touchscreen_detected=*/true,
  412. /*pairing_state=*/absl::nullopt);
  413. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  414. AssertInputDevicesStatus(
  415. {.pointer_is_missing = true, .keyboard_is_missing = true});
  416. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/1,
  417. /*total_count=*/1);
  418. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/0,
  419. /*total_count=*/0);
  420. RemoveDevice(touchscreen_id1);
  421. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  422. AssertHidDetectionStatus(
  423. /*pointer_metadata=*/{InputState::kSearching,
  424. /*detected_hid_name=*/""},
  425. /*keyboard_metadata=*/
  426. {InputState::kSearching, /*detected_hid_name=*/""},
  427. /*touchscreen_detected=*/false,
  428. /*pairing_state=*/absl::nullopt);
  429. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  430. AssertInputDevicesStatus(
  431. {.pointer_is_missing = true, .keyboard_is_missing = true});
  432. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/1,
  433. /*total_count=*/1);
  434. StopHidDetection(/*should_be_using_bluetooth=*/false);
  435. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  436. AssertHidDetectionStatus(
  437. /*pointer_metadata=*/{InputState::kSearching,
  438. /*detected_hid_name=*/""},
  439. /*keyboard_metadata=*/
  440. {InputState::kSearching, /*detected_hid_name=*/""},
  441. /*touchscreen_detected=*/false,
  442. /*pairing_state=*/absl::nullopt);
  443. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  444. AssertInputDevicesStatus(
  445. {.pointer_is_missing = true, .keyboard_is_missing = true});
  446. // Add another touchscreen device. This should not inform the delegate.
  447. std::string touchscreen_id2;
  448. AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO,
  449. &touchscreen_id2);
  450. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  451. AssertHidDetectionStatus(
  452. /*pointer_metadata=*/{InputState::kSearching,
  453. /*detected_hid_name=*/""},
  454. /*keyboard_metadata=*/
  455. {InputState::kSearching, /*detected_hid_name=*/""},
  456. /*touchscreen_detected=*/false,
  457. /*pairing_state=*/absl::nullopt);
  458. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  459. AssertInputDevicesStatus(
  460. {.pointer_is_missing = true, .keyboard_is_missing = true});
  461. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/1,
  462. /*total_count=*/1);
  463. // Remove the touchscreen device. This should not inform the delegate.
  464. RemoveDevice(touchscreen_id2);
  465. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  466. AssertHidDetectionStatus(
  467. /*pointer_metadata=*/{InputState::kSearching,
  468. /*detected_hid_name=*/""},
  469. /*keyboard_metadata=*/
  470. {InputState::kSearching, /*detected_hid_name=*/""},
  471. /*touchscreen_detected=*/false,
  472. /*pairing_state=*/absl::nullopt);
  473. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  474. AssertInputDevicesStatus(
  475. {.pointer_is_missing = true, .keyboard_is_missing = true});
  476. AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/1,
  477. /*total_count=*/1);
  478. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/1,
  479. /*total_count=*/1);
  480. }
  481. TEST_F(HidDetectionManagerImplTest,
  482. StartDetection_PointerConnectedDisconnected) {
  483. StartHidDetection();
  484. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  485. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  486. AssertHidDetectionStatus(
  487. /*pointer_metadata=*/{InputState::kSearching,
  488. /*detected_hid_name=*/""},
  489. /*keyboard_metadata=*/
  490. {InputState::kSearching, /*detected_hid_name=*/""},
  491. /*touchscreen_detected=*/false,
  492. /*pairing_state=*/absl::nullopt);
  493. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  494. AssertInputDevicesStatus(
  495. {.pointer_is_missing = true, .keyboard_is_missing = true});
  496. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0,
  497. /*total_count=*/0);
  498. std::string pointer_id1;
  499. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_BLUETOOTH, &pointer_id1);
  500. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  501. AssertHidDetectionStatus(
  502. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, pointer_id1},
  503. /*keyboard_metadata=*/
  504. {InputState::kSearching, /*detected_hid_name=*/""},
  505. /*touchscreen_detected=*/false,
  506. /*pairing_state=*/absl::nullopt);
  507. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  508. AssertInputDevicesStatus(
  509. {.pointer_is_missing = false, .keyboard_is_missing = true});
  510. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1,
  511. /*total_count=*/1);
  512. AssertHidDisconnectedCount(HidType::kBluetoothPointer, /*count=*/0,
  513. /*total_count=*/0);
  514. RemoveDevice(pointer_id1);
  515. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  516. AssertHidDetectionStatus(
  517. /*pointer_metadata=*/{InputState::kSearching,
  518. /*detected_hid_name=*/""},
  519. /*keyboard_metadata=*/
  520. {InputState::kSearching, /*detected_hid_name=*/""},
  521. /*touchscreen_detected=*/false,
  522. /*pairing_state=*/absl::nullopt);
  523. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  524. AssertInputDevicesStatus(
  525. {.pointer_is_missing = true, .keyboard_is_missing = true});
  526. AssertHidDisconnectedCount(HidType::kBluetoothPointer, /*count=*/1,
  527. /*total_count=*/1);
  528. StopHidDetection(/*should_be_using_bluetooth=*/false);
  529. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  530. AssertHidDetectionStatus(
  531. /*pointer_metadata=*/{InputState::kSearching,
  532. /*detected_hid_name=*/""},
  533. /*keyboard_metadata=*/
  534. {InputState::kSearching, /*detected_hid_name=*/""},
  535. /*touchscreen_detected=*/false,
  536. /*pairing_state=*/absl::nullopt);
  537. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  538. AssertInputDevicesStatus(
  539. {.pointer_is_missing = true, .keyboard_is_missing = true});
  540. // Add another pointer device. This should not inform the delegate.
  541. std::string pointer_id2;
  542. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_USB, &pointer_id2);
  543. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  544. AssertHidDetectionStatus(
  545. /*pointer_metadata=*/{InputState::kSearching,
  546. /*detected_hid_name=*/""},
  547. /*keyboard_metadata=*/
  548. {InputState::kSearching, /*detected_hid_name=*/""},
  549. /*touchscreen_detected=*/false,
  550. /*pairing_state=*/absl::nullopt);
  551. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  552. AssertInputDevicesStatus(
  553. {.pointer_is_missing = true, .keyboard_is_missing = true});
  554. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1,
  555. /*total_count=*/1);
  556. // Remove the pointer device. This should not inform the delegate.
  557. RemoveDevice(pointer_id2);
  558. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  559. AssertHidDetectionStatus(
  560. /*pointer_metadata=*/{InputState::kSearching,
  561. /*detected_hid_name=*/""},
  562. /*keyboard_metadata=*/
  563. {InputState::kSearching, /*detected_hid_name=*/""},
  564. /*touchscreen_detected=*/false,
  565. /*pairing_state=*/absl::nullopt);
  566. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  567. AssertInputDevicesStatus(
  568. {.pointer_is_missing = true, .keyboard_is_missing = true});
  569. AssertHidDisconnectedCount(HidType::kBluetoothPointer, /*count=*/1,
  570. /*total_count=*/1);
  571. }
  572. TEST_F(HidDetectionManagerImplTest,
  573. StartDetection_KeyboardConnectedDisconnected) {
  574. StartHidDetection();
  575. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  576. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  577. AssertHidDetectionStatus(
  578. /*pointer_metadata=*/{InputState::kSearching,
  579. /*detected_hid_name=*/""},
  580. /*keyboard_metadata=*/
  581. {InputState::kSearching, /*detected_hid_name=*/""},
  582. /*touchscreen_detected=*/false,
  583. /*pairing_state=*/absl::nullopt);
  584. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  585. AssertInputDevicesStatus(
  586. {.pointer_is_missing = true, .keyboard_is_missing = true});
  587. AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/0,
  588. /*total_count=*/0);
  589. std::string keyboard_id1;
  590. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_USB, &keyboard_id1);
  591. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  592. AssertHidDetectionStatus(
  593. /*pointer_metadata=*/{InputState::kSearching,
  594. /*detected_hid_name=*/""},
  595. /*keyboard_metadata=*/
  596. {InputState::kConnectedViaUsb, keyboard_id1},
  597. /*touchscreen_detected=*/false,
  598. /*pairing_state=*/absl::nullopt);
  599. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  600. AssertInputDevicesStatus(
  601. {.pointer_is_missing = true, .keyboard_is_missing = false});
  602. AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/1,
  603. /*total_count=*/1);
  604. AssertHidDisconnectedCount(HidType::kUsbKeyboard, /*count=*/0,
  605. /*total_count=*/0);
  606. RemoveDevice(keyboard_id1);
  607. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  608. AssertHidDetectionStatus(
  609. /*pointer_metadata=*/{InputState::kSearching,
  610. /*detected_hid_name=*/""},
  611. /*keyboard_metadata=*/
  612. {InputState::kSearching, /*detected_hid_name=*/""},
  613. /*touchscreen_detected=*/false,
  614. /*pairing_state=*/absl::nullopt);
  615. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  616. AssertInputDevicesStatus(
  617. {.pointer_is_missing = true, .keyboard_is_missing = true});
  618. AssertHidDisconnectedCount(HidType::kUsbKeyboard, /*count=*/1,
  619. /*total_count=*/1);
  620. StopHidDetection(/*should_be_using_bluetooth=*/false);
  621. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  622. AssertHidDetectionStatus(
  623. /*pointer_metadata=*/{InputState::kSearching,
  624. /*detected_hid_name=*/""},
  625. /*keyboard_metadata=*/
  626. {InputState::kSearching, /*detected_hid_name=*/""},
  627. /*touchscreen_detected=*/false,
  628. /*pairing_state=*/absl::nullopt);
  629. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  630. AssertInputDevicesStatus(
  631. {.pointer_is_missing = true, .keyboard_is_missing = true});
  632. // Add another keyboard device. This should not inform the delegate.
  633. std::string keyboard_id2;
  634. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_USB, &keyboard_id2);
  635. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  636. AssertHidDetectionStatus(
  637. /*pointer_metadata=*/{InputState::kSearching,
  638. /*detected_hid_name=*/""},
  639. /*keyboard_metadata=*/
  640. {InputState::kSearching, /*detected_hid_name=*/""},
  641. /*touchscreen_detected=*/false,
  642. /*pairing_state=*/absl::nullopt);
  643. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  644. AssertInputDevicesStatus(
  645. {.pointer_is_missing = true, .keyboard_is_missing = true});
  646. AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/1,
  647. /*total_count=*/1);
  648. // Remove the keyboard device. This should not inform the delegate.
  649. RemoveDevice(keyboard_id2);
  650. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  651. AssertHidDetectionStatus(
  652. /*pointer_metadata=*/{InputState::kSearching,
  653. /*detected_hid_name=*/""},
  654. /*keyboard_metadata=*/
  655. {InputState::kSearching, /*detected_hid_name=*/""},
  656. /*touchscreen_detected=*/false,
  657. /*pairing_state=*/absl::nullopt);
  658. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  659. AssertInputDevicesStatus(
  660. {.pointer_is_missing = true, .keyboard_is_missing = true});
  661. AssertHidDisconnectedCount(HidType::kUsbKeyboard, /*count=*/1,
  662. /*total_count=*/1);
  663. }
  664. TEST_F(HidDetectionManagerImplTest,
  665. StartDetection_MultipleTouchscreensDisconnected) {
  666. std::string device_id1;
  667. AddDevice(TestHidType::kTablet, InputDeviceType::TYPE_SERIO, &device_id1);
  668. std::string device_id2;
  669. AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO,
  670. &device_id2);
  671. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  672. StartHidDetection();
  673. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  674. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  675. AssertHidDetectionStatus(
  676. /*pointer_metadata=*/{InputState::kSearching,
  677. /*detected_hid_name=*/""},
  678. /*keyboard_metadata=*/
  679. {InputState::kSearching, /*detected_hid_name=*/""},
  680. /*touchscreen_detected=*/true,
  681. /*pairing_state=*/absl::nullopt);
  682. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  683. AssertInputDevicesStatus(
  684. {.pointer_is_missing = true, .keyboard_is_missing = true});
  685. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/0,
  686. /*total_count=*/0);
  687. // Remove the first touchscreen device. The second touchscreen should be
  688. // detected and delegate notified.
  689. RemoveDevice(device_id1);
  690. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  691. AssertHidDetectionStatus(
  692. /*pointer_metadata=*/{InputState::kSearching,
  693. /*detected_hid_name=*/""},
  694. /*keyboard_metadata=*/
  695. {InputState::kSearching, /*detected_hid_name=*/""},
  696. /*touchscreen_detected=*/true,
  697. /*pairing_state=*/absl::nullopt);
  698. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  699. AssertInputDevicesStatus(
  700. {.pointer_is_missing = true, .keyboard_is_missing = true});
  701. AssertHidDisconnectedCount(HidType::kTouchscreen, /*count=*/1,
  702. /*total_count=*/1);
  703. StopHidDetection(/*should_be_using_bluetooth=*/false);
  704. }
  705. TEST_F(HidDetectionManagerImplTest,
  706. StartDetection_MultiplePointersDisconnected) {
  707. std::string device_id1;
  708. AddDevice(TestHidType::kTouchpad, InputDeviceType::TYPE_UNKNOWN, &device_id1);
  709. std::string device_id2;
  710. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_BLUETOOTH, &device_id2);
  711. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  712. StartHidDetection();
  713. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  714. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  715. AssertHidDetectionStatus(
  716. /*pointer_metadata=*/{InputState::kConnected, device_id1},
  717. /*keyboard_metadata=*/
  718. {InputState::kSearching, /*detected_hid_name=*/""},
  719. /*touchscreen_detected=*/false,
  720. /*pairing_state=*/absl::nullopt);
  721. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  722. AssertInputDevicesStatus(
  723. {.pointer_is_missing = false, .keyboard_is_missing = true});
  724. AssertHidDisconnectedCount(HidType::kUnknownPointer, /*count=*/0,
  725. /*total_count=*/0);
  726. // Remove the first pointer. The second pointer should be detected and
  727. // delegate notified.
  728. RemoveDevice(device_id1);
  729. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  730. AssertHidDetectionStatus(
  731. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, device_id2},
  732. /*keyboard_metadata=*/
  733. {InputState::kSearching, /*detected_hid_name=*/""},
  734. /*touchscreen_detected=*/false,
  735. /*pairing_state=*/absl::nullopt);
  736. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  737. AssertInputDevicesStatus(
  738. {.pointer_is_missing = false, .keyboard_is_missing = true});
  739. AssertHidDisconnectedCount(HidType::kUnknownPointer, /*count=*/1,
  740. /*total_count=*/1);
  741. StopHidDetection(/*should_be_using_bluetooth=*/true);
  742. }
  743. TEST_F(HidDetectionManagerImplTest,
  744. StartDetection_MultipleKeyboardsDisconnected) {
  745. std::string device_id1;
  746. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_BLUETOOTH,
  747. &device_id1);
  748. std::string device_id2;
  749. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_SERIO, &device_id2);
  750. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  751. StartHidDetection();
  752. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  753. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  754. AssertHidDetectionStatus(
  755. /*pointer_metadata=*/{InputState::kSearching,
  756. /*detected_hid_name=*/""},
  757. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, device_id1},
  758. /*touchscreen_detected=*/false,
  759. /*pairing_state=*/absl::nullopt);
  760. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  761. AssertInputDevicesStatus(
  762. {.pointer_is_missing = true, .keyboard_is_missing = false});
  763. AssertHidDisconnectedCount(HidType::kBluetoothKeyboard, /*count=*/0,
  764. /*total_count=*/0);
  765. // Remove the first keyboard. The second keyboard should be detected and
  766. // delegate notified.
  767. RemoveDevice(device_id1);
  768. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  769. AssertHidDetectionStatus(
  770. /*pointer_metadata=*/{InputState::kSearching,
  771. /*detected_hid_name=*/""},
  772. /*keyboard_metadata=*/{InputState::kConnected, device_id2},
  773. /*touchscreen_detected=*/false,
  774. /*pairing_state=*/absl::nullopt);
  775. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  776. AssertInputDevicesStatus(
  777. {.pointer_is_missing = true, .keyboard_is_missing = false});
  778. AssertHidDisconnectedCount(HidType::kBluetoothKeyboard, /*count=*/1,
  779. /*total_count=*/1);
  780. StopHidDetection(/*should_be_using_bluetooth=*/false);
  781. }
  782. TEST_F(HidDetectionManagerImplTest,
  783. StartDetection_DeviceMultipleHidTypesDisconnected) {
  784. std::string device_id1;
  785. AddDevice(TestHidType::kTouchpad, InputDeviceType::TYPE_USB, &device_id1);
  786. std::string device_id2;
  787. std::vector<TestHidType> hid_types{TestHidType::kKeyboard,
  788. TestHidType::kTouchpad};
  789. AddDevice(hid_types, InputDeviceType::TYPE_SERIO, &device_id2);
  790. std::string device_id3;
  791. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_UNKNOWN, &device_id3);
  792. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  793. StartHidDetection();
  794. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  795. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  796. AssertHidDetectionStatus(
  797. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  798. /*keyboard_metadata=*/{InputState::kConnected, device_id2},
  799. /*touchscreen_detected=*/false,
  800. /*pairing_state=*/absl::nullopt);
  801. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  802. AssertInputDevicesStatus(
  803. {.pointer_is_missing = false, .keyboard_is_missing = false});
  804. AssertHidDisconnectedCount(HidType::kUsbPointer, /*count=*/0,
  805. /*total_count=*/0);
  806. RemoveDevice(device_id1);
  807. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  808. AssertHidDetectionStatus(
  809. /*pointer_metadata=*/{InputState::kConnected, device_id2},
  810. /*keyboard_metadata=*/{InputState::kConnected, device_id2},
  811. /*touchscreen_detected=*/false,
  812. /*pairing_state=*/absl::nullopt);
  813. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  814. AssertInputDevicesStatus(
  815. {.pointer_is_missing = false, .keyboard_is_missing = false});
  816. AssertHidDisconnectedCount(HidType::kUsbPointer, /*count=*/1,
  817. /*total_count=*/1);
  818. AssertHidDisconnectedCount(HidType::kSerialPointer, /*count=*/0,
  819. /*total_count=*/1);
  820. RemoveDevice(device_id2);
  821. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  822. AssertHidDetectionStatus(
  823. /*pointer_metadata=*/{InputState::kSearching,
  824. /*detected_hid_name=*/""},
  825. /*keyboard_metadata=*/{InputState::kConnected, device_id3},
  826. /*touchscreen_detected=*/false,
  827. /*pairing_state=*/absl::nullopt);
  828. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  829. AssertInputDevicesStatus(
  830. {.pointer_is_missing = true, .keyboard_is_missing = false});
  831. AssertHidDisconnectedCount(HidType::kUsbPointer, /*count=*/1,
  832. /*total_count=*/2);
  833. AssertHidDisconnectedCount(HidType::kSerialPointer, /*count=*/1,
  834. /*total_count=*/2);
  835. StopHidDetection(/*should_be_using_bluetooth=*/false);
  836. }
  837. // TODO(gordonseto): Test add device for type already connected, remove device
  838. // for type already connected.
  839. TEST_F(HidDetectionManagerImplTest, StartDetection_BluetoothPointerSuccess) {
  840. StartHidDetection();
  841. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  842. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  843. AssertHidDetectionStatus(
  844. /*pointer_metadata=*/{InputState::kSearching,
  845. /*detected_hid_name=*/""},
  846. /*keyboard_metadata=*/
  847. {InputState::kSearching, /*detected_hid_name=*/""},
  848. /*touchscreen_detected=*/false,
  849. /*pairing_state=*/absl::nullopt);
  850. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  851. AssertInputDevicesStatus(
  852. {.pointer_is_missing = true, .keyboard_is_missing = true});
  853. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0,
  854. /*total_count=*/0);
  855. SimulatePairingStarted(
  856. BluetoothHidMetadata{kTestHidName, BluetoothHidType::kPointer});
  857. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  858. AssertHidDetectionStatus(
  859. /*pointer_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  860. /*keyboard_metadata=*/
  861. {InputState::kSearching, /*detected_hid_name=*/""},
  862. /*touchscreen_detected=*/false,
  863. /*pairing_state=*/absl::nullopt);
  864. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  865. AssertInputDevicesStatus(
  866. {.pointer_is_missing = true, .keyboard_is_missing = true});
  867. // Simulate the pairing succeeding.
  868. AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_BLUETOOTH,
  869. /*id_out=*/nullptr, kTestHidName);
  870. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  871. AssertHidDetectionStatus(
  872. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  873. /*keyboard_metadata=*/
  874. {InputState::kSearching, /*detected_hid_name=*/""},
  875. /*touchscreen_detected=*/false,
  876. /*pairing_state=*/absl::nullopt);
  877. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  878. AssertInputDevicesStatus(
  879. {.pointer_is_missing = false, .keyboard_is_missing = true});
  880. AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1,
  881. /*total_count=*/1);
  882. SimulatePairingSessionEnded();
  883. EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
  884. AssertHidDetectionStatus(
  885. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  886. /*keyboard_metadata=*/
  887. {InputState::kSearching, /*detected_hid_name=*/""},
  888. /*touchscreen_detected=*/false,
  889. /*pairing_state=*/absl::nullopt);
  890. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  891. AssertInputDevicesStatus(
  892. {.pointer_is_missing = false, .keyboard_is_missing = true});
  893. StopHidDetection(/*should_be_using_bluetooth=*/true);
  894. }
  895. TEST_F(HidDetectionManagerImplTest, StartDetection_BluetoothPointerFailure) {
  896. StartHidDetection();
  897. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  898. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  899. AssertHidDetectionStatus(
  900. /*pointer_metadata=*/{InputState::kSearching,
  901. /*detected_hid_name=*/""},
  902. /*keyboard_metadata=*/
  903. {InputState::kSearching, /*detected_hid_name=*/""},
  904. /*touchscreen_detected=*/false,
  905. /*pairing_state=*/absl::nullopt);
  906. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  907. AssertInputDevicesStatus(
  908. {.pointer_is_missing = true, .keyboard_is_missing = true});
  909. SimulatePairingStarted(
  910. BluetoothHidMetadata{kTestHidName, BluetoothHidType::kPointer});
  911. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  912. AssertHidDetectionStatus(
  913. /*pointer_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  914. /*keyboard_metadata=*/
  915. {InputState::kSearching, /*detected_hid_name=*/""},
  916. /*touchscreen_detected=*/false,
  917. /*pairing_state=*/absl::nullopt);
  918. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  919. AssertInputDevicesStatus(
  920. {.pointer_is_missing = true, .keyboard_is_missing = true});
  921. // Simulate the pairing failing.
  922. SimulatePairingSessionEnded();
  923. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  924. AssertHidDetectionStatus(
  925. /*pointer_metadata=*/{InputState::kSearching,
  926. /*detected_hid_name=*/""},
  927. /*keyboard_metadata=*/
  928. {InputState::kSearching, /*detected_hid_name=*/""},
  929. /*touchscreen_detected=*/false,
  930. /*pairing_state=*/absl::nullopt);
  931. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  932. AssertInputDevicesStatus(
  933. {.pointer_is_missing = true, .keyboard_is_missing = true});
  934. StopHidDetection(/*should_be_using_bluetooth=*/false);
  935. }
  936. TEST_F(HidDetectionManagerImplTest, StartDetection_BluetoothKeyboardSuccess) {
  937. StartHidDetection();
  938. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  939. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  940. AssertHidDetectionStatus(
  941. /*pointer_metadata=*/{InputState::kSearching,
  942. /*detected_hid_name=*/""},
  943. /*keyboard_metadata=*/
  944. {InputState::kSearching, /*detected_hid_name=*/""},
  945. /*touchscreen_detected=*/false,
  946. /*pairing_state=*/absl::nullopt);
  947. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  948. AssertInputDevicesStatus(
  949. {.pointer_is_missing = true, .keyboard_is_missing = true});
  950. AssertHidConnectedCount(HidType::kBluetoothKeyboard, /*count=*/0,
  951. /*total_count=*/0);
  952. SimulatePairingStarted(
  953. BluetoothHidMetadata{kTestHidName, BluetoothHidType::kKeyboard});
  954. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  955. AssertHidDetectionStatus(
  956. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  957. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  958. /*touchscreen_detected=*/false,
  959. /*pairing_state=*/absl::nullopt);
  960. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  961. AssertInputDevicesStatus(
  962. {.pointer_is_missing = true, .keyboard_is_missing = true});
  963. absl::optional<BluetoothHidPairingState> pairing_state =
  964. BluetoothHidPairingState{kTestPinCode, /*num_keys_entered=*/6};
  965. SimulatePairingCodeRequired(pairing_state.value());
  966. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  967. AssertHidDetectionStatus(
  968. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  969. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  970. /*touchscreen_detected=*/false, pairing_state);
  971. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  972. AssertInputDevicesStatus(
  973. {.pointer_is_missing = true, .keyboard_is_missing = true});
  974. // Simulate the pairing succeeding.
  975. AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_BLUETOOTH,
  976. /*id_out=*/nullptr, kTestHidName);
  977. AssertHidConnectedCount(HidType::kBluetoothKeyboard, /*count=*/1,
  978. /*total_count=*/1);
  979. EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
  980. AssertHidDetectionStatus(
  981. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  982. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  983. /*touchscreen_detected=*/false, pairing_state);
  984. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  985. AssertInputDevicesStatus(
  986. {.pointer_is_missing = true, .keyboard_is_missing = false});
  987. SimulatePairingSessionEnded();
  988. EXPECT_EQ(5u, GetNumHidDetectionStatusChangedCalls());
  989. AssertHidDetectionStatus(
  990. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  991. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  992. /*touchscreen_detected=*/false,
  993. /*pairing_state=*/absl::nullopt);
  994. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  995. AssertInputDevicesStatus(
  996. {.pointer_is_missing = true, .keyboard_is_missing = false});
  997. StopHidDetection(/*should_be_using_bluetooth=*/true);
  998. }
  999. TEST_F(HidDetectionManagerImplTest, StartDetection_BluetoothKeyboardFailure) {
  1000. StartHidDetection();
  1001. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  1002. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  1003. AssertHidDetectionStatus(
  1004. /*pointer_metadata=*/{InputState::kSearching,
  1005. /*detected_hid_name=*/""},
  1006. /*keyboard_metadata=*/
  1007. {InputState::kSearching, /*detected_hid_name=*/""},
  1008. /*touchscreen_detected=*/false,
  1009. /*pairing_state=*/absl::nullopt);
  1010. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1011. AssertInputDevicesStatus(
  1012. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1013. SimulatePairingStarted(
  1014. BluetoothHidMetadata{kTestHidName, BluetoothHidType::kKeyboard});
  1015. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  1016. AssertHidDetectionStatus(
  1017. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  1018. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1019. /*touchscreen_detected=*/false,
  1020. /*pairing_state=*/absl::nullopt);
  1021. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1022. AssertInputDevicesStatus(
  1023. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1024. absl::optional<BluetoothHidPairingState> pairing_state =
  1025. BluetoothHidPairingState{kTestPinCode, /*num_keys_entered=*/6};
  1026. SimulatePairingCodeRequired(pairing_state.value());
  1027. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  1028. AssertHidDetectionStatus(
  1029. /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
  1030. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1031. /*touchscreen_detected=*/false, pairing_state);
  1032. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1033. AssertInputDevicesStatus(
  1034. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1035. // Simulate the pairing failing.
  1036. SimulatePairingSessionEnded();
  1037. EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
  1038. AssertHidDetectionStatus(
  1039. /*pointer_metadata=*/{InputState::kSearching,
  1040. /*detected_hid_name=*/""},
  1041. /*keyboard_metadata=*/
  1042. {InputState::kSearching, /*detected_hid_name=*/""},
  1043. /*touchscreen_detected=*/false,
  1044. /*pairing_state=*/absl::nullopt);
  1045. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1046. AssertInputDevicesStatus(
  1047. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1048. StopHidDetection(/*should_be_using_bluetooth=*/false);
  1049. }
  1050. TEST_F(HidDetectionManagerImplTest,
  1051. StartDetection_BluetoothKeyboardPointerComboSuccess) {
  1052. StartHidDetection();
  1053. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  1054. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  1055. AssertHidDetectionStatus(
  1056. /*pointer_metadata=*/{InputState::kSearching,
  1057. /*detected_hid_name=*/""},
  1058. /*keyboard_metadata=*/
  1059. {InputState::kSearching, /*detected_hid_name=*/""},
  1060. /*touchscreen_detected=*/false,
  1061. /*pairing_state=*/absl::nullopt);
  1062. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1063. AssertInputDevicesStatus(
  1064. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1065. SimulatePairingStarted(BluetoothHidMetadata{
  1066. kTestHidName, BluetoothHidType::kKeyboardPointerCombo});
  1067. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  1068. AssertHidDetectionStatus(
  1069. /*pointer_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1070. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1071. /*touchscreen_detected=*/false,
  1072. /*pairing_state=*/absl::nullopt);
  1073. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1074. AssertInputDevicesStatus(
  1075. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1076. // Simulate the pairing succeeding.
  1077. AddDevice(std::vector{TestHidType::kKeyboard, TestHidType::kTouchpad},
  1078. InputDeviceType::TYPE_BLUETOOTH,
  1079. /*id_out=*/nullptr, kTestHidName);
  1080. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  1081. AssertHidDetectionStatus(
  1082. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1083. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1084. /*touchscreen_detected=*/false,
  1085. /*pairing_state=*/absl::nullopt);
  1086. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  1087. AssertInputDevicesStatus(
  1088. {.pointer_is_missing = false, .keyboard_is_missing = false});
  1089. SimulatePairingSessionEnded();
  1090. EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
  1091. AssertHidDetectionStatus(
  1092. /*pointer_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1093. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1094. /*touchscreen_detected=*/false,
  1095. /*pairing_state=*/absl::nullopt);
  1096. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  1097. AssertInputDevicesStatus(
  1098. {.pointer_is_missing = false, .keyboard_is_missing = false});
  1099. StopHidDetection(/*should_be_using_bluetooth=*/true);
  1100. }
  1101. TEST_F(HidDetectionManagerImplTest,
  1102. StartDetection_BluetoothKeyboardComboFailure) {
  1103. StartHidDetection();
  1104. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  1105. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  1106. AssertHidDetectionStatus(
  1107. /*pointer_metadata=*/{InputState::kSearching,
  1108. /*detected_hid_name=*/""},
  1109. /*keyboard_metadata=*/
  1110. {InputState::kSearching, /*detected_hid_name=*/""},
  1111. /*touchscreen_detected=*/false,
  1112. /*pairing_state=*/absl::nullopt);
  1113. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1114. AssertInputDevicesStatus(
  1115. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1116. SimulatePairingStarted(BluetoothHidMetadata{
  1117. kTestHidName, BluetoothHidType::kKeyboardPointerCombo});
  1118. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  1119. AssertHidDetectionStatus(
  1120. /*pointer_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1121. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1122. /*touchscreen_detected=*/false,
  1123. /*pairing_state=*/absl::nullopt);
  1124. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1125. AssertInputDevicesStatus(
  1126. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1127. // Simulate the pairing failing.
  1128. SimulatePairingSessionEnded();
  1129. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  1130. AssertHidDetectionStatus(
  1131. /*pointer_metadata=*/{InputState::kSearching,
  1132. /*detected_hid_name=*/""},
  1133. /*keyboard_metadata=*/
  1134. {InputState::kSearching, /*detected_hid_name=*/""},
  1135. /*touchscreen_detected=*/false,
  1136. /*pairing_state=*/absl::nullopt);
  1137. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1138. AssertInputDevicesStatus(
  1139. {.pointer_is_missing = true, .keyboard_is_missing = true});
  1140. StopHidDetection(/*should_be_using_bluetooth=*/false);
  1141. }
  1142. TEST_F(HidDetectionManagerImplTest,
  1143. StartDetection_BluetoothKeyboardPointerComboPointerPreConnected) {
  1144. std::string device_id1;
  1145. AddDevice(TestHidType::kTouchpad, InputDeviceType::TYPE_USB, &device_id1);
  1146. EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
  1147. StartHidDetection();
  1148. EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
  1149. ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
  1150. AssertHidDetectionStatus(
  1151. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  1152. /*keyboard_metadata=*/
  1153. {InputState::kSearching, /*detected_hid_name=*/""},
  1154. /*touchscreen_detected=*/false,
  1155. /*pairing_state=*/absl::nullopt);
  1156. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1157. AssertInputDevicesStatus(
  1158. {.pointer_is_missing = false, .keyboard_is_missing = true});
  1159. SimulatePairingStarted(BluetoothHidMetadata{
  1160. kTestHidName, BluetoothHidType::kKeyboardPointerCombo});
  1161. EXPECT_EQ(2u, GetNumHidDetectionStatusChangedCalls());
  1162. AssertHidDetectionStatus(
  1163. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  1164. /*keyboard_metadata=*/{InputState::kPairingViaBluetooth, kTestHidName},
  1165. /*touchscreen_detected=*/false,
  1166. /*pairing_state=*/absl::nullopt);
  1167. EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
  1168. AssertInputDevicesStatus(
  1169. {.pointer_is_missing = false, .keyboard_is_missing = true});
  1170. // Simulate the pairing succeeding.
  1171. std::string device_id2;
  1172. AddDevice(std::vector{TestHidType::kKeyboard, TestHidType::kTouchpad},
  1173. InputDeviceType::TYPE_BLUETOOTH, &device_id2, kTestHidName);
  1174. EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
  1175. AssertHidDetectionStatus(
  1176. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  1177. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1178. /*touchscreen_detected=*/false,
  1179. /*pairing_state=*/absl::nullopt);
  1180. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  1181. AssertInputDevicesStatus(
  1182. {.pointer_is_missing = false, .keyboard_is_missing = false});
  1183. SimulatePairingSessionEnded();
  1184. EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
  1185. AssertHidDetectionStatus(
  1186. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  1187. /*keyboard_metadata=*/{InputState::kPairedViaBluetooth, kTestHidName},
  1188. /*touchscreen_detected=*/false,
  1189. /*pairing_state=*/absl::nullopt);
  1190. EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
  1191. AssertInputDevicesStatus(
  1192. {.pointer_is_missing = false, .keyboard_is_missing = false});
  1193. // Disconnect the Bluetooth device.
  1194. RemoveDevice(device_id2);
  1195. EXPECT_EQ(5u, GetNumHidDetectionStatusChangedCalls());
  1196. AssertHidDetectionStatus(
  1197. /*pointer_metadata=*/{InputState::kConnectedViaUsb, device_id1},
  1198. /*keyboard_metadata=*/
  1199. {InputState::kSearching, /*detected_hid_name=*/""},
  1200. /*touchscreen_detected=*/false,
  1201. /*pairing_state=*/absl::nullopt);
  1202. EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
  1203. AssertInputDevicesStatus(
  1204. {.pointer_is_missing = false, .keyboard_is_missing = true});
  1205. StopHidDetection(/*should_be_using_bluetooth=*/false);
  1206. }
  1207. } // namespace ash::hid_detection