From df10aeb1da87f980e5d0512133261e2c92c688a7 Mon Sep 17 00:00:00 2001
From: Yohei Yukawa <yukawa@google.com>
Date: Wed, 8 Jan 2014 16:39:55 +0900
Subject: [PATCH] Trigger haptic feedback at touch down on the
 EmojiPalettesView

EmojiPalettesView triggers the haptic feedback at the timing of touch-up rather than touch-down.
This patch set changes the timing to touch-up so that the UX on the EmojiPalettesView can be consistent with normal keyboard layouts.

This patch set also fixes the missing haptic feedback from facemarks such as ":-)".

Bug: 11439600
Change-Id: I22245946712bd1c36226786d6ff81e3b563f7ef7
---
 .../keyboard/EmojiPalettesView.java           | 58 +++++++++++++------
 .../internal/EmojiPageKeyboardView.java       | 22 +++----
 2 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index ff0d53865c..31749614df 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -71,8 +71,8 @@ import java.util.concurrent.ConcurrentHashMap;
  * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
  */
 public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
-        ViewPager.OnPageChangeListener, View.OnClickListener,
-        EmojiPageKeyboardView.OnKeyClickListener {
+        ViewPager.OnPageChangeListener, View.OnTouchListener,
+        EmojiPageKeyboardView.OnKeyEventListener {
     static final String TAG = EmojiPalettesView.class.getSimpleName();
     private static final boolean DEBUG_PAGER = false;
     private final int mKeyBackgroundId;
@@ -486,16 +486,16 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
         final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
         alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
         alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
-        alphabetKey.setOnClickListener(this);
+        alphabetKey.setOnTouchListener(this);
         final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
         spaceKey.setBackgroundResource(mKeyBackgroundId);
         spaceKey.setTag(Constants.CODE_SPACE);
-        spaceKey.setOnClickListener(this);
+        spaceKey.setOnTouchListener(this);
         mEmojiLayoutParams.setKeyProperties(spaceKey);
         final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2);
         alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
         alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
-        alphabetKey2.setOnClickListener(this);
+        alphabetKey2.setOnTouchListener(this);
     }
 
     @Override
@@ -543,31 +543,51 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
         }
     }
 
+    // Called from {@link EmojiPageKeyboardView} through {@link View.OnTouchListener} interface to
+    // handle touch events from View-based elements such as the space bar.
     @Override
-    public void onClick(final View v) {
-        if (v.getTag() instanceof Integer) {
-            final int code = (Integer)v.getTag();
-            registerCode(code);
-            return;
+    public boolean onTouch(final View v, final MotionEvent event) {
+        final Object tag = v.getTag();
+        if (!(tag instanceof Integer)) {
+            return false;
+        }
+        final int code = (Integer) tag;
+        switch(event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mKeyboardActionListener.onPressKey(
+                        code, 0 /* repeatCount */, true /* isSinglePointer */);
+                break;
+            case MotionEvent.ACTION_UP:
+                mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
+                mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
+                break;
         }
+        return false;
     }
 
-    private void registerCode(final int code) {
+    // Called from {@link EmojiPageKeyboardView} through
+    // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
+    // non-View-based elements like typical Emoji characters.
+    @Override
+    public void onPressKey(final Key key) {
+        final int code = key.getCode();
         mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
-        mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
-        mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
     }
 
+    // Called from {@link EmojiPageKeyboardView} through
+    // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
+    // non-View-based elements like typical Emoji characters.
     @Override
-    public void onKeyClick(final Key key) {
+    public void onReleaseKey(final Key key) {
         mEmojiPalettesAdapter.addRecentKey(key);
         mEmojiCategory.saveLastTypedCategoryPage();
         final int code = key.getCode();
         if (code == Constants.CODE_OUTPUT_TEXT) {
             mKeyboardActionListener.onTextInput(key.getOutputText());
-            return;
+        } else {
+            mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
         }
-        registerCode(code);
+        mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
     }
 
     public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
@@ -630,7 +650,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
     }
 
     private static class EmojiPalettesAdapter extends PagerAdapter {
-        private final EmojiPageKeyboardView.OnKeyClickListener mListener;
+        private final EmojiPageKeyboardView.OnKeyEventListener mListener;
         private final DynamicGridKeyboard mRecentsKeyboard;
         private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews =
                 CollectionUtils.newSparseArray();
@@ -638,7 +658,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
         private int mActivePosition = 0;
 
         public EmojiPalettesAdapter(final EmojiCategory emojiCategory,
-                final EmojiPageKeyboardView.OnKeyClickListener listener) {
+                final EmojiPageKeyboardView.OnKeyEventListener listener) {
             mEmojiCategory = emojiCategory;
             mListener = listener;
             mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0);
@@ -702,7 +722,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
             final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate(
                     R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
             keyboardView.setKeyboard(keyboard);
-            keyboardView.setOnKeyClickListener(mListener);
+            keyboardView.setOnKeyEventListener(mListener);
             container.addView(keyboardView);
             mActiveKeyboardViews.put(position, keyboardView);
             return keyboardView;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
index 2e80f79622..5c7c6e39db 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
@@ -35,16 +35,19 @@ import com.android.inputmethod.latin.R;
 // TODO: Implement key popup preview.
 public final class EmojiPageKeyboardView extends KeyboardView implements
         GestureDetector.OnGestureListener {
-    public interface OnKeyClickListener {
-        public void onKeyClick(Key key);
+    public interface OnKeyEventListener {
+        public void onPressKey(Key key);
+        public void onReleaseKey(Key key);
     }
 
-    private static final OnKeyClickListener EMPTY_LISTENER = new OnKeyClickListener() {
-        @Override
-        public void onKeyClick(final Key key) {}
+    private static final OnKeyEventListener EMPTY_LISTENER = new OnKeyEventListener() {
+      @Override
+      public void onPressKey(final Key key) {}
+      @Override
+      public void onReleaseKey(final Key key) {}
     };
 
-    private OnKeyClickListener mListener = EMPTY_LISTENER;
+    private OnKeyEventListener mListener = EMPTY_LISTENER;
     private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */);
     private final GestureDetector mGestureDetector;
 
@@ -59,7 +62,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
         mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
     }
 
-    public void setOnKeyClickListener(final OnKeyClickListener listener) {
+    public void setOnKeyEventListener(final OnKeyEventListener listener) {
         mListener = listener;
     }
 
@@ -115,9 +118,9 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
         if (key == null) {
             return false;
         }
-        // TODO: May call {@link KeyboardActionListener#onPressKey(int,int,boolean)}.
         key.onPressed();
         invalidateKey(key);
+        mListener.onPressKey(key);
         return false;
     }
 
@@ -133,10 +136,9 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
         if (key == null) {
             return false;
         }
-        // TODO: May call {@link KeyboardActionListener#onReleaseKey(int,boolean)}.
         key.onReleased();
         invalidateKey(key);
-        mListener.onKeyClick(key);
+        mListener.onReleaseKey(key);
         return true;
     }
 
-- 
GitLab