Merge "Refactor on the user history dictionary"
diff --git a/java/res/values/sudden-jumping-touch-event-device-list.xml b/java/res/values/sudden-jumping-touch-event-device-list.xml
deleted file mode 100644
index 3a9c379..0000000
--- a/java/res/values/sudden-jumping-touch-event-device-list.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-<resources>
-    <string-array name="sudden_jumping_touch_event_device_list" translatable="false">
-        <!-- "Build condition,true" that needs "sudden jump touch event" hack.
-             See {@link com.android.inputmethod.keyboard.SuddenJumpingTouchEventHandler}. -->
-        <!-- Nexus One -->
-        <item>HARDWARE=mahimahi,true</item>
-        <!-- Droid -->
-        <item>HARDWARE=sholes,true</item>
-        <!-- Default value for unknown device -->
-        <item>,false</item>
-    </string-array>
-</resources>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols2.xml b/java/res/xml-sw600dp/rowkeys_symbols2.xml
index 7d7dcfe..14abb42 100644
--- a/java/res/xml-sw600dp/rowkeys_symbols2.xml
+++ b/java/res/xml-sw600dp/rowkeys_symbols2.xml
@@ -62,10 +62,11 @@
         latin:keyLabel="*"
         latin:moreKeys="!text/more_keys_for_star" />
     <!-- U+2013: "–" EN DASH
-         U+2014: "—" EM DASH -->
+         U+2014: "—" EM DASH
+         U+00B7: "·" MIDDLE DOT -->
     <Key
         latin:keyLabel="-"
-        latin:moreKeys="_,&#x2013;,&#x2014;" />
+        latin:moreKeys="_,&#x2013;,&#x2014;,&#x00B7;" />
     <Key
         latin:keyLabel="+"
         latin:moreKeys="!text/more_keys_for_plus" />
diff --git a/java/res/xml/rowkeys_symbols2.xml b/java/res/xml/rowkeys_symbols2.xml
index d3c1278..3e27f15 100644
--- a/java/res/xml/rowkeys_symbols2.xml
+++ b/java/res/xml/rowkeys_symbols2.xml
@@ -54,10 +54,11 @@
         latin:keyLabel="*"
         latin:moreKeys="!text/more_keys_for_star" />
     <!-- U+2013: "–" EN DASH
-         U+2014: "—" EM DASH -->
+         U+2014: "—" EM DASH
+         U+00B7: "·" MIDDLE DOT -->
     <Key
         latin:keyLabel="-"
-        latin:moreKeys="_,&#x2013;,&#x2014;" />
+        latin:moreKeys="_,&#x2013;,&#x2014;,&#x00B7;" />
     <Key
         latin:keyLabel="+"
         latin:moreKeys="!text/more_keys_for_plus" />
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 36f4db9..a5205d8 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -55,7 +55,6 @@
 import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
 import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
 import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
-import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
@@ -115,8 +114,7 @@
  * @attr ref R.styleable#MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration
  */
 public final class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
