From 4e1a558ee8d7747b71dba5aac86a7c9003d6f57d Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Fri, 25 May 2012 19:56:45 +0900
Subject: [PATCH] Simulate hardware enter/delete events if the app targets < 16

This will make text input buggy on all apps until they target
JB or superior.

Bug: 6537051
Change-Id: I726347db8c84d1582ad1962d3a910e698389e08c
---
 .../android/inputmethod/latin/LatinIME.java   | 40 +++++++++++++++++--
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c58549497..b58ca21c7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -45,6 +45,8 @@ import android.text.TextUtils;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
@@ -1224,6 +1226,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         }
     }
 
+    static private void sendUpDownEnterOrBackspace(final int code, final InputConnection ic) {
+        final long eventTime = SystemClock.uptimeMillis();
+        ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
+                KeyEvent.ACTION_DOWN, code, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+                KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
+        ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
+                KeyEvent.ACTION_UP, code, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+                KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
+    }
+
     private void sendKeyCodePoint(int code) {
         // TODO: Remove this special handling of digit letters.
         // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
@@ -1234,8 +1246,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
         final InputConnection ic = getCurrentInputConnection();
         if (ic != null) {
-            final String text = new String(new int[] { code }, 0, 1);
-            ic.commitText(text, text.length());
+            // 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
+            // we want to be able to compile against the Ice Cream Sandwich SDK.
+            if (Keyboard.CODE_ENTER == code && mTargetApplicationInfo != null
+                    && mTargetApplicationInfo.targetSdkVersion < 16) {
+                // Backward compatibility mode. Before Jelly bean, the keyboard would simulate
+                // a hardware keyboard event on pressing enter or delete. This is bad for many
+                // reasons (there are race conditions with commits) but some applications are
+                // relying on this behavior so we continue to support it for older apps.
+                sendUpDownEnterOrBackspace(KeyEvent.KEYCODE_ENTER, ic);
+            } else {
+                final String text = new String(new int[] { code }, 0, 1);
+                ic.commitText(text, text.length());
+            }
             if (ProductionFlag.IS_EXPERIMENTAL) {
                 ResearchLogger.latinIME_sendKeyCodePoint(code);
             }
@@ -1464,7 +1487,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     // This should never happen.
                     Log.e(TAG, "Backspace when we don't know the selection position");
                 }
-                ic.deleteSurroundingText(1, 0);
+                // 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
+                // we want to be able to compile against the Ice Cream Sandwich SDK.
+                if (mTargetApplicationInfo != null
+                        && mTargetApplicationInfo.targetSdkVersion < 16) {
+                    // Backward compatibility mode. Before Jelly bean, the keyboard would simulate
+                    // a hardware keyboard event on pressing enter or delete. This is bad for many
+                    // reasons (there are race conditions with commits) but some applications are
+                    // relying on this behavior so we continue to support it for older apps.
+                    sendUpDownEnterOrBackspace(KeyEvent.KEYCODE_DEL, ic);
+                } else {
+                    ic.deleteSurroundingText(1, 0);
+                }
                 if (ProductionFlag.IS_EXPERIMENTAL) {
                     ResearchLogger.latinIME_deleteSurroundingText(1);
                 }