diff options
author | 2021-09-21 12:04:46 -0700 | |
---|---|---|
committer | 2021-09-24 01:18:40 +0000 | |
commit | 8c79b6a55ab0b27d6866faa39c1727c5d9281bfd (patch) | |
tree | 66a568d1ba1330a4dbeade0cfe646a88cb73b1ba | |
parent | 2943f54efcd0d87b981b434ebd535bc15ee1cef2 (diff) |
Prevent some keylayouts from being added to Android
Some of the custom key layouts cause problems. Specifically:
1. Microsoft designed some of its devices to work with Generic.kl, and
if we add a custom layout, it could break these devices. We
should check with Microsoft prior to adding such layouts. Often, we
should just tell the users to update the firmware on their controllers
to get it working properly.
2. Some devices use the same vendor id / product id (incorrectly). They
should all have unique numbers, but they have chosen
to reuse Broadcom's numbers instead. As a result, adding a layout for
one of them breaks the others. Matching by name is fine,
though. Fail the build to prevent these from being added.
Bug: 191720859
Bug: 194334400
Test: added one of these layouts and tried to build Android, observed
build failure
Change-Id: I26c44dd3d322154cc1eeecbc7cab65b1add130d0
-rw-r--r-- | tools/validatekeymaps/Main.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp index 991b28071515..817effd24a2d 100644 --- a/tools/validatekeymaps/Main.cpp +++ b/tools/validatekeymaps/Main.cpp @@ -29,6 +29,17 @@ using namespace android; static const char* PROG_NAME = "validatekeymaps"; static bool gQuiet = false; +/** + * Return true if 'str' contains 'substr', ignoring case. + */ +static bool containsSubstringCaseInsensitive(std::string_view str, std::string_view substr) { + auto it = std::search(str.begin(), str.end(), substr.begin(), substr.end(), + [](char left, char right) { + return std::tolower(left) == std::tolower(right); + }); + return it != str.end(); +} + enum class FileType { UNKNOWN, KEY_LAYOUT, @@ -85,6 +96,36 @@ static FileType getFileType(const char* filename) { return FileType::UNKNOWN; } +/** + * Return true if the filename is allowed, false otherwise. + */ +static bool validateKeyLayoutFileName(const std::string& filename) { + static const std::string kMicrosoftReason = + "Microsoft's controllers are designed to work with Generic.kl. Please check with " + "Microsoft prior to adding these layouts. See b/194334400"; + static const std::vector<std::pair<std::string, std::string>> kBannedDevices{ + std::make_pair("Vendor_0a5c_Product_8502", + "This vendorId/productId combination conflicts with 'SnakeByte " + "iDroid:con', 'BT23BK keyboard', and other keyboards. Instead, consider " + "matching these specific devices by name. See b/36976285, b/191720859"), + std::make_pair("Vendor_045e_Product_0b05", kMicrosoftReason), + std::make_pair("Vendor_045e_Product_0b20", kMicrosoftReason), + std::make_pair("Vendor_045e_Product_0b21", kMicrosoftReason), + std::make_pair("Vendor_045e_Product_0b22", kMicrosoftReason), + }; + + for (const auto& [filenameSubstr, reason] : kBannedDevices) { + if (containsSubstringCaseInsensitive(filename, filenameSubstr)) { + error("You are trying to add a key layout %s, which matches %s. ", filename.c_str(), + filenameSubstr.c_str()); + error("This would cause some devices to function incorrectly. "); + error("%s. ", reason.c_str()); + return false; + } + } + return true; +} + static bool validateFile(const char* filename) { log("Validating file '%s'...\n", filename); @@ -95,6 +136,9 @@ static bool validateFile(const char* filename) { return false; case FileType::KEY_LAYOUT: { + if (!validateKeyLayoutFileName(filename)) { + return false; + } base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(filename); if (!ret.ok()) { error("Error %s parsing key layout file.\n\n", ret.error().message().c_str()); |