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

Commit c27855a9 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8060779 from 6f28d23f to sc-v2-release

Change-Id: I6a6467d5515bfae05384053e816c8fb8d363ffad
parents fdde8fd6 6f28d23f
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ public:

    const std::string getLoadFileName() const;

    /* Combines this key character map with an overlay. */
    /* Combines this key character map with the provided overlay. */
    void combine(const KeyCharacterMap& overlay);

    /* Gets the keyboard type. */
@@ -144,6 +144,8 @@ public:

    bool operator==(const KeyCharacterMap& other) const;

    bool operator!=(const KeyCharacterMap& other) const;

    KeyCharacterMap(const KeyCharacterMap& other);

    virtual ~KeyCharacterMap();
@@ -230,11 +232,12 @@ private:
    KeyedVector<int32_t, Key*> mKeys;
    KeyboardType mType;
    std::string mLoadFileName;
    bool mLayoutOverlayApplied;

    KeyedVector<int32_t, int32_t> mKeysByScanCode;
    KeyedVector<int32_t, int32_t> mKeysByUsageCode;

    KeyCharacterMap();
    KeyCharacterMap(const std::string& filename);

    bool getKey(int32_t keyCode, const Key** outKey) const;
    bool getKeyBehavior(int32_t keyCode, int32_t metaState,
@@ -243,8 +246,6 @@ private:

    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;

    static base::Result<std::shared_ptr<KeyCharacterMap>> load(Tokenizer* tokenizer, Format format);

    static void addKey(Vector<KeyEvent>& outEvents,
            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
    static void addMetaKeys(Vector<KeyEvent>& outEvents,
@@ -264,6 +265,15 @@ private:
            int32_t deviceId, int32_t metaState, nsecs_t time,
            int32_t keyCode, int32_t keyMetaState,
            int32_t* currentMetaState);

    /* Clears all data stored in this key character map */
    void clear();

    /* Loads the KeyCharacterMap provided by the tokenizer into this instance. */
    status_t load(Tokenizer* tokenizer, Format format);

    /* Reloads the data from mLoadFileName and unapplies any overlay. */
    status_t reloadBaseFromFile();
};

} // namespace android
+110 −26
Original line number Diff line number Diff line
@@ -86,10 +86,13 @@ static String8 toString(const char16_t* chars, size_t numChars) {

// --- KeyCharacterMap ---

KeyCharacterMap::KeyCharacterMap() : mType(KeyboardType::UNKNOWN) {}
KeyCharacterMap::KeyCharacterMap(const std::string& filename)
      : mType(KeyboardType::UNKNOWN), mLoadFileName(filename) {}

KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other)
      : mType(other.mType),
        mLoadFileName(other.mLoadFileName),
        mLayoutOverlayApplied(other.mLayoutOverlayApplied),
        mKeysByScanCode(other.mKeysByScanCode),
        mKeysByUsageCode(other.mKeysByUsageCode) {
    for (size_t i = 0; i < other.mKeys.size(); i++) {
@@ -98,16 +101,19 @@ KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other)
}

KeyCharacterMap::~KeyCharacterMap() {
    for (size_t i = 0; i < mKeys.size(); i++) {
        Key* key = mKeys.editValueAt(i);
        delete key;
    }
    clear();
}

bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const {
    if (mType != other.mType) {
        return false;
    }
    if (mLoadFileName != other.mLoadFileName) {
        return false;
    }
    if (mLayoutOverlayApplied != other.mLayoutOverlayApplied) {
        return false;
    }
    if (mKeys.size() != other.mKeys.size() ||
        mKeysByScanCode.size() != other.mKeysByScanCode.size() ||
        mKeysByUsageCode.size() != other.mKeysByUsageCode.size()) {
@@ -146,6 +152,10 @@ bool KeyCharacterMap::operator==(const KeyCharacterMap& other) const {
    return true;
}

bool KeyCharacterMap::operator!=(const KeyCharacterMap& other) const {
    return !(*this == other);
}

base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(const std::string& filename,
                                                                     Format format) {
    Tokenizer* tokenizer;
@@ -153,12 +163,18 @@ base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(const std::
    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));
    if (!map.get()) {
        ALOGE("Error allocating key character map.");
        return Errorf("Error allocating key character map.");
    }
    std::unique_ptr<Tokenizer> t(tokenizer);
    auto ret = load(t.get(), format);
    if (ret.ok()) {
        (*ret)->mLoadFileName = filename;
    status = map->load(t.get(), format);
    if (status == OK) {
        return map;
    }
    return ret;
    return Errorf("Load KeyCharacterMap failed {}.", status);
}

base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::loadContents(
@@ -169,40 +185,67 @@ base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::loadContents(
        ALOGE("Error %d opening key character map.", status);
        return Errorf("Error {} opening key character map.", status);
    }
    std::shared_ptr<KeyCharacterMap> map =
            std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap(filename));
    if (!map.get()) {
        ALOGE("Error allocating key character map.");
        return Errorf("Error allocating key character map.");
    }
    std::unique_ptr<Tokenizer> t(tokenizer);
    auto ret = load(t.get(), format);
    if (ret.ok()) {
        (*ret)->mLoadFileName = filename;
    status = map->load(t.get(), format);
    if (status == OK) {
        return map;
    }
    return ret;
    return Errorf("Load KeyCharacterMap failed {}.", status);
}

base::Result<std::shared_ptr<KeyCharacterMap>> KeyCharacterMap::load(Tokenizer* tokenizer,
                                                                     Format format) {
status_t KeyCharacterMap::load(Tokenizer* tokenizer, Format format) {
    status_t status = OK;
    std::shared_ptr<KeyCharacterMap> map = std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap());
    if (!map.get()) {
        ALOGE("Error allocating key character map.");
        return Errorf("Error allocating key character map.");
    }
#if DEBUG_PARSER_PERFORMANCE
    nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
#endif
    Parser parser(map.get(), tokenizer, format);
    Parser parser(this, tokenizer, format);
    status = parser.parse();
#if DEBUG_PARSER_PERFORMANCE
    nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
    ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
          tokenizer->getFilename().string(), tokenizer->getLineNumber(), elapsedTime / 1000000.0);
#endif
    if (status == OK) {
        return map;
    if (status != OK) {
        ALOGE("Loading KeyCharacterMap failed with status %s", statusToString(status).c_str());
    }
    return status;
}

    return Errorf("Load KeyCharacterMap failed {}.", status);
void KeyCharacterMap::clear() {
    mKeysByScanCode.clear();
    mKeysByUsageCode.clear();
    for (size_t i = 0; i < mKeys.size(); i++) {
        Key* key = mKeys.editValueAt(i);
        delete key;
    }
    mKeys.clear();
    mLayoutOverlayApplied = false;
    mType = KeyboardType::UNKNOWN;
}

status_t KeyCharacterMap::reloadBaseFromFile() {
    clear();
    Tokenizer* tokenizer;
    status_t status = Tokenizer::open(String8(mLoadFileName.c_str()), &tokenizer);
    if (status) {
        ALOGE("Error %s opening key character map file %s.", statusToString(status).c_str(),
              mLoadFileName.c_str());
        return status;
    }
    std::unique_ptr<Tokenizer> t(tokenizer);
    return load(t.get(), KeyCharacterMap::Format::BASE);
}

void KeyCharacterMap::combine(const KeyCharacterMap& overlay) {
    if (mLayoutOverlayApplied) {
        reloadBaseFromFile();
    }
    for (size_t i = 0; i < overlay.mKeys.size(); i++) {
        int32_t keyCode = overlay.mKeys.keyAt(i);
        Key* key = overlay.mKeys.valueAt(i);
@@ -224,7 +267,7 @@ void KeyCharacterMap::combine(const KeyCharacterMap& overlay) {
        mKeysByUsageCode.replaceValueFor(overlay.mKeysByUsageCode.keyAt(i),
                                         overlay.mKeysByUsageCode.valueAt(i));
    }
    mLoadFileName = overlay.mLoadFileName;
    mLayoutOverlayApplied = true;
}

KeyCharacterMap::KeyboardType KeyCharacterMap::getKeyboardType() const {
@@ -636,8 +679,11 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel)
        ALOGE("%s: Null parcel", __func__);
        return nullptr;
    }
    std::shared_ptr<KeyCharacterMap> map = std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap());
    std::string loadFileName = parcel->readCString();
    std::shared_ptr<KeyCharacterMap> map =
            std::shared_ptr<KeyCharacterMap>(new KeyCharacterMap(loadFileName));
    map->mType = static_cast<KeyCharacterMap::KeyboardType>(parcel->readInt32());
    map->mLayoutOverlayApplied = parcel->readBool();
    size_t numKeys = parcel->readInt32();
    if (parcel->errorCheck()) {
        return nullptr;
@@ -687,6 +733,30 @@ std::shared_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel)
            return nullptr;
        }
    }
    size_t numKeysByScanCode = parcel->readInt32();
    if (parcel->errorCheck()) {
        return nullptr;
    }
    for (size_t i = 0; i < numKeysByScanCode; i++) {
        int32_t key = parcel->readInt32();
        int32_t value = parcel->readInt32();
        map->mKeysByScanCode.add(key, value);
        if (parcel->errorCheck()) {
            return nullptr;
        }
    }
    size_t numKeysByUsageCode = parcel->readInt32();
    if (parcel->errorCheck()) {
        return nullptr;
    }
    for (size_t i = 0; i < numKeysByUsageCode; i++) {
        int32_t key = parcel->readInt32();
        int32_t value = parcel->readInt32();
        map->mKeysByUsageCode.add(key, value);
        if (parcel->errorCheck()) {
            return nullptr;
        }
    }
    return map;
}

