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

Commit d78dd9b1 authored by Linnan Li's avatar Linnan Li Committed by Siarhei Vishniakou
Browse files

Copy KeyCharacterMap object when we fill InputDeviceInfo(1/n)



Currently, in InputDeviceInfo, we store the KeyCharacterMap object,
which is actually the original KeyCharacterMap from the EventHub. This
could potentially lead to issues where two threads operate on the same
KeyCharacterMap object simultaneously, resulting in thread safety
problems.

To avoid potential risks in the future, we make a copy of the original
KeyCharacterMap when generating InputDeviceInfo.

This change should not introduce any behavioral changes.

Bug: 373011069
Flag: EXEMPT refactor
Test: presubmit

Signed-off-by: default avatarLinnan Li <lilinnan@xiaomi.corp-partner.google.com>
(cherry picked from https://partner-android-review.googlesource.com/q/commit:1be9c1ce7400e38cf3f45921d7181e947929f91c)
Merged-In: I0d0155133f95b0f1dc925422eda0da04c6f196ea
Change-Id: I0d0155133f95b0f1dc925422eda0da04c6f196ea
parent 93ee540f
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -266,6 +266,7 @@ class InputDeviceInfo {
public:
    InputDeviceInfo();
    InputDeviceInfo(const InputDeviceInfo& other);
    InputDeviceInfo& operator=(const InputDeviceInfo& other);
    ~InputDeviceInfo();

    struct MotionRange {
@@ -315,13 +316,11 @@ public:

    inline const InputDeviceViewBehavior& getViewBehavior() const { return mViewBehavior; }

    inline void setKeyCharacterMap(const std::shared_ptr<KeyCharacterMap> value) {
        mKeyCharacterMap = value;
    inline void setKeyCharacterMap(std::unique_ptr<KeyCharacterMap> value) {
        mKeyCharacterMap = std::move(value);
    }

    inline const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap() const {
        return mKeyCharacterMap;
    }
    inline const KeyCharacterMap* getKeyCharacterMap() const { return mKeyCharacterMap.get(); }

    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
    inline bool hasVibrator() const { return mHasVibrator; }
@@ -364,7 +363,7 @@ private:
    std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
    uint32_t mSources;
    int32_t mKeyboardType;
    std::shared_ptr<KeyCharacterMap> mKeyCharacterMap;
    std::unique_ptr<KeyCharacterMap> mKeyCharacterMap;
    std::optional<InputDeviceUsiVersion> mUsiVersion;
    ui::LogicalDisplayId mAssociatedDisplayId{ui::LogicalDisplayId::INVALID};
    bool mEnabled;
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public:
    };

    /* Loads a key character map from a file. */
    static base::Result<std::shared_ptr<KeyCharacterMap>> load(const std::string& filename,
    static base::Result<std::unique_ptr<KeyCharacterMap>> load(const std::string& filename,
                                                               Format format);

    /* Loads a key character map from its string contents. */
+31 −1
Original line number Diff line number Diff line
@@ -191,7 +191,9 @@ InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other)
        mKeyboardLayoutInfo(other.mKeyboardLayoutInfo),
        mSources(other.mSources),
        mKeyboardType(other.mKeyboardType),
        mKeyCharacterMap(other.mKeyCharacterMap),
        mKeyCharacterMap(other.mKeyCharacterMap
                                 ? std::make_unique<KeyCharacterMap>(*other.mKeyCharacterMap)
                                 : nullptr),
        mUsiVersion(other.mUsiVersion),
        mAssociatedDisplayId(other.mAssociatedDisplayId),
        mEnabled(other.mEnabled),
@@ -204,6 +206,34 @@ InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other)
        mLights(other.mLights),
        mViewBehavior(other.mViewBehavior) {}

InputDeviceInfo& InputDeviceInfo::operator=(const InputDeviceInfo& other) {
    mId = other.mId;
    mGeneration = other.mGeneration;
    mControllerNumber = other.mControllerNumber;
    mIdentifier = other.mIdentifier;
    mAlias = other.mAlias;
    mIsExternal = other.mIsExternal;
    mHasMic = other.mHasMic;
    mKeyboardLayoutInfo = other.mKeyboardLayoutInfo;
    mSources = other.mSources;
    mKeyboardType = other.mKeyboardType;
    mKeyCharacterMap = other.mKeyCharacterMap
            ? std::make_unique<KeyCharacterMap>(*other.mKeyCharacterMap)
            : nullptr;
    mUsiVersion = other.mUsiVersion;
    mAssociatedDisplayId = other.mAssociatedDisplayId;
    mEnabled = other.mEnabled;
    mHasVibrator = other.mHasVibrator;
    mHasBattery = other.mHasBattery;
    mHasButtonUnderPad = other.mHasButtonUnderPad;
    mHasSensor = other.mHasSensor;
    mMotionRanges = other.mMotionRanges;
    mSensors = other.mSensors;
    mLights = other.mLights;
    mViewBehavior = other.mViewBehavior;
    return *this;
}

InputDeviceInfo::~InputDeviceInfo() {
}

+3 −3
Original line number Diff line number Diff line
@@ -84,15 +84,15 @@ static String8 toString(const char16_t* chars, size_t numChars) {

KeyCharacterMap::KeyCharacterMap(const std::string& filename) : mLoadFileName(filename) {}

base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(const std::string& filename,
base::Result<std::unique_ptr<KeyCharacterMap>> KeyCharacterMap::load(const std::string& filename,
                                                                     Format format) {
    Tokenizer* tokenizer;
    status_t status = Tokenizer::open(String8(filename.c_str()), &tokenizer);
    if (status) {
        return Errorf("Error {} opening key character map file {}.", status, filename.c_str());
    }
    std::shared_ptr<KeyCharacterMap> map =
            std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap(filename));
    std::unique_ptr<KeyCharacterMap> map =
            std::unique_ptr<KeyCharacterMap>(new KeyCharacterMap(filename));
    if (!map.get()) {
        ALOGE("Error allocating key character map.");
        return Errorf("Error allocating key character map.");
+3 −1
Original line number Diff line number Diff line
@@ -132,7 +132,9 @@ std::optional<KeyboardLayoutInfo> KeyboardInputMapper::getKeyboardLayoutInfo() c
void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
    InputMapper::populateDeviceInfo(info);

    info.setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
    if (const auto kcm = getDeviceContext().getKeyCharacterMap(); kcm != nullptr) {
        info.setKeyCharacterMap(std::make_unique<KeyCharacterMap>(*kcm));
    }

    std::optional keyboardLayoutInfo = getKeyboardLayoutInfo();
    if (keyboardLayoutInfo) {