Use std::list to store Behavior objects

There's a bug about behavior being null. It's not clear how it gets
there, but before this CL, there was a custom implementation of linked
list to store the behaviours. Instead of implementing a
custom linked list, let's switch over to std::list to remove the
possibility of this bug.

Bug: 238626341
Test: atest libinput_tests inputflinger_tests KeyCharacterMapTest
Change-Id: I98e20de7d40b74e4af085cdafb68f867e6ebfe19
diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
index 585ea3c..1c9a5ea 100644
--- a/include/input/KeyCharacterMap.h
+++ b/include/input/KeyCharacterMap.h
@@ -18,6 +18,7 @@
 #define _LIBINPUT_KEY_CHARACTER_MAP_H
 
 #include <stdint.h>
+#include <list>
 
 #ifdef __linux__
 #include <binder/IBinder.h>
@@ -152,29 +153,22 @@
 
 private:
     struct Behavior {
-        Behavior();
-        Behavior(const Behavior& other);
-
-        /* The next behavior in the list, or NULL if none. */
-        Behavior* next;
-
         /* The meta key modifiers for this behavior. */
-        int32_t metaState;
+        int32_t metaState = 0;
 
         /* The character to insert. */
-        char16_t character;
+        char16_t character = 0;
 
         /* The fallback keycode if the key is not handled. */
-        int32_t fallbackKeyCode;
+        int32_t fallbackKeyCode = 0;
 
         /* The replacement keycode if the key has to be replaced outright. */
-        int32_t replacementKeyCode;
+        int32_t replacementKeyCode = 0;
     };
 
     struct Key {
         Key();
         Key(const Key& other);
-        ~Key();
 
         /* The single character label printed on the key, or 0 if none. */
         char16_t label;
@@ -184,7 +178,7 @@
 
         /* The list of key behaviors sorted from most specific to least specific
          * meta key binding. */
-        Behavior* firstBehavior;
+        std::list<Behavior> behaviors;
     };
 
     class Parser {
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 5cb844e..422e6e0 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -345,12 +345,12 @@
         // Try to find the most general behavior that maps to this character.
         // For example, the base key behavior will usually be last in the list.
         // However, if we find a perfect meta state match for one behavior then use that one.
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character) {
+        for (const Behavior& behavior : key->behaviors) {
+            if (behavior.character) {
                 for (size_t i = 0; i < numChars; i++) {
-                    if (behavior->character == chars[i]) {
-                        result = behavior->character;
-                        if ((behavior->metaState & metaState) == behavior->metaState) {
+                    if (behavior.character == chars[i]) {
+                        result = behavior.character;
+                        if ((behavior.metaState & metaState) == behavior.metaState) {
                             goto ExactMatch;
                         }
                         break;
@@ -485,12 +485,10 @@
                                                                  int32_t metaState) const {
     const Key* key;
     if (getKey(keyCode, &key)) {
-        const Behavior* behavior = key->firstBehavior;
-        while (behavior) {
-            if (matchesMetaState(metaState, behavior->metaState)) {
-                return behavior;
+        for (const Behavior& behavior : key->behaviors) {
+            if (matchesMetaState(metaState, behavior.metaState)) {
+                return &behavior;
             }
-            behavior = behavior->next;
         }
     }
     return nullptr;
@@ -538,12 +536,12 @@
         // Try to find the most general behavior that maps to this character.
         // For example, the base key behavior will usually be last in the list.
         const Behavior* found = nullptr;
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character == ch) {
-                found = behavior;
+        for (const Behavior& behavior : key->behaviors) {
+            if (behavior.character == ch) {
+                found = &behavior;
             }
         }
-        if (found) {
+        if (found != nullptr) {
             *outKeyCode = mKeys.keyAt(i);
             *outMetaState = found->metaState;
             return true;
@@ -701,7 +699,6 @@
         key->number = number;
         map->mKeys.add(keyCode, key);
 
-        Behavior* lastBehavior = nullptr;
         while (parcel->readInt32()) {
             int32_t metaState = parcel->readInt32();
             char16_t character = parcel->readInt32();
@@ -711,17 +708,12 @@
                 return nullptr;
             }
 
-            Behavior* behavior = new Behavior();
-            behavior->metaState = metaState;
-            behavior->character = character;
-            behavior->fallbackKeyCode = fallbackKeyCode;
-            behavior->replacementKeyCode = replacementKeyCode;
-            if (lastBehavior) {
-                lastBehavior->next = behavior;
-            } else {
-                key->firstBehavior = behavior;
-            }
-            lastBehavior = behavior;
+            key->behaviors.push_back({
+                    .metaState = metaState,
+                    .character = character,
+                    .fallbackKeyCode = fallbackKeyCode,
+                    .replacementKeyCode = replacementKeyCode,
+            });
         }
 
         if (parcel->errorCheck()) {
@@ -772,13 +764,12 @@
         parcel->writeInt32(keyCode);
         parcel->writeInt32(key->label);
         parcel->writeInt32(key->number);
-        for (const Behavior* behavior = key->firstBehavior; behavior != nullptr;
-                behavior = behavior->next) {
+        for (const Behavior& behavior : key->behaviors) {
             parcel->writeInt32(1);
-            parcel->writeInt32(behavior->metaState);
-            parcel->writeInt32(behavior->character);
-            parcel->writeInt32(behavior->fallbackKeyCode);
-            parcel->writeInt32(behavior->replacementKeyCode);
+            parcel->writeInt32(behavior.metaState);
+            parcel->writeInt32(behavior.character);
+            parcel->writeInt32(behavior.fallbackKeyCode);
+            parcel->writeInt32(behavior.replacementKeyCode);
         }
         parcel->writeInt32(0);
     }
@@ -799,38 +790,10 @@
 
 // --- KeyCharacterMap::Key ---
 
-KeyCharacterMap::Key::Key() :
-        label(0), number(0), firstBehavior(nullptr) {
-}
+KeyCharacterMap::Key::Key() : label(0), number(0) {}
 
-KeyCharacterMap::Key::Key(const Key& other) :
-        label(other.label), number(other.number),
-        firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : nullptr) {
-}
-
-KeyCharacterMap::Key::~Key() {
-    Behavior* behavior = firstBehavior;
-    while (behavior) {
-        Behavior* next = behavior->next;
-        delete behavior;
-        behavior = next;
-    }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
-        next(nullptr), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) {
-}
-
-KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
-        next(other.next ? new Behavior(*other.next) : nullptr),
-        metaState(other.metaState), character(other.character),
-        fallbackKeyCode(other.fallbackKeyCode),
-        replacementKeyCode(other.replacementKeyCode) {
-}
-
+KeyCharacterMap::Key::Key(const Key& other)
+      : label(other.label), number(other.number), behaviors(other.behaviors) {}
 
 // --- KeyCharacterMap::Parser ---
 
@@ -1208,23 +1171,21 @@
 #endif
             break;
         case PROPERTY_META: {
-            for (Behavior* b = key->firstBehavior; b; b = b->next) {
-                if (b->metaState == property.metaState) {
+            for (const Behavior& b : key->behaviors) {
+                if (b.metaState == property.metaState) {
                     ALOGE("%s: Duplicate key behavior for modifier.",
                             mTokenizer->getLocation().string());
                     return BAD_VALUE;
                 }
             }
-            Behavior* newBehavior = new Behavior(behavior);
-            newBehavior->metaState = property.metaState;
-            newBehavior->next = key->firstBehavior;
-            key->firstBehavior = newBehavior;
-#if DEBUG_PARSER
-            ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
-                    mKeyCode,
-                    newBehavior->metaState, newBehavior->character,
-                    newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode);
-#endif
+            Behavior newBehavior = behavior;
+            newBehavior.metaState = property.metaState;
+            key->behaviors.push_front(newBehavior);
+            ALOGD_IF(DEBUG_PARSER,
+                     "Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
+                     mKeyCode, key->behaviors.front().metaState, key->behaviors.front().character,
+                     key->behaviors.front().fallbackKeyCode,
+                     key->behaviors.front().replacementKeyCode);
             break;
         }
         }
@@ -1237,8 +1198,8 @@
     if (!key->number) {
         char16_t digit = 0;
         char16_t symbol = 0;
-        for (Behavior* b = key->firstBehavior; b; b = b->next) {
-            char16_t ch = b->character;
+        for (const Behavior& b : key->behaviors) {
+            char16_t ch = b.character;
             if (ch) {
                 if (ch >= '0' && ch <= '9') {
                     digit = ch;