@@ -695,7 +765,9 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
        ALOGE("%s: Null parcel", __func__);
        return;
    }
    parcel->writeCString(mLoadFileName.c_str());
    parcel->writeInt32(static_cast<int32_t>(mType));
    parcel->writeBool(mLayoutOverlayApplied);

    size_t numKeys = mKeys.size();
    parcel->writeInt32(numKeys);
@@ -715,6 +787,18 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
        }
        parcel->writeInt32(0);
    }
    size_t numKeysByScanCode = mKeysByScanCode.size();
    parcel->writeInt32(numKeysByScanCode);
    for (size_t i = 0; i < numKeysByScanCode; i++) {
        parcel->writeInt32(mKeysByScanCode.keyAt(i));
        parcel->writeInt32(mKeysByScanCode.valueAt(i));
    }
    size_t numKeysByUsageCode = mKeysByUsageCode.size();
    parcel->writeInt32(numKeysByUsageCode);
    for (size_t i = 0; i < numKeysByUsageCode; i++) {
        parcel->writeInt32(mKeysByUsageCode.keyAt(i));
        parcel->writeInt32(mKeysByUsageCode.valueAt(i));
    }
}
#endif // __linux__

+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ cc_test {
        "libui",
        "libutils",
    ],
    data: ["data/*.kcm"],
    test_suites: ["device-tests"],
}

@@ -59,5 +60,5 @@ cc_library_static {
        "libbinder",
        "libui",
        "libbase",
    ]
    ],
}
+50 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <input/InputDevice.h>
#include <input/KeyLayoutMap.h>
#include <input/Keyboard.h>
#include "android-base/file.h"

