keyboard stuff
at master 444 lines 15 kB view raw
1/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17#include "gtest/gtest.h" 18 19extern "C" { 20#include "os_detection.h" 21#include "timer.h" 22 23void advance_time(uint32_t ms); 24} 25 26static uint32_t reported_count; 27static os_variant_t reported_os; 28 29class OsDetectionTest : public ::testing::Test { 30 protected: 31 void SetUp() override { 32 erase_wlength_data(); 33 reported_count = 0; 34 reported_os = OS_UNSURE; 35 } 36}; 37 38os_variant_t check_sequence(const std::vector<uint16_t> &w_lengths) { 39 for (auto &w_length : w_lengths) { 40 process_wlength(w_length); 41 } 42 return detected_host_os(); 43} 44 45bool process_detected_host_os_kb(os_variant_t os) { 46 reported_count = reported_count + 1; 47 reported_os = os; 48 49 return true; 50} 51 52void assert_not_reported(void) { 53 // check that it does not report the result, nor any intermediate results 54 EXPECT_EQ(reported_count, 0); 55 EXPECT_EQ(reported_os, OS_UNSURE); 56} 57 58void assert_reported(os_variant_t os) { 59 // check that it reports exclusively the result, not any intermediate results 60 EXPECT_EQ(reported_count, 1); 61 EXPECT_EQ(reported_os, os); 62 EXPECT_EQ(reported_os, detected_host_os()); 63} 64 65/* Some collected data. 66 67ChibiOS: 68Windows 10: [FF, FF, 4, 24, 4, 24, 4, FF, 24, FF, 4, FF, 24, 4, 24, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A] 69Windows 10 (another host): [FF, FF, 4, 24, 4, 24, 4, 24, 4, 24, 4, 24] 70macOS 12.5: [2, 24, 2, 28, FF] 71macOS 15.1.x: [ 2, 4E, 2, 1C, 2, 1A, FF, FF] 72macOS 15.x (another host): [ 2, 0E, 2, 1E, 2, 42, FF] 73macOS 15.x (periodic weirdness): [ 2, 42, 2, 1C, 2, 1A, FF, 2, 42, 2, 1C, 2, 1A, FF ] 74iOS/iPadOS 15.6: [2, 24, 2, 28] 75Linux (including Android, Raspberry Pi and WebOS TV): [FF, FF, FF] 76Linux (another host): [FF, FF, FF, FF, FF, FF] 77PS5: [2, 4, 2, 28, 2, 24] 78Nintendo Switch: [82, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40] 79Quest 2: [FF, FF, FF, FE, FF, FE, FF, FE, FF, FE, FF] 80 81LUFA: 82Windows 10 (first connect): [12, FF, FF, 4, 10, FF, FF, FF, 4, 10, 20A, 20A, 20A, 20A, 20A, 20A] 83Windows 10 (subsequent connect): [FF, FF, 4, 10, FF, 4, FF, 10, FF, 20A, 20A, 20A, 20A, 20A, 20A] 84Windows 10 (another host): [FF, FF, 4, 10, 4, 10] 85macOS: [2, 10, 2, E, FF] 86macOS 15.x: [ 2, 64, 2, 28, FF, FF] 87iOS/iPadOS: [2, 10, 2, E] 88Linux: [FF, FF, FF] 89PS5: [2, 4, 2, E, 2, 10] 90Nintendo Switch: [82, FF, 40, 40, FF, 40, 40] 91 92V-USB: 93Windows 10: [FF, FF, 4, E, FF] 94Windows 10 (another host): [FF, FF, 4, E, 4] 95macOS: [2, E, 2, E, FF] 96iOS/iPadOS: [2, E, 2, E] 97Linux: [FF, FF, FF] 98PS5: [2, 4, 2, E, 2] 99Nintendo Switch: [82, FF, 40, 40] 100Quest 2: [FF, FF, FF, FE] 101 102Common parts: 103Windows: [..., FF, FF, 4, ...] 104macOS: [2, _, 2, _, FF] 105iOS/iPadOS: [2, _, 2, _] 106Linux: [FF, FF, FF] 107PS5: [2, 4, 2, _, 2, ...] 108Nintendo Switch: [82, FF, 40, 40, ...] 109Quest 2: [FF, FF, FF, FE, ...] 110*/ 111TEST_F(OsDetectionTest, TestLinux) { 112 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF}), OS_LINUX); 113 os_detection_task(); 114 assert_not_reported(); 115} 116 117TEST_F(OsDetectionTest, TestChibiosLinux) { 118 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}), OS_LINUX); 119 os_detection_task(); 120 assert_not_reported(); 121} 122 123TEST_F(OsDetectionTest, TestChibiosMacos) { 124 EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28, 0xFF}), OS_MACOS); 125 os_detection_task(); 126 assert_not_reported(); 127} 128 129TEST_F(OsDetectionTest, TestChibiosMacos2) { 130 EXPECT_EQ(check_sequence({0x2, 0x42, 0x2, 0x1C, 0x2, 0x1A, 0xFF}), OS_MACOS); 131 os_detection_task(); 132 assert_not_reported(); 133} 134 135TEST_F(OsDetectionTest, TestChibiosMacos3) { 136 EXPECT_EQ(check_sequence({0x2, 0x42, 0x2, 0x1C, 0x2, 0x1A, 0xFF, 0x2, 0x42, 0x2, 0x1C, 0x2, 0x1A, 0xFF}), OS_MACOS); 137 os_detection_task(); 138 assert_not_reported(); 139} 140 141// Regression reported in https://github.com/qmk/qmk_firmware/pull/21777#issuecomment-1922815841 142TEST_F(OsDetectionTest, TestChibiosMacM1) { 143 EXPECT_EQ(check_sequence({0x02, 0x32, 0x02, 0x24, 0x101, 0xFF}), OS_MACOS); 144 os_detection_task(); 145 assert_not_reported(); 146} 147 148TEST_F(OsDetectionTest, TestChibiosMacSequoia) { 149 EXPECT_EQ(check_sequence({0x02, 0x4E, 0x02, 0x1C, 0x02, 0x1A, 0xFF, 0xFF}), OS_MACOS); 150 os_detection_task(); 151 assert_not_reported(); 152} 153 154TEST_F(OsDetectionTest, TestChibiosMacSequoia2) { 155 EXPECT_EQ(check_sequence({0x02, 0x4E, 0x02, 0x1C, 0x02, 0x1A, 0xFF, 0x02, 0x42, 0x02, 0x1C, 0x02, 0x1A, 0xFF}), OS_MACOS); 156 os_detection_task(); 157 assert_not_reported(); 158} 159 160TEST_F(OsDetectionTest, TestChibiosMacSequoia3) { 161 EXPECT_EQ(check_sequence({0x02, 0x0E, 0x02, 0x1E, 0x02, 0x42, 0xFF}), OS_MACOS); 162 os_detection_task(); 163 assert_not_reported(); 164} 165 166TEST_F(OsDetectionTest, TestLufaMacos) { 167 EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE, 0xFF}), OS_MACOS); 168 os_detection_task(); 169 assert_not_reported(); 170} 171 172TEST_F(OsDetectionTest, TestDetectLufaMacSequoia2) { 173 EXPECT_EQ(check_sequence({0x02, 0x64, 0x02, 0x28, 0xFF, 0xFF}), OS_MACOS); 174 os_detection_task(); 175 assert_not_reported(); 176} 177 178TEST_F(OsDetectionTest, TestVusbMacos) { 179 EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE, 0xFF}), OS_MACOS); 180 os_detection_task(); 181 assert_not_reported(); 182} 183 184TEST_F(OsDetectionTest, TestChibiosIos) { 185 EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28}), OS_IOS); 186 os_detection_task(); 187 assert_not_reported(); 188} 189 190TEST_F(OsDetectionTest, TestLufaIos) { 191 EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE}), OS_IOS); 192 os_detection_task(); 193 assert_not_reported(); 194} 195 196TEST_F(OsDetectionTest, TestVusbIos) { 197 EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE}), OS_IOS); 198 os_detection_task(); 199 assert_not_reported(); 200} 201 202TEST_F(OsDetectionTest, TestChibiosWindows10) { 203 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0xFF, 0x24, 0xFF, 0x4, 0xFF, 0x24, 0x4, 0x24, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 204 os_detection_task(); 205 assert_not_reported(); 206} 207 208TEST_F(OsDetectionTest, TestChibiosWindows10_2) { 209 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24}), OS_WINDOWS); 210 os_detection_task(); 211 assert_not_reported(); 212} 213 214TEST_F(OsDetectionTest, TestLufaWindows10) { 215 EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 216 os_detection_task(); 217 assert_not_reported(); 218} 219 220TEST_F(OsDetectionTest, TestLufaWindows10_2) { 221 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0xFF, 0x4, 0xFF, 0x10, 0xFF, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 222 os_detection_task(); 223 assert_not_reported(); 224} 225 226TEST_F(OsDetectionTest, TestLufaWindows10_3) { 227 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0x4, 0x10}), OS_WINDOWS); 228 os_detection_task(); 229 assert_not_reported(); 230} 231 232TEST_F(OsDetectionTest, TestVusbWindows10) { 233 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0xFF}), OS_WINDOWS); 234 os_detection_task(); 235 assert_not_reported(); 236} 237 238TEST_F(OsDetectionTest, TestVusbWindows10_2) { 239 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0x4}), OS_WINDOWS); 240 os_detection_task(); 241 assert_not_reported(); 242} 243 244TEST_F(OsDetectionTest, TestChibiosPs5) { 245 EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0x28, 0x2, 0x24}), OS_LINUX); 246 os_detection_task(); 247 assert_not_reported(); 248} 249 250TEST_F(OsDetectionTest, TestLufaPs5) { 251 EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2, 0x10}), OS_LINUX); 252 os_detection_task(); 253 assert_not_reported(); 254} 255 256TEST_F(OsDetectionTest, TestVusbPs5) { 257 EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2}), OS_LINUX); 258 os_detection_task(); 259 assert_not_reported(); 260} 261 262TEST_F(OsDetectionTest, TestChibiosNintendoSwitch) { 263 EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); 264 os_detection_task(); 265 assert_not_reported(); 266} 267 268TEST_F(OsDetectionTest, TestLufaNintendoSwitch) { 269 EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); 270 os_detection_task(); 271 assert_not_reported(); 272} 273 274TEST_F(OsDetectionTest, TestVusbNintendoSwitch) { 275 EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40}), OS_LINUX); 276 os_detection_task(); 277 assert_not_reported(); 278} 279 280TEST_F(OsDetectionTest, TestChibiosQuest2) { 281 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF}), OS_LINUX); 282 os_detection_task(); 283 assert_not_reported(); 284} 285 286TEST_F(OsDetectionTest, TestVusbQuest2) { 287 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); 288 os_detection_task(); 289 assert_not_reported(); 290} 291 292TEST_F(OsDetectionTest, TestDoNotReportIfUsbUnstable) { 293 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); 294 os_detection_task(); 295 assert_not_reported(); 296 297 advance_time(OS_DETECTION_DEBOUNCE); 298 os_detection_task(); 299 assert_not_reported(); 300 EXPECT_EQ(detected_host_os(), OS_LINUX); 301} 302 303static struct usb_device_state usb_device_state_configured = {.configure_state = USB_DEVICE_STATE_CONFIGURED}; 304 305TEST_F(OsDetectionTest, TestReportAfterDebounce) { 306 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); 307 os_detection_notify_usb_device_state_change(usb_device_state_configured); 308 os_detection_task(); 309 assert_not_reported(); 310 311 advance_time(1); 312 os_detection_task(); 313 assert_not_reported(); 314 EXPECT_EQ(detected_host_os(), OS_LINUX); 315 316 advance_time(OS_DETECTION_DEBOUNCE - 3); 317 os_detection_task(); 318 assert_not_reported(); 319 EXPECT_EQ(detected_host_os(), OS_LINUX); 320 321 advance_time(1); 322 os_detection_task(); 323 assert_not_reported(); 324 EXPECT_EQ(detected_host_os(), OS_LINUX); 325 326 // advancing the timer alone must not cause a report 327 advance_time(1); 328 assert_not_reported(); 329 EXPECT_EQ(detected_host_os(), OS_LINUX); 330 // the task will cause a report 331 os_detection_task(); 332 assert_reported(OS_LINUX); 333 EXPECT_EQ(detected_host_os(), OS_LINUX); 334 335 // check that it remains the same after a long time 336 advance_time(OS_DETECTION_DEBOUNCE * 15); 337 assert_reported(OS_LINUX); 338 EXPECT_EQ(detected_host_os(), OS_LINUX); 339} 340 341TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) { 342 EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 343 os_detection_notify_usb_device_state_change(usb_device_state_configured); 344 os_detection_task(); 345 assert_not_reported(); 346 347 advance_time(1); 348 os_detection_task(); 349 assert_not_reported(); 350 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 351 352 // advancing the timer alone must not cause a report 353 advance_time(OS_DETECTION_DEBOUNCE * 15); 354 assert_not_reported(); 355 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 356 // the task will cause a report 357 os_detection_task(); 358 assert_reported(OS_WINDOWS); 359 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 360 361 // check that it remains the same after a long time 362 advance_time(OS_DETECTION_DEBOUNCE * 10); 363 os_detection_task(); 364 assert_reported(OS_WINDOWS); 365 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 366} 367 368TEST_F(OsDetectionTest, TestReportUnsure) { 369 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); 370 os_detection_notify_usb_device_state_change(usb_device_state_configured); 371 os_detection_task(); 372 assert_not_reported(); 373 374 advance_time(1); 375 os_detection_task(); 376 assert_not_reported(); 377 EXPECT_EQ(detected_host_os(), OS_UNSURE); 378 379 // advancing the timer alone must not cause a report 380 advance_time(OS_DETECTION_DEBOUNCE - 1); 381 assert_not_reported(); 382 EXPECT_EQ(detected_host_os(), OS_UNSURE); 383 // the task will cause a report 384 os_detection_task(); 385 assert_reported(OS_UNSURE); 386 EXPECT_EQ(detected_host_os(), OS_UNSURE); 387 388 // check that it remains the same after a long time 389 advance_time(OS_DETECTION_DEBOUNCE * 10); 390 os_detection_task(); 391 assert_reported(OS_UNSURE); 392 EXPECT_EQ(detected_host_os(), OS_UNSURE); 393} 394 395TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) { 396 EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); 397 os_detection_notify_usb_device_state_change(usb_device_state_configured); 398 os_detection_task(); 399 assert_not_reported(); 400 401 advance_time(OS_DETECTION_DEBOUNCE - 1); 402 os_detection_task(); 403 assert_not_reported(); 404 EXPECT_EQ(detected_host_os(), OS_UNSURE); 405 406 // at this stage, the final result has not been reached yet 407 EXPECT_EQ(check_sequence({0xFF}), OS_LINUX); 408 os_detection_notify_usb_device_state_change(usb_device_state_configured); 409 advance_time(OS_DETECTION_DEBOUNCE - 1); 410 os_detection_task(); 411 assert_not_reported(); 412 // the intermedite but yet unstable result is exposed through detected_host_os() 413 EXPECT_EQ(detected_host_os(), OS_LINUX); 414 415 // the remainder is processed 416 EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); 417 os_detection_notify_usb_device_state_change(usb_device_state_configured); 418 advance_time(OS_DETECTION_DEBOUNCE - 1); 419 os_detection_task(); 420 assert_not_reported(); 421 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 422 423 // advancing the timer alone must not cause a report 424 advance_time(1); 425 assert_not_reported(); 426 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 427 // the task will cause a report 428 os_detection_task(); 429 assert_reported(OS_WINDOWS); 430 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 431 432 // check that it remains the same after a long time 433 advance_time(OS_DETECTION_DEBOUNCE * 10); 434 os_detection_task(); 435 assert_reported(OS_WINDOWS); 436 EXPECT_EQ(detected_host_os(), OS_WINDOWS); 437} 438 439TEST_F(OsDetectionTest, TestDoNotGoBackToUnsure) { 440 // 0x02 would cause it to go back to Unsure, so check that it does not 441 EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE, 0x02}), OS_LINUX); 442 os_detection_task(); 443 assert_not_reported(); 444}