-        PointerTracker.DrawingProxy, MoreKeysPanel.Controller,
-        TouchScreenRegulator.ProcessMotionEvent {
+        PointerTracker.DrawingProxy, MoreKeysPanel.Controller {
     private static final String TAG = MainKeyboardView.class.getSimpleName();
 
     // TODO: Kill process when the usability study mode was changed.
@@ -183,8 +181,6 @@
     // TODO: Make this parameter customizable by user via settings.
     private int mGestureFloatingPreviewTextLingerTimeout;
 
-    private final TouchScreenRegulator mTouchScreenRegulator;
-
     private KeyDetector mKeyDetector;
     private final boolean mHasDistinctMultitouch;
     private int mOldPointerCount = 1;
@@ -450,8 +446,6 @@
     public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
         super(context, attrs, defStyle);
 
-        mTouchScreenRegulator = new TouchScreenRegulator(context, this);
-
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         final boolean forceNonDistinctMultitouch = prefs.getBoolean(
                 DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false);
@@ -628,7 +622,6 @@
         mKeyDetector.setKeyboard(
                 keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
         PointerTracker.setKeyDetector(mKeyDetector);
-        mTouchScreenRegulator.setKeyboardGeometry(keyboard.mOccupiedWidth);
         mMoreKeysKeyboardCache.clear();
 
         mSpaceKey = keyboard.getKey(Constants.CODE_SPACE);
@@ -1050,10 +1043,11 @@
         if (getKeyboard() == null) {
             return false;
         }
-        return mTouchScreenRegulator.onTouchEvent(me);
+        // TODO: Add multi-touch to single-touch event converter for non-distinct multi-touch
+        // device.
+        return processMotionEvent(me);
     }
 
-    @Override
     public boolean processMotionEvent(final MotionEvent me) {
         final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
         final int action = me.getActionMasked();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 1594df7..7bb7442 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -374,8 +374,7 @@
         /* 115 */ "w",
         /* 116 */ "y",
         /* 117 */ "x",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        /* 118 */ "\u00F1",
+        /* 118 */ EMPTY,
         /* 119 */ "!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm",
         /* 120 */ "!icon/settings_key|!code/key_settings",
         /* 121 */ "!icon/shortcut_key|!code/key_shortcut",
@@ -625,7 +624,8 @@
 
     /* Language az: Azerbaijani */
     private static final String[] LANGUAGE_az = {
-        /* 0 */ null,
+        // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+        /* 0 */ "\u00E2",
         // U+0259: "ə" LATIN SMALL LETTER SCHWA
         /* 1 */ "\u0259",
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
@@ -776,9 +776,28 @@
         /* 8~ */
         null, null, null, null, null, null,
         /* ~13 */
-        // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
+        // U+00B7: "·" MIDDLE DOT
         // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
-        /* 14 */ "\u0140,\u0142",
+        /* 14 */ "l\u00B7l,\u0142",
+        /* 15~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null,
+        /* ~52 */
+        // U+00B7: "·" MIDDLE DOT
+        /* 53 */ "!fixedColumnOrder!9,\u00B7,\",\',#,-,:,!,\\,,?,@,&,\\%,+,;,/,(,)",
+        /* 54~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
+        /* ~107 */
+        /* 108 */ "?,\u00B7",
+        /* 109~ */
+        null, null, null, null, null, null, null, null, null,
+        /* ~117 */
+        // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+        /* 118 */ "\u00E7",
     };
 
     /* Language cs: Czech */
@@ -1253,6 +1272,11 @@
         /* 109 */ "\"",
         /* 110 */ "\'",
         /* 111 */ "\'",
+        /* 112~ */
+        null, null, null, null, null, null,
+        /* ~117 */
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        /* 118 */ "\u00F1",
     };
 
     /* Language et: Estonian */
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java b/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
deleted file mode 100644
index fddd985..0000000
--- a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.inputmethod.keyboard.internal;
-
-import android.content.Context;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.utils.ResourceUtils;
-import com.android.inputmethod.research.ResearchLogger;
-
-public final class TouchScreenRegulator {
-    private static final String TAG = TouchScreenRegulator.class.getSimpleName();
-    private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
-
-    public interface ProcessMotionEvent {
-        public boolean processMotionEvent(MotionEvent me);
-    }
-
-    private final ProcessMotionEvent mView;
-    private final boolean mNeedsSuddenJumpingHack;
-
-    /** Whether we've started dropping move events because we found a big jump */
-    private boolean mDroppingEvents;
-    /**
-     * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
-     * occured
-     */
-    private boolean mDisableDisambiguation;
-    /** The distance threshold at which we start treating the touch session as a multi-touch */
-    private int mJumpThresholdSquare = Integer.MAX_VALUE;
-    private int mLastX;
-    private int mLastY;
-    // One-seventh of the keyboard width seems like a reasonable threshold
-    private static final float JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH = 1.0f / 7.0f;
-
-    public TouchScreenRegulator(final Context context, final ProcessMotionEvent view) {
-        mView = view;
-        mNeedsSuddenJumpingHack = Boolean.parseBoolean(ResourceUtils.getDeviceOverrideValue(
-                context.getResources(), R.array.sudden_jumping_touch_event_device_list));
-    }
-
-    public void setKeyboardGeometry(final int keyboardWidth) {
-        final float jumpThreshold = keyboardWidth * JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH;
-        mJumpThresholdSquare = (int)(jumpThreshold * jumpThreshold);
-    }
-
-    /**
-     * This function checks to see if we need to handle any sudden jumps in the pointer location
-     * that could be due to a multi-touch being treated as a move by the firmware or hardware.
-     * Once a sudden jump is detected, all subsequent move events are discarded
-     * until an UP is received.<P>
-     * When a sudden jump is detected, an UP event is simulated at the last position and when
-     * the sudden moves subside, a DOWN event is simulated for the second key.
-     * @param me the motion event
-     * @return true if the event was consumed, so that it doesn't continue to be handled by
-     * {@link MainKeyboardView}.
-     */
-    private boolean handleSuddenJumping(final MotionEvent me) {
-        if (!mNeedsSuddenJumpingHack)
-            return false;
-        final int action = me.getAction();
-        final int x = (int) me.getX();
-        final int y = (int) me.getY();
-        boolean result = false;
-
-        // Real multi-touch event? Stop looking for sudden jumps
-        if (me.getPointerCount() > 1) {
-            mDisableDisambiguation = true;
-        }
-        if (mDisableDisambiguation) {
-            // If UP, reset the multi-touch flag
-            if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
-            return false;
-        }
-
-        switch (action) {
-        case MotionEvent.ACTION_DOWN:
-            // Reset the "session"
-            mDroppingEvents = false;
-            mDisableDisambiguation = false;
-            break;
-        case MotionEvent.ACTION_MOVE:
-            // Is this a big jump?
-            final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
-            // Check the distance.
-            if (distanceSquare > mJumpThresholdSquare) {
-                // If we're not yet dropping events, start dropping and send an UP event
-                if (!mDroppingEvents) {
-                    mDroppingEvents = true;
-                    // Send an up event
-                    MotionEvent translated = MotionEvent.obtain(
-                            me.getEventTime(), me.getEventTime(),
-                            MotionEvent.ACTION_UP,
-                            mLastX, mLastY, me.getMetaState());
-                    mView.processMotionEvent(translated);
-                    translated.recycle();
-                }
-                result = true;
-            } else if (mDroppingEvents) {
-                // If moves are small and we're already dropping events, continue dropping
-                result = true;
-            }
-            break;
-        case MotionEvent.ACTION_UP:
-            if (mDroppingEvents) {
-                // Send a down event first, as we dropped a bunch of sudden jumps and assume that
-                // the user is releasing the touch on the second key.
-                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
-                        MotionEvent.ACTION_DOWN,
-                        x, y, me.getMetaState());
-                mView.processMotionEvent(translated);
-                translated.recycle();
-                mDroppingEvents = false;
-                // Let the up event get processed as well, result = false
-            }
-            break;
-        }
-        // Track the previous coordinate
-        mLastX = x;
-        mLastY = y;
-        return result;
-    }
-
-    public boolean onTouchEvent(final MotionEvent me) {
-        // If there was a sudden jump, return without processing the actual motion event.
-        if (handleSuddenJumping(me)) {
-            if (DEBUG_MODE)
-                Log.w(TAG, "onTouchEvent: ignore sudden jump " + me);
-            if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                ResearchLogger.suddenJumpingTouchEventHandler_onTouchEvent(me);
-            }
-            return true;
-        }
-        return mView.processMotionEvent(me);
-    }
-}
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
index f3b110b..6b4ef2f 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
@@ -150,7 +150,7 @@
         }
         actualLength1 = i + 1;
     }