namespace android {

@@ -82,4 +83,53 @@ TEST_F(InputDeviceKeyMapTest, keyCharacterMapParcelingTest) {
    ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
}

TEST_F(InputDeviceKeyMapTest, keyCharacterMapWithOverlayParcelingTest) {
    Parcel parcel;
    std::string overlayPath = base::GetExecutableDirectory() + "/data/german.kcm";
    base::Result<std::shared_ptr<KeyCharacterMap>> overlay =
            KeyCharacterMap::load(overlayPath, KeyCharacterMap::Format::OVERLAY);
    ASSERT_TRUE(overlay.ok()) << "Cannot load KeyCharacterMap at " << overlayPath;
    mKeyMap.keyCharacterMap->combine(*overlay->get());
    mKeyMap.keyCharacterMap->writeToParcel(&parcel);
    parcel.setDataPosition(0);
    std::shared_ptr<KeyCharacterMap> map = KeyCharacterMap::readFromParcel(&parcel);
    ASSERT_EQ(*map, *mKeyMap.keyCharacterMap);
}

TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) {
    std::string frenchOverlayPath = base::GetExecutableDirectory() + "/data/french.kcm";
    std::string englishOverlayPath = base::GetExecutableDirectory() + "/data/english_us.kcm";
    std::string germanOverlayPath = base::GetExecutableDirectory() + "/data/german.kcm";
    base::Result<std::shared_ptr<KeyCharacterMap>> frenchOverlay =
            KeyCharacterMap::load(frenchOverlayPath, KeyCharacterMap::Format::OVERLAY);
    ASSERT_TRUE(frenchOverlay.ok()) << "Cannot load KeyCharacterMap at " << frenchOverlayPath;
    base::Result<std::shared_ptr<KeyCharacterMap>> englishOverlay =
            KeyCharacterMap::load(englishOverlayPath, KeyCharacterMap::Format::OVERLAY);
    ASSERT_TRUE(englishOverlay.ok()) << "Cannot load KeyCharacterMap at " << englishOverlayPath;
    base::Result<std::shared_ptr<KeyCharacterMap>> germanOverlay =
            KeyCharacterMap::load(germanOverlayPath, KeyCharacterMap::Format::OVERLAY);
    ASSERT_TRUE(germanOverlay.ok()) << "Cannot load KeyCharacterMap at " << germanOverlayPath;

    // Apply the French overlay
    mKeyMap.keyCharacterMap->combine(*frenchOverlay->get());
    // Copy the result for later
    std::shared_ptr<KeyCharacterMap> frenchOverlaidKeyCharacterMap =
            std::make_shared<KeyCharacterMap>(*mKeyMap.keyCharacterMap);

    // Apply the English overlay
    mKeyMap.keyCharacterMap->combine(*englishOverlay->get());
    // Verify that the result is different from the French overlay result
    ASSERT_NE(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);

    // Apply the German overlay
    mKeyMap.keyCharacterMap->combine(*germanOverlay->get());
    // Verify that the result is different from the French overlay result
    ASSERT_NE(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);

    // Apply the French overlay
    mKeyMap.keyCharacterMap->combine(*frenchOverlay->get());
    // Verify that the result is the same like after applying it initially
    ASSERT_EQ(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);
}

} // namespace android
+311 −0
Original line number Diff line number Diff line
# Copyright (C) 2021 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.

#
# English (US) keyboard layout.
# Unlike the default (generic) keyboard layout, English (US) does not contain any
# special ALT characters.
#

type OVERLAY

### ROW 1

key GRAVE {
    label:                              '`'
    base:                               '`'
    shift:                              '~'
}

key 1 {
    label:                              '1'
    base:                               '1'
    shift:                              '!'
}

key 2 {
    label:                              '2'
    base:                               '2'
    shift:                              '@'
}

key 3 {
    label:                              '3'
    base:                               '3'
    shift:                              '#'
}

key 4 {
    label:                              '4'
    base:                               '4'
    shift:                              '$'
}

key 5 {
    label:                              '5'
    base:                               '5'
    shift:                              '%'
}

key 6 {
    label:                              '6'
    base:                               '6'
    shift:                              '^'
}

