Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fb41136 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

Convert country code to Layoutinfo (Language tag + Layout type)

Instead of passing country code to InputDevice.java, convert it
to Language tag and Layout type on native side and pass that
forward instead.
We can later add support for  HID language tag, that would give
us better layout information than country code. This HID
language tag is for Keyboard devices so, we set this country
code derived language tag also for Keyboards only, even though
country code could be specified for all types of devices.
Moreover, we are using language tag and layout type for setting
layout related info for Virtual keyboard devices too, making
using country code redundant.

Test: atest inputflinger_tests
Bug: 259530132
Change-Id: I8eca5537a5bb44d0b8b056947cc317ac82a0901f
parent 78c84d62
Loading
Loading
Loading
Loading
+1 −6
Original line number Original line Diff line number Diff line
@@ -24,7 +24,6 @@
#include <vector>
#include <vector>


#include <android/os/IInputConstants.h>
#include <android/os/IInputConstants.h>
#include "android/hardware/input/InputDeviceCountryCode.h"


namespace android {
namespace android {


@@ -236,9 +235,7 @@ public:


    void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
    void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
                    const InputDeviceIdentifier& identifier, const std::string& alias,
                    const InputDeviceIdentifier& identifier, const std::string& alias,
                    bool isExternal, bool hasMic,
                    bool isExternal, bool hasMic);
                    hardware::input::InputDeviceCountryCode countryCode =
                            hardware::input::InputDeviceCountryCode::INVALID);


    inline int32_t getId() const { return mId; }
    inline int32_t getId() const { return mId; }
    inline int32_t getControllerNumber() const { return mControllerNumber; }
    inline int32_t getControllerNumber() const { return mControllerNumber; }
@@ -250,7 +247,6 @@ public:
    }
    }
    inline bool isExternal() const { return mIsExternal; }
    inline bool isExternal() const { return mIsExternal; }
    inline bool hasMic() const { return mHasMic; }
    inline bool hasMic() const { return mHasMic; }
    inline hardware::input::InputDeviceCountryCode getCountryCode() const { return mCountryCode; }
    inline uint32_t getSources() const { return mSources; }
    inline uint32_t getSources() const { return mSources; }


    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
@@ -310,7 +306,6 @@ private:
    std::string mAlias;
    std::string mAlias;
    bool mIsExternal;
    bool mIsExternal;
    bool mHasMic;
    bool mHasMic;
    hardware::input::InputDeviceCountryCode mCountryCode;
    std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
    std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
    uint32_t mSources;
    uint32_t mSources;
    int32_t mKeyboardType;
    int32_t mKeyboardType;