-    actualLength1 = min(actualLength1, MAX_WORD_LENGTH - actualLength0 - 1);
+    actualLength1 = min(actualLength1, MAX_WORD_LENGTH - actualLength0);
     memcpy(&dest[actualLength0], src1, actualLength1 * sizeof(dest[0]));
     return actualLength0 + actualLength1;
 }
diff --git a/tools/maketext/res/values-ca/donottranslate-more-keys.xml b/tools/maketext/res/values-ca/donottranslate-more-keys.xml
index baa23bf..8624dfb 100644
--- a/tools/maketext/res/values-ca/donottranslate-more-keys.xml
+++ b/tools/maketext/res/values-ca/donottranslate-more-keys.xml
@@ -67,7 +67,12 @@
          U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
          U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
     <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
-    <!-- U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
+    <!-- U+00B7: "·" MIDDLE DOT
          U+0142: "ł" LATIN SMALL LETTER L WITH STROKE -->
-    <string name="more_keys_for_l">&#x0140;,&#x0142;</string>
+    <string name="more_keys_for_l">l&#x00B7;l,&#x0142;</string>
+    <!-- U+00B7: "·" MIDDLE DOT -->
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,&#x00B7;,\",\',#,-,:,!,\\,,\?,\@,&amp;,\\%,+,;,/,(,)"</string>
+    <string name="more_keys_for_tablet_period">\?,&#x00B7;</string>
+    <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA -->
+    <string name="keylabel_for_spanish_row2_10">&#x00E7;</string>
 </resources>
diff --git a/tools/maketext/res/values-es/donottranslate-more-keys.xml b/tools/maketext/res/values-es/donottranslate-more-keys.xml
index 961193b..0e58c14 100644
--- a/tools/maketext/res/values-es/donottranslate-more-keys.xml
+++ b/tools/maketext/res/values-es/donottranslate-more-keys.xml
@@ -67,6 +67,8 @@
          U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
          U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
     <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
+    <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE -->
+    <string name="keylabel_for_spanish_row2_10">&#x00F1;</string>
     <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK
          U+00BF: "¿" INVERTED QUESTION MARK -->
     <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,&#x00A1;,\",\',#,-,:,!,\\,,\?,&#x00BF;,\@,&amp;,\\%,+,;,/,(,)"</string>
diff --git a/tools/maketext/res/values/donottranslate-more-keys.xml b/tools/maketext/res/values/donottranslate-more-keys.xml
index b53a369..4cf2650 100644
--- a/tools/maketext/res/values/donottranslate-more-keys.xml
+++ b/tools/maketext/res/values/donottranslate-more-keys.xml
@@ -180,8 +180,7 @@
     <string name="keylabel_for_w">w</string>
     <string name="keylabel_for_y">y</string>
     <string name="keylabel_for_x">x</string>
-    <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE -->
-    <string name="keylabel_for_spanish_row2_10">&#x00F1;</string>
+    <string name="keylabel_for_spanish_row2_10"></string>
     <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,\@string/label_time_am,\@string/label_time_pm</string>
     <string name="settings_as_more_key">!icon/settings_key|!code/key_settings</string>
     <string name="shortcut_as_more_key">!icon/shortcut_key|!code/key_shortcut</string>