key 7 {
    label:                              '7'
    base:                               '7'
    shift:                              '&'
}

key 8 {
    label:                              '8'
    base:                               '8'
    shift:                              '*'
}

key 9 {
    label:                              '9'
    base:                               '9'
    shift:                              '('
}

key 0 {
    label:                              '0'
    base:                               '0'
    shift:                              ')'
}

key MINUS {
    label:                              '-'
    base:                               '-'
    shift:                              '_'
}

key EQUALS {
    label:                              '='
    base:                               '='
    shift:                              '+'
}

### ROW 2

key Q {
    label:                              'Q'
    base:                               'q'
    shift, capslock:                    'Q'
}

key W {
    label:                              'W'
    base:                               'w'
    shift, capslock:                    'W'
}

key E {
    label:                              'E'
    base:                               'e'
    shift, capslock:                    'E'
}

key R {
    label:                              'R'
    base:                               'r'
    shift, capslock:                    'R'
}

key T {
    label:                              'T'
    base:                               't'
    shift, capslock:                    'T'
}

key Y {
    label:                              'Y'
    base:                               'y'
    shift, capslock:                    'Y'
}

key U {
    label:                              'U'
    base:                               'u'
    shift, capslock:                    'U'
}

key I {
    label:                              'I'
    base:                               'i'
    shift, capslock:                    'I'
}

key O {
    label:                              'O'
    base:                               'o'
    shift, capslock:                    'O'
}

key P {
    label:                              'P'
    base:                               'p'
    shift, capslock:                    'P'
}

key LEFT_BRACKET {
    label:                              '['
    base:                               '['
    shift:                              '{'
}

key RIGHT_BRACKET {
    label:                              ']'
    base:                               ']'
    shift:                              '}'
}

key BACKSLASH {
    label:                              '\\'
    base:                               '\\'
    shift:                              '|'
}

### ROW 3

key A {
    label:                              'A'
    base:                               'a'
    shift, capslock:                    'A'
}

key S {
    label:                              'S'
    base:                               's'
    shift, capslock:                    'S'
}

key D {
    label:                              'D'
    base:                               'd'
    shift, capslock:                    'D'
}

key F {
    label:                              'F'
    base:                               'f'
    shift, capslock:                    'F'
}

key G {
    label:                              'G'
    base:                               'g'
    shift, capslock:                    'G'
}

key H {
    label:                              'H'
    base:                               'h'
    shift, capslock:                    'H'
}

key J {
    label:                              'J'
    base:                               'j'
    shift, capslock:                    'J'
}

key K {
    label:                              'K'
    base:                               'k'
    shift, capslock:                    'K'
}

key L {
    label:                              'L'
    base:                               'l'
    shift, capslock:                    'L'
}

key SEMICOLON {
    label:                              ';'
    base:                               ';'
    shift:                              ':'
}

key APOSTROPHE {
    label:                              '\''
    base:                               '\''
    shift:                              '"'
}

### ROW 4

key Z {
    label:                              'Z'
    base:                               'z'
    shift, capslock:                    'Z'
}

key X {
    label:                              'X'
    base:                               'x'
    shift, capslock:                    'X'
}

key C {
    label:                              'C'
    base:                               'c'
    shift, capslock:                    'C'
}

key V {
    label:                              'V'
    base:                               'v'
    shift, capslock:                    'V'
}

key B {
    label:                              'B'
    base:                               'b'
    shift, capslock:                    'B'
}

key N {
    label:                              'N'
    base:                               'n'
    shift, capslock:                    'N'
}

key M {
    label:                              'M'
    base:                               'm'
    shift, capslock:                    'M'
}

key COMMA {
    label:                              ','
    base:                               ','
    shift:                              '<'
}

key PERIOD {
    label:                              '.'
    base:                               '.'
    shift:                              '>'
}

key SLASH {
    label:                              '/'
    base:                               '/'
    shift:                              '?'
}
 No newline at end of file
Loading