Delete gender-balanced emoji sequence by one backspace key event.

The gender-balanced emojis are made with ZWJ sequence and emoji
modifiers.  For example, U+1F469 U+1F3FD U+200D U+1F4BC should be
deleted at the same time by single backsapce key event.  Here, U+1F469
is WOMAN, U+1F3FD is EMOJI MODIFIER FITZPATRICK TYPE-4, U+200D is ZERO
WIDTH JOINER, U+1F4BC is BRIEFCASE.

This CL also renames the state name from STATE_BEFORE_ZWJ_EMOJI to
STATE_BEFORE_EMOJI since now all emoji can be a part of ZWJ sequence
after I572dad42ee108476962d4b3fe9f3a6019cb50098

BUG: 29728397
Change-Id: Ib114295db45c6592f1c65a0773ab236f8bf35209
(cherry picked from commit bba8d97c369f02a9d1988217324724a24842079f)
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 3770a45..2f327f3 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -129,8 +129,8 @@
         // The offset is immediately before a variation selector.
         final int STATE_BEFORE_VS = 6;
 
-        // The offset is immediately before a ZWJ emoji.
-        final int STATE_BEFORE_ZWJ_EMOJI = 7;
+        // The offset is immediately before an emoji.
+        final int STATE_BEFORE_EMOJI = 7;
         // The offset is immediately before a ZWJ that were seen before a ZWJ emoji.
         final int STATE_BEFORE_ZWJ = 8;
         // The offset is immediately before a variation selector and a ZWJ that were seen before a
@@ -169,7 +169,7 @@
                     } else if (codePoint == Emoji.COMBINING_ENCLOSING_KEYCAP) {
                         state = STATE_BEFORE_KEYCAP;
                     } else if (Emoji.isEmoji(codePoint)) {
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                     } else {
                         state = STATE_FINISHED;
                     }
@@ -232,7 +232,7 @@
                 case STATE_BEFORE_VS:
                     if (Emoji.isEmoji(codePoint)) {
                         deleteCharCount += Character.charCount(codePoint);
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                         break;
                     }
 
@@ -242,7 +242,7 @@
                     }
                     state = STATE_FINISHED;
                     break;
-                case STATE_BEFORE_ZWJ_EMOJI:
+                case STATE_BEFORE_EMOJI:
                     if (codePoint == Emoji.ZERO_WIDTH_JOINER) {
                         state = STATE_BEFORE_ZWJ;
                     } else {
@@ -252,7 +252,8 @@
                 case STATE_BEFORE_ZWJ:
                     if (Emoji.isEmoji(codePoint)) {
                         deleteCharCount += Character.charCount(codePoint) + 1;  // +1 for ZWJ.
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = Emoji.isEmojiModifier(codePoint) ?
+                                STATE_BEFORE_EMOJI_MODIFIER : STATE_BEFORE_EMOJI;
                     } else if (isVariationSelector(codePoint)) {
                         lastSeenVSCharCount = Character.charCount(codePoint);
                         state = STATE_BEFORE_VS_AND_ZWJ;
@@ -265,7 +266,7 @@
                         // +1 for ZWJ.
                         deleteCharCount += lastSeenVSCharCount + 1 + Character.charCount(codePoint);
                         lastSeenVSCharCount = 0;
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                     } else {
                         state = STATE_FINISHED;
                     }
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index a9fa4dd..f24ed6f 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -174,6 +174,11 @@
         backspace(state, 0);
         state.assertEquals("|");
 
+        // Emoji modifier can be appended to the first emoji.
+        state.setByString("U+1F469 U+1F3FB U+200D U+1F4BC |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
         // End with ZERO WIDTH JOINER
         state.setByString("U+1F441 U+200D |");
         backspace(state, 0);
@@ -445,13 +450,6 @@
         backspace(state, 0);
         state.assertEquals("|");
 
-        // Emoji modifier + ZERO WIDTH JOINER
-        state.setByString("U+1F466 U+1F3FB U+200D U+1F469 |");
-        backspace(state, 0);
-        state.assertEquals("U+1F466 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
         // Regional indicator symbol + Emoji modifier
         state.setByString("U+1F1FA U+1F3FB |");
         backspace(state, 0);