+0 −1
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ package {
filegroup {
filegroup {
    name: "inputconstants_aidl",
    name: "inputconstants_aidl",
    srcs: [
    srcs: [
        "android/hardware/input/InputDeviceCountryCode.aidl",
        "android/os/IInputConstants.aidl",
        "android/os/IInputConstants.aidl",
        "android/os/InputEventInjectionResult.aidl",
        "android/os/InputEventInjectionResult.aidl",
        "android/os/InputEventInjectionSync.aidl",
        "android/os/InputEventInjectionSync.aidl",
+1 −4
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@
#include <input/InputEventLabels.h>
#include <input/InputEventLabels.h>


using android::base::StringPrintf;
using android::base::StringPrintf;
using android::hardware::input::InputDeviceCountryCode;


namespace android {
namespace android {


@@ -178,7 +177,6 @@ InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other)
        mAlias(other.mAlias),
        mAlias(other.mAlias),
        mIsExternal(other.mIsExternal),
        mIsExternal(other.mIsExternal),
        mHasMic(other.mHasMic),
        mHasMic(other.mHasMic),
        mCountryCode(other.mCountryCode),
        mKeyboardLayoutInfo(other.mKeyboardLayoutInfo),
        mKeyboardLayoutInfo(other.mKeyboardLayoutInfo),
        mSources(other.mSources),
        mSources(other.mSources),
        mKeyboardType(other.mKeyboardType),
        mKeyboardType(other.mKeyboardType),
@@ -197,7 +195,7 @@ InputDeviceInfo::~InputDeviceInfo() {


void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
                                 const InputDeviceIdentifier& identifier, const std::string& alias,
                                 const InputDeviceIdentifier& identifier, const std::string& alias,
                                 bool isExternal, bool hasMic, InputDeviceCountryCode countryCode) {
                                 bool isExternal, bool hasMic) {
    mId = id;
    mId = id;
    mGeneration = generation;
    mGeneration = generation;
    mControllerNumber = controllerNumber;
    mControllerNumber = controllerNumber;
@@ -205,7 +203,6 @@ void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t control
    mAlias = alias;
    mAlias = alias;
    mIsExternal = isExternal;
    mIsExternal = isExternal;
    mHasMic = hasMic;
    mHasMic = hasMic;
    mCountryCode = countryCode;
    mSources = 0;
    mSources = 0;
    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
    mHasVibrator = false;
    mHasVibrator = false;
+0 −212
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.input;

/**
 * Constant for HID country code declared by a HID device. These constants are declared as AIDL to
 * be used by java and native input code.
 *
 * @hide
 */
@Backing(type="int")
enum InputDeviceCountryCode {
    /**
     * Used as default value where country code is not set in the device HID descriptor
     */
    INVALID = -1,

    /**
     * Used as default value when country code is not supported by the HID device. The HID
     * descriptor sets "00" as the country code in this case.
     */
    NOT_SUPPORTED = 0,

    /**
     * Arabic
     */
    ARABIC = 1,

    /**
     * Belgian
     */
    BELGIAN = 2,

    /**
     * Canadian (Bilingual)
     */
    CANADIAN_BILINGUAL = 3,

    /**
     * Canadian (French)
     */
    CANADIAN_FRENCH = 4,

    /**
     * Czech Republic
     */
    CZECH_REPUBLIC = 5,

    /**
     * Danish
     */
    DANISH = 6,

    /**
     * Finnish
     */
    FINNISH = 7,

    /**
     * French
     */
    FRENCH = 8,

    /**
     * German
     */
    GERMAN = 9,

    /**
     * Greek
     */
    GREEK = 10,

    /**
     * Hebrew
     */
    HEBREW = 11,

    /**
     * Hungary
     */
    HUNGARY = 12,

    /**
     * International (ISO)
     */
    INTERNATIONAL = 13,

    /**
     * Italian
     */
    ITALIAN = 14,

    /**
     * Japan (Katakana)
     */
    JAPAN = 15,

    /**
     * Korean
     */
    KOREAN = 16,

    /**
     * Latin American
     */
    LATIN_AMERICAN = 17,

    /**
     * Netherlands (Dutch)
     */
    DUTCH = 18,

    /**
     * Norwegian
     */
    NORWEGIAN = 19,

    /**
     * Persian
     */
    PERSIAN = 20,

    /**
     * Poland
     */
    POLAND = 21,

    /**
     * Portuguese
     */
    PORTUGUESE = 22,

    /**
     * Russia
     */
    RUSSIA = 23,

    /**
     * Slovakia
     */
    SLOVAKIA = 24,

    /**
     * Spanish
     */
    SPANISH = 25,

    /**
     * Swedish
     */
    SWEDISH = 26,

    /**
     * Swiss (French)
     */
    SWISS_FRENCH = 27,

    /**
     * Swiss (German)
     */
    SWISS_GERMAN = 28,

    /**
     * Switzerland
     */
    SWITZERLAND = 29,

    /**
     * Taiwan
     */
    TAIWAN = 30,

    /**
     * Turkish_Q
     */
    TURKISH_Q = 31,

    /**
     * UK
     */
    UK = 32,

    /**
     * US
     */
    US = 33,

    /**
     * Yugoslavia
     */
    YUGOSLAVIA = 34,

    /**
     * Turkish_F
     */
    TURKISH_F = 35,
}
 No newline at end of file
+61 −14
Original line number Original line Diff line number Diff line
@@ -62,7 +62,6 @@
#define INDENT3 "      "
#define INDENT3 "      "


using android::base::StringPrintf;
using android::base::StringPrintf;
using android::hardware::input::InputDeviceCountryCode;


namespace android {
namespace android {


@@ -135,6 +134,46 @@ const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightC
                                                                  {"green", LightColor::GREEN},
                                                                  {"green", LightColor::GREEN},
                                                                  {"blue", LightColor::BLUE}};
                                                                  {"blue", LightColor::BLUE}};


// Mapping for country code to Layout info.
// See bCountryCode in 6.2.1 of https://usb.org/sites/default/files/hid1_11.pdf.
const std::unordered_map<std::int32_t, RawLayoutInfo> LAYOUT_INFOS =
        {{0, RawLayoutInfo{.languageTag = "", .layoutType = ""}},             // NOT_SUPPORTED
         {1, RawLayoutInfo{.languageTag = "ar-Arab", .layoutType = ""}},      // ARABIC
         {2, RawLayoutInfo{.languageTag = "fr-BE", .layoutType = ""}},        // BELGIAN
         {3, RawLayoutInfo{.languageTag = "fr-CA", .layoutType = ""}},        // CANADIAN_BILINGUAL
         {4, RawLayoutInfo{.languageTag = "fr-CA", .layoutType = ""}},        // CANADIAN_FRENCH
         {5, RawLayoutInfo{.languageTag = "cs", .layoutType = ""}},           // CZECH_REPUBLIC
         {6, RawLayoutInfo{.languageTag = "da", .layoutType = ""}},           // DANISH
         {7, RawLayoutInfo{.languageTag = "fi", .layoutType = ""}},           // FINNISH
         {8, RawLayoutInfo{.languageTag = "fr-FR", .layoutType = ""}},        // FRENCH
         {9, RawLayoutInfo{.languageTag = "de", .layoutType = ""}},           // GERMAN
         {10, RawLayoutInfo{.languageTag = "el", .layoutType = ""}},          // GREEK
         {11, RawLayoutInfo{.languageTag = "iw", .layoutType = ""}},          // HEBREW
         {12, RawLayoutInfo{.languageTag = "hu", .layoutType = ""}},          // HUNGARY
         {13, RawLayoutInfo{.languageTag = "en", .layoutType = "extended"}},  // INTERNATIONAL (ISO)
         {14, RawLayoutInfo{.languageTag = "it", .layoutType = ""}},          // ITALIAN
         {15, RawLayoutInfo{.languageTag = "ja", .layoutType = ""}},          // JAPAN
         {16, RawLayoutInfo{.languageTag = "ko", .layoutType = ""}},          // KOREAN
         {17, RawLayoutInfo{.languageTag = "es-419", .layoutType = ""}},      // LATIN_AMERICA
         {18, RawLayoutInfo{.languageTag = "nl", .layoutType = ""}},          // DUTCH
         {19, RawLayoutInfo{.languageTag = "nb", .layoutType = ""}},          // NORWEGIAN
         {20, RawLayoutInfo{.languageTag = "fa", .layoutType = ""}},          // PERSIAN
         {21, RawLayoutInfo{.languageTag = "pl", .layoutType = ""}},          // POLAND
         {22, RawLayoutInfo{.languageTag = "pt", .layoutType = ""}},          // PORTUGUESE
         {23, RawLayoutInfo{.languageTag = "ru", .layoutType = ""}},          // RUSSIA
         {24, RawLayoutInfo{.languageTag = "sk", .layoutType = ""}},          // SLOVAKIA
         {25, RawLayoutInfo{.languageTag = "es-ES", .layoutType = ""}},       // SPANISH
         {26, RawLayoutInfo{.languageTag = "sv", .layoutType = ""}},          // SWEDISH
         {27, RawLayoutInfo{.languageTag = "fr-CH", .layoutType = ""}},       // SWISS_FRENCH
         {28, RawLayoutInfo{.languageTag = "de-CH", .layoutType = ""}},       // SWISS_GERMAN
         {29, RawLayoutInfo{.languageTag = "de-CH", .layoutType = ""}},       // SWITZERLAND
         {30, RawLayoutInfo{.languageTag = "zh-TW", .layoutType = ""}},       // TAIWAN
         {31, RawLayoutInfo{.languageTag = "tr", .layoutType = "turkish_q"}}, // TURKISH_Q
         {32, RawLayoutInfo{.languageTag = "en-GB", .layoutType = ""}},       // UK
         {33, RawLayoutInfo{.languageTag = "en-US", .layoutType = ""}},       // US
         {34, RawLayoutInfo{.languageTag = "", .layoutType = ""}},            // YUGOSLAVIA
         {35, RawLayoutInfo{.languageTag = "tr", .layoutType = "turkish_f"}}}; // TURKISH_F

static std::string sha1(const std::string& in) {
static std::string sha1(const std::string& in) {
    SHA_CTX ctx;
    SHA_CTX ctx;
    SHA1_Init(&ctx);
    SHA1_Init(&ctx);
@@ -311,22 +350,27 @@ static std::optional<std::array<LightColor, COLOR_NUM>> getColorIndexArray(
}
}


/**
/**
 * Read country code information exposed through the sysfs path.
 * Read country code information exposed through the sysfs path and convert it to Layout info.
 */
 */
static InputDeviceCountryCode readCountryCodeLocked(const std::filesystem::path& sysfsRootPath) {
static std::optional<RawLayoutInfo> readLayoutConfiguration(
        const std::filesystem::path& sysfsRootPath) {
    // Check the sysfs root path
    // Check the sysfs root path
    int hidCountryCode = static_cast<int>(InputDeviceCountryCode::INVALID);
    int32_t hidCountryCode = -1;
    std::string str;
    std::string str;
    if (base::ReadFileToString(sysfsRootPath / "country", &str)) {
    if (base::ReadFileToString(sysfsRootPath / "country", &str)) {
        hidCountryCode = std::stoi(str, nullptr, 16);
        hidCountryCode = std::stoi(str, nullptr, 16);
        // Update this condition if new supported country codes are added to HID spec.
        if (hidCountryCode > 35 || hidCountryCode < 0) {
        if (hidCountryCode > 35 || hidCountryCode < 0) {
            ALOGE("HID country code should be in range [0, 35], but for sysfs path %s it was %d",
            ALOGE("HID country code should be in range [0, 35], but for sysfs path %s it was %d",
                  sysfsRootPath.c_str(), hidCountryCode);
                  sysfsRootPath.c_str(), hidCountryCode);
            return InputDeviceCountryCode::INVALID;
        }
        }
    }
    }
    const auto it = LAYOUT_INFOS.find(hidCountryCode);
    if (it != LAYOUT_INFOS.end()) {
        return it->second;
    }


    return static_cast<InputDeviceCountryCode>(hidCountryCode);
    return std::nullopt;
}
}


/**
/**
@@ -1299,13 +1343,13 @@ void EventHub::setLightIntensities(int32_t deviceId, int32_t lightId,
    }
    }
}
}


InputDeviceCountryCode EventHub::getCountryCode(int32_t deviceId) const {
std::optional<RawLayoutInfo> EventHub::getRawLayoutInfo(int32_t deviceId) const {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(mLock);
    Device* device = getDeviceLocked(deviceId);
    Device* device = getDeviceLocked(deviceId);
    if (device == nullptr || !device->associatedDevice) {
    if (device == nullptr || !device->associatedDevice) {
        return InputDeviceCountryCode::INVALID;
        return std::nullopt;
    }
    }
    return device->associatedDevice->countryCode;
    return device->associatedDevice->layoutInfo;
}
}


void EventHub::setExcludedDevices(const std::vector<std::string>& devices) {
void EventHub::setExcludedDevices(const std::vector<std::string>& devices) {
@@ -1449,9 +1493,9 @@ std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDevi


    std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
    std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
            AssociatedDevice{.sysfsRootPath = path,
            AssociatedDevice{.sysfsRootPath = path,
                             .countryCode = readCountryCodeLocked(path),
                             .batteryInfos = readBatteryConfiguration(path),
                             .batteryInfos = readBatteryConfiguration(path),
                             .lightInfos = readLightsConfiguration(path)});
                             .lightInfos = readLightsConfiguration(path),
                             .layoutInfo = readLayoutConfiguration(path)});


    bool associatedDeviceChanged = false;
    bool associatedDeviceChanged = false;
    for (const auto& [id, dev] : mDevices) {
    for (const auto& [id, dev] : mDevices) {
@@ -2686,9 +2730,12 @@ void EventHub::dump(std::string& dump) const {
                                 device->keyMap.keyLayoutFile.c_str());
                                 device->keyMap.keyLayoutFile.c_str());
            dump += StringPrintf(INDENT3 "KeyCharacterMapFile: %s\n",
            dump += StringPrintf(INDENT3 "KeyCharacterMapFile: %s\n",
                                 device->keyMap.keyCharacterMapFile.c_str());
                                 device->keyMap.keyCharacterMapFile.c_str());
            dump += StringPrintf(INDENT3 "CountryCode: %d\n",
            if (device->associatedDevice && device->associatedDevice->layoutInfo) {
                                 device->associatedDevice ? device->associatedDevice->countryCode
                dump += StringPrintf(INDENT3 "LanguageTag: %s\n",
                                                          : InputDeviceCountryCode::INVALID);
                                     device->associatedDevice->layoutInfo->languageTag.c_str());
                dump += StringPrintf(INDENT3 "LayoutType: %s\n",
                                     device->associatedDevice->layoutInfo->layoutType.c_str());
            }
            dump += StringPrintf(INDENT3 "ConfigurationFile: %s\n",
            dump += StringPrintf(INDENT3 "ConfigurationFile: %s\n",
                                 device->configurationFile.c_str());
                                 device->configurationFile.c_str());
            dump += StringPrintf(INDENT3 "VideoDevice: %s\n",
            dump += StringPrintf(INDENT3 "VideoDevice: %s\n",